Line data Source code
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 <TVector3.h>
25 : #include "AliLog.h"
26 : #include "AliExternalTrackParam.h"
27 : #include "AliVVertex.h"
28 : #include "AliDetectorPID.h"
29 : #include "AliAODEvent.h"
30 : #include "AliAODHMPIDrings.h"
31 : #include "AliTOFHeader.h"
32 :
33 : #include "AliAODTrack.h"
34 :
35 170 : ClassImp(AliAODTrack)
36 :
37 : //______________________________________________________________________________
38 : AliAODTrack::AliAODTrack() :
39 2 : AliVTrack(),
40 2 : fRAtAbsorberEnd(0.),
41 2 : fChi2perNDF(-999.),
42 2 : fChi2MatchTrigger(0.),
43 2 : fPID(0),
44 2 : fITSchi2(0),
45 2 : fFlags(0),
46 2 : fLabel(-999),
47 2 : fTOFLabel(),
48 2 : fTrackLength(0),
49 2 : fITSMuonClusterMap(0),
50 2 : fMUONtrigHitsMapTrg(0),
51 2 : fMUONtrigHitsMapTrk(0),
52 2 : fFilterMap(0),
53 2 : fTPCFitMap(),
54 2 : fTPCClusterMap(),
55 2 : fTPCSharedMap(),
56 2 : fTPCnclsF(0),
57 2 : fTPCNCrossedRows(0),
58 2 : fID(-999),
59 2 : fCharge(-99),
60 2 : fType(kUndef),
61 2 : fPIDForTracking(AliPID::kPion),
62 2 : fCaloIndex(kEMCALNoMatch),
63 2 : fCovMatrix(NULL),
64 2 : fDetPid(NULL),
65 2 : fDetectorPID(NULL),
66 2 : fProdVertex(NULL),
67 2 : fTrackPhiOnEMCal(-999),
68 2 : fTrackEtaOnEMCal(-999),
69 2 : fTrackPtOnEMCal(-999),
70 2 : fIsMuonGlobalTrack(kFALSE), // AU
71 2 : fITSsignalTuned(0.),
72 2 : fTPCsignalTuned(0),
73 2 : fTOFsignalTuned(99999),
74 2 : fMFTClusterPattern(0), // AU
75 2 : fAODEvent(NULL)
76 10 : {
77 : // default constructor
78 :
79 2 : SetP();
80 2 : SetPosition((Float_t*)NULL);
81 2 : SetXYAtDCA(-999., -999.);
82 2 : SetPxPyPzAtDCA(-999., -999., -999.);
83 16 : for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = -1;}
84 4 : }
85 :
86 : //______________________________________________________________________________
87 : AliAODTrack::AliAODTrack(Short_t id,
88 : Int_t label,
89 : Double_t p[3],
90 : Bool_t cartesian,
91 : Double_t x[3],
92 : Bool_t isDCA,
93 : Double_t covMatrix[21],
94 : Short_t charge,
95 : UChar_t itsClusMap,
96 : AliAODVertex *prodVertex,
97 : Bool_t usedForVtxFit,
98 : Bool_t usedForPrimVtxFit,
99 : AODTrk_t ttype,
100 : UInt_t selectInfo,
101 : Float_t chi2perNDF) :
102 137 : AliVTrack(),
103 137 : fRAtAbsorberEnd(0.),
104 137 : fChi2perNDF(chi2perNDF),
105 137 : fChi2MatchTrigger(0.),
106 137 : fPID(0),
107 137 : fITSchi2(0),
108 137 : fFlags(0),
109 137 : fLabel(label),
110 137 : fTOFLabel(),
111 137 : fTrackLength(0),
112 137 : fITSMuonClusterMap(0),
113 137 : fMUONtrigHitsMapTrg(0),
114 137 : fMUONtrigHitsMapTrk(0),
115 137 : fFilterMap(selectInfo),
116 137 : fTPCFitMap(),
117 137 : fTPCClusterMap(),
118 137 : fTPCSharedMap(),
119 137 : fTPCnclsF(0),
120 137 : fTPCNCrossedRows(0),
121 137 : fID(id),
122 137 : fCharge(charge),
123 137 : fType(ttype),
124 137 : fPIDForTracking(AliPID::kPion),
125 137 : fCaloIndex(kEMCALNoMatch),
126 137 : fCovMatrix(NULL),
127 137 : fDetPid(NULL),
128 137 : fDetectorPID(NULL),
129 137 : fProdVertex(prodVertex),
130 137 : fTrackPhiOnEMCal(-999),
131 137 : fTrackEtaOnEMCal(-999),
132 137 : fTrackPtOnEMCal(-999),
133 137 : fIsMuonGlobalTrack(kFALSE), // AU
134 137 : fITSsignalTuned(0),
135 137 : fTPCsignalTuned(0),
136 137 : fTOFsignalTuned(99999),
137 137 : fMFTClusterPattern(0), // AU
138 137 : fAODEvent(NULL)
139 411 : {
140 : // constructor
141 :
142 137 : SetP(p, cartesian);
143 137 : SetPosition(x, isDCA);
144 137 : SetXYAtDCA(-999., -999.);
145 137 : SetPxPyPzAtDCA(-999., -999., -999.);
146 137 : SetUsedForVtxFit(usedForVtxFit);
147 137 : SetUsedForPrimVtxFit(usedForPrimVtxFit);
148 258 : if(covMatrix) SetCovMatrix(covMatrix);
149 137 : SetITSClusterMap(itsClusMap);
150 1096 : for (Int_t i=0;i<3;i++) {fTOFLabel[i]=-1;}
151 274 : }
152 :
153 : //______________________________________________________________________________
154 : AliAODTrack::AliAODTrack(Short_t id,
155 : Int_t label,
156 : Float_t p[3],
157 : Bool_t cartesian,
158 : Float_t x[3],
159 : Bool_t isDCA,
160 : Float_t covMatrix[21],
161 : Short_t charge,
162 : UChar_t itsClusMap,
163 : AliAODVertex *prodVertex,
164 : Bool_t usedForVtxFit,
165 : Bool_t usedForPrimVtxFit,
166 : AODTrk_t ttype,
167 : UInt_t selectInfo,
168 : Float_t chi2perNDF ) :
169 0 : AliVTrack(),
170 0 : fRAtAbsorberEnd(0.),
171 0 : fChi2perNDF(chi2perNDF),
172 0 : fChi2MatchTrigger(0.),
173 0 : fPID(0),
174 0 : fITSchi2(0),
175 0 : fFlags(0),
176 0 : fLabel(label),
177 0 : fTOFLabel(),
178 0 : fTrackLength(0),
179 0 : fITSMuonClusterMap(0),
180 0 : fMUONtrigHitsMapTrg(0),
181 0 : fMUONtrigHitsMapTrk(0),
182 0 : fFilterMap(selectInfo),
183 0 : fTPCFitMap(),
184 0 : fTPCClusterMap(),
185 0 : fTPCSharedMap(),
186 0 : fTPCnclsF(0),
187 0 : fTPCNCrossedRows(0),
188 0 : fID(id),
189 0 : fCharge(charge),
190 0 : fType(ttype),
191 0 : fPIDForTracking(AliPID::kPion),
192 0 : fCaloIndex(kEMCALNoMatch),
193 0 : fCovMatrix(NULL),
194 0 : fDetPid(NULL),
195 0 : fDetectorPID(NULL),
196 0 : fProdVertex(prodVertex),
197 0 : fTrackPhiOnEMCal(-999),
198 0 : fTrackEtaOnEMCal(-999),
199 0 : fTrackPtOnEMCal(-999),
200 0 : fIsMuonGlobalTrack(kFALSE), // AU
201 0 : fITSsignalTuned(0),
202 0 : fTPCsignalTuned(0),
203 0 : fTOFsignalTuned(99999),
204 0 : fMFTClusterPattern(0), // AU
205 0 : fAODEvent(NULL)
206 0 : {
207 : // constructor
208 :
209 0 : SetP(p, cartesian);
210 0 : SetPosition(x, isDCA);
211 0 : SetXYAtDCA(-999., -999.);
212 0 : SetPxPyPzAtDCA(-999., -999., -999.);
213 0 : SetUsedForVtxFit(usedForVtxFit);
214 0 : SetUsedForPrimVtxFit(usedForPrimVtxFit);
215 0 : if(covMatrix) SetCovMatrix(covMatrix);
216 0 : SetITSClusterMap(itsClusMap);
217 0 : for (Int_t i=0;i<3;i++) {fTOFLabel[i]=-1;}
218 0 : }
219 :
220 : //______________________________________________________________________________
221 : AliAODTrack::~AliAODTrack()
222 834 : {
223 : // destructor
224 260 : delete fCovMatrix;
225 259 : delete fDetPid;
226 139 : delete fDetectorPID;
227 139 : if (fPID) {delete[] fPID; fPID = 0;}
228 417 : }
229 :
230 :
231 : //______________________________________________________________________________
232 : AliAODTrack::AliAODTrack(const AliAODTrack& trk) :
233 0 : AliVTrack(trk),
234 0 : fRAtAbsorberEnd(trk.fRAtAbsorberEnd),
235 0 : fChi2perNDF(trk.fChi2perNDF),
236 0 : fChi2MatchTrigger(trk.fChi2MatchTrigger),
237 0 : fPID(0),
238 0 : fITSchi2(trk.fITSchi2),
239 0 : fFlags(trk.fFlags),
240 0 : fLabel(trk.fLabel),
241 0 : fTOFLabel(),
242 0 : fTrackLength(trk.fTrackLength),
243 0 : fITSMuonClusterMap(trk.fITSMuonClusterMap),
244 0 : fMUONtrigHitsMapTrg(trk.fMUONtrigHitsMapTrg),
245 0 : fMUONtrigHitsMapTrk(trk.fMUONtrigHitsMapTrk),
246 0 : fFilterMap(trk.fFilterMap),
247 0 : fTPCFitMap(trk.fTPCFitMap),
248 0 : fTPCClusterMap(trk.fTPCClusterMap),
249 0 : fTPCSharedMap(trk.fTPCSharedMap),
250 0 : fTPCnclsF(trk.fTPCnclsF),
251 0 : fTPCNCrossedRows(trk.fTPCNCrossedRows),
252 0 : fID(trk.fID),
253 0 : fCharge(trk.fCharge),
254 0 : fType(trk.fType),
255 0 : fPIDForTracking(trk.fPIDForTracking),
256 0 : fCaloIndex(trk.fCaloIndex),
257 0 : fCovMatrix(NULL),
258 0 : fDetPid(NULL),
259 0 : fDetectorPID(NULL),
260 0 : fProdVertex(trk.fProdVertex),
261 0 : fTrackPhiOnEMCal(trk.fTrackPhiOnEMCal),
262 0 : fTrackEtaOnEMCal(trk.fTrackEtaOnEMCal),
263 0 : fTrackPtOnEMCal(trk.fTrackPtOnEMCal),
264 0 : fIsMuonGlobalTrack(trk.fIsMuonGlobalTrack), // AU
265 0 : fITSsignalTuned(trk.fITSsignalTuned),
266 0 : fTPCsignalTuned(trk.fTPCsignalTuned),
267 0 : fTOFsignalTuned(trk.fTOFsignalTuned),
268 0 : fMFTClusterPattern(trk.fMFTClusterPattern), // AU
269 0 : fAODEvent(trk.fAODEvent)
270 0 : {
271 : // Copy constructor
272 :
273 0 : trk.GetP(fMomentum);
274 0 : trk.GetPosition(fPosition);
275 0 : SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
276 0 : SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
277 0 : SetUsedForVtxFit(trk.GetUsedForVtxFit());
278 0 : SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
279 0 : if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
280 0 : if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
281 0 : SetPID(trk.fPID);
282 0 : if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
283 0 : for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = trk.fTOFLabel[i];}
284 0 : }
285 :
286 : //______________________________________________________________________________
287 : AliAODTrack& AliAODTrack::operator=(const AliAODTrack& trk)
288 : {
289 : // Assignment operator
290 0 : if(this!=&trk) {
291 :
292 0 : AliVTrack::operator=(trk);
293 :
294 0 : trk.GetP(fMomentum);
295 0 : trk.GetPosition(fPosition);
296 0 : SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
297 0 : SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
298 0 : fRAtAbsorberEnd = trk.fRAtAbsorberEnd;
299 0 : fChi2perNDF = trk.fChi2perNDF;
300 0 : fChi2MatchTrigger = trk.fChi2MatchTrigger;
301 0 : SetPID( trk.fPID );
302 0 : fITSchi2 = trk.fITSchi2;
303 0 : fFlags = trk.fFlags;
304 0 : fLabel = trk.fLabel;
305 0 : fTrackLength = trk.fTrackLength;
306 0 : fITSMuonClusterMap = trk.fITSMuonClusterMap;
307 0 : fMUONtrigHitsMapTrg = trk.fMUONtrigHitsMapTrg;
308 0 : fMUONtrigHitsMapTrk = trk.fMUONtrigHitsMapTrk;
309 0 : fFilterMap = trk.fFilterMap;
310 0 : fTPCFitMap = trk.fTPCFitMap;
311 0 : fTPCClusterMap = trk.fTPCClusterMap;
312 0 : fTPCSharedMap = trk.fTPCSharedMap;
313 0 : fTPCnclsF = trk.fTPCnclsF;
314 0 : fTPCNCrossedRows = trk.fTPCNCrossedRows;
315 0 : fID = trk.fID;
316 0 : fCharge = trk.fCharge;
317 0 : fType = trk.fType;
318 0 : fPIDForTracking = trk.fPIDForTracking;
319 0 : fCaloIndex = trk.fCaloIndex;
320 0 : fTrackPhiOnEMCal = trk.fTrackPhiOnEMCal;
321 0 : fTrackEtaOnEMCal = trk.fTrackEtaOnEMCal;
322 0 : fTrackPtOnEMCal = trk.fTrackPtOnEMCal;
323 0 : fIsMuonGlobalTrack = trk.fIsMuonGlobalTrack; // AU
324 0 : fITSsignalTuned = trk.fITSsignalTuned;
325 0 : fTPCsignalTuned = trk.fTPCsignalTuned;
326 0 : fTOFsignalTuned = trk.fTOFsignalTuned;
327 0 : fMFTClusterPattern = trk.fMFTClusterPattern; // AU
328 :
329 0 : delete fCovMatrix;
330 0 : if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
331 0 : else fCovMatrix=NULL;
332 :
333 :
334 0 : fProdVertex = trk.fProdVertex;
335 0 : SetUsedForVtxFit(trk.GetUsedForVtxFit());
336 0 : SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
337 :
338 : //detector raw signals
339 0 : delete fDetPid;
340 0 : if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
341 0 : else fDetPid=NULL;
342 :
343 : //calibrated PID cache
344 0 : delete fDetectorPID;
345 0 : fDetectorPID=0x0;
346 0 : if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
347 0 : for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = trk.fTOFLabel[i];}
348 0 : }
349 :
350 0 : return *this;
351 0 : }
352 :
353 : //______________________________________________________________________________
354 : Double_t AliAODTrack::M(AODTrkPID_t pid) const
355 : {
356 : // Returns the mass.
357 : // Masses for nuclei don't exist in the PDG tables, therefore they were put by hand.
358 :
359 0 : switch (pid) {
360 :
361 : case kElectron :
362 0 : return 0.000510999; //TDatabasePDG::Instance()->GetParticle(11/*::kElectron*/)->Mass();
363 : break;
364 :
365 : case kMuon :
366 0 : return 0.1056584; //TDatabasePDG::Instance()->GetParticle(13/*::kMuonMinus*/)->Mass();
367 : break;
368 :
369 : case kPion :
370 0 : return 0.13957; //TDatabasePDG::Instance()->GetParticle(211/*::kPiPlus*/)->Mass();
371 : break;
372 :
373 : case kKaon :
374 0 : return 0.4937; //TDatabasePDG::Instance()->GetParticle(321/*::kKPlus*/)->Mass();
375 : break;
376 :
377 : case kProton :
378 0 : return 0.9382720; //TDatabasePDG::Instance()->GetParticle(2212/*::kProton*/)->Mass();
379 : break;
380 :
381 : case kDeuteron :
382 0 : return 1.8756; //TDatabasePDG::Instance()->GetParticle(1000010020)->Mass();
383 : break;
384 :
385 : case kTriton :
386 0 : return 2.8089; //TDatabasePDG::Instance()->GetParticle(1000010030)->Mass();
387 : break;
388 :
389 : case kHelium3 :
390 0 : return 2.8084; //TDatabasePDG::Instance()->GetParticle(1000020030)->Mass();
391 : break;
392 :
393 : case kAlpha :
394 0 : return 3.7274; //TDatabasePDG::Instance()->GetParticle(1000020040)->Mass();
395 : break;
396 :
397 : case kUnknown :
398 0 : return -999.;
399 : break;
400 :
401 : default :
402 0 : return -999.;
403 : }
404 0 : }
405 :
406 : //______________________________________________________________________________
407 : Double_t AliAODTrack::E(AODTrkPID_t pid) const
408 : {
409 : // Returns the energy of the particle of a given pid.
410 :
411 0 : if (pid != kUnknown) { // particle was identified
412 0 : Double_t m = M(pid);
413 0 : return TMath::Sqrt(P()*P() + m*m);
414 : } else { // pid unknown
415 0 : return -999.;
416 : }
417 0 : }
418 :
419 : //______________________________________________________________________________
420 : Double_t AliAODTrack::Y(AODTrkPID_t pid) const
421 : {
422 : // Returns the rapidity of a particle of a given pid.
423 :
424 0 : if (pid != kUnknown) { // particle was identified
425 0 : Double_t e = E(pid);
426 0 : Double_t pz = Pz();
427 0 : if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
428 0 : return 0.5*TMath::Log((e+pz)/(e-pz));
429 : } else { // energy not known or equal to pz
430 0 : return -999.;
431 : }
432 : } else { // pid unknown
433 0 : return -999.;
434 : }
435 0 : }
436 :
437 : //______________________________________________________________________________
438 : Double_t AliAODTrack::Y(Double_t m) const
439 : {
440 : // Returns the rapidity of a particle of a given mass.
441 :
442 0 : if (m >= 0.) { // mass makes sense
443 0 : Double_t e = E(m);
444 0 : Double_t pz = Pz();
445 0 : if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
446 0 : return 0.5*TMath::Log((e+pz)/(e-pz));
447 : } else { // energy not known or equal to pz
448 0 : return -999.;
449 : }
450 : } else { // pid unknown
451 0 : return -999.;
452 : }
453 0 : }
454 :
455 : void AliAODTrack::SetTOFLabel(const Int_t *p) {
456 : // Sets (in TOF)
457 1629 : for (Int_t i = 0; i < 3; i++) fTOFLabel[i]=p[i];
458 181 : }
459 :
460 : //_______________________________________________________________________
461 : void AliAODTrack::GetTOFLabel(Int_t *p) const {
462 : // Gets (in TOF)
463 549 : for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
464 61 : }
465 :
466 : //______________________________________________________________________________
467 : AliAODTrack::AODTrkPID_t AliAODTrack::GetMostProbablePID() const
468 : {
469 : // Returns the most probable PID array element.
470 :
471 : Int_t nPID = 10;
472 : AODTrkPID_t loc = kUnknown;
473 : Bool_t allTheSame = kTRUE;
474 0 : if (fPID) {
475 : Double_t max = 0.;
476 0 : for (Int_t iPID = 0; iPID < nPID; iPID++) {
477 0 : if (fPID[iPID] >= max) {
478 0 : if (fPID[iPID] > max) {
479 : allTheSame = kFALSE;
480 : max = fPID[iPID];
481 : loc = (AODTrkPID_t)iPID;
482 0 : } else {
483 : allTheSame = kTRUE;
484 : }
485 : }
486 : }
487 0 : }
488 0 : return allTheSame ? AODTrkPID_t(GetPIDForTracking()) : loc;
489 : }
490 :
491 : //______________________________________________________________________________
492 : void AliAODTrack::ConvertAliPIDtoAODPID()
493 : {
494 : // Converts AliPID array.
495 : // The numbering scheme is the same for electrons, muons, pions, kaons, and protons.
496 : // Everything else has to be set to zero.
497 282 : if (fPID) {
498 0 : fPID[kDeuteron] = 0.;
499 0 : fPID[kTriton] = 0.;
500 0 : fPID[kHelium3] = 0.;
501 0 : fPID[kAlpha] = 0.;
502 0 : fPID[kUnknown] = 0.;
503 0 : }
504 141 : return;
505 : }
506 :
507 : /*
508 : //______________________________________________________________________________
509 : template <typename T> void AliAODTrack::SetPosition(const T *x, const Bool_t dca)
510 : {
511 : // set the position
512 :
513 : if (x) {
514 : if (!dca) {
515 : ResetBit(kIsDCA);
516 :
517 : fPosition[0] = x[0];
518 : fPosition[1] = x[1];
519 : fPosition[2] = x[2];
520 : } else {
521 : SetBit(kIsDCA);
522 : // don't know any better yet
523 : fPosition[0] = -999.;
524 : fPosition[1] = -999.;
525 : fPosition[2] = -999.;
526 : }
527 : } else {
528 : ResetBit(kIsDCA);
529 :
530 : fPosition[0] = -999.;
531 : fPosition[1] = -999.;
532 : fPosition[2] = -999.;
533 : }
534 : }
535 : */
536 : //______________________________________________________________________________
537 : void AliAODTrack::SetDCA(Double_t d, Double_t z)
538 : {
539 : // set the dca
540 0 : fPosition[0] = d;
541 0 : fPosition[1] = z;
542 0 : fPosition[2] = 0.;
543 0 : SetBit(kIsDCA);
544 0 : }
545 :
546 : //______________________________________________________________________________
547 : void AliAODTrack::Print(Option_t* /* option */) const
548 : {
549 : // prints information about AliAODTrack
550 :
551 0 : printf("Object name: %s Track type: %s\n", GetName(), GetTitle());
552 0 : printf(" px = %f\n", Px());
553 0 : printf(" py = %f\n", Py());
554 0 : printf(" pz = %f\n", Pz());
555 0 : printf(" pt = %f\n", Pt());
556 0 : printf(" 1/pt = %f\n", OneOverPt());
557 0 : printf(" theta = %f\n", Theta());
558 0 : printf(" phi = %f\n", Phi());
559 0 : printf(" chi2/NDF = %f\n", Chi2perNDF());
560 0 : printf(" charge = %d\n", Charge());
561 0 : }
562 :
563 : //______________________________________________________________________________
564 : void AliAODTrack::SetMatchTrigger(Int_t matchTrig)
565 : {
566 : // Set the MUON trigger information
567 32 : switch(matchTrig){
568 : case 0: // 0 track does not match trigger
569 4 : fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
570 4 : break;
571 : case 1: // 1 track match but does not pass pt cut
572 0 : fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x40000000;
573 0 : break;
574 : case 2: // 2 track match Low pt cut
575 0 : fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x80000000;
576 0 : break;
577 : case 3: // 3 track match High pt cut
578 12 : fITSMuonClusterMap=fITSMuonClusterMap|0xc0000000;
579 12 : break;
580 : default:
581 0 : fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
582 0 : AliWarning(Form("unknown case for matchTrig: %d\n",matchTrig));
583 0 : }
584 16 : }
585 :
586 : //______________________________________________________________________________
587 : Bool_t AliAODTrack::HitsMuonChamber(Int_t MuonChamber, Int_t cathode) const
588 : {
589 : // return kTRUE if the track fires the given tracking or trigger chamber.
590 : // If the chamber is a trigger one:
591 : // - if cathode = 0 or 1, the track matches the corresponding cathode
592 : // - if cathode = -1, the track matches both cathodes
593 :
594 0 : if (MuonChamber < 0) return kFALSE;
595 :
596 0 : if (MuonChamber < 10) return TESTBIT(GetMUONClusterMap(), MuonChamber);
597 :
598 0 : if (MuonChamber < 14) {
599 :
600 0 : if (cathode < 0) return TESTBIT(GetMUONTrigHitsMapTrg(), 13-MuonChamber) &&
601 0 : TESTBIT(GetMUONTrigHitsMapTrg(), 13-MuonChamber+4);
602 :
603 0 : if (cathode < 2) return TESTBIT(GetMUONTrigHitsMapTrg(), 13-MuonChamber+(1-cathode)*4);
604 :
605 : }
606 :
607 0 : return kFALSE;
608 0 : }
609 :
610 : //______________________________________________________________________________
611 : Bool_t AliAODTrack::MatchTriggerDigits() const
612 : {
613 : // return kTRUE if the track matches a digit on both planes of at least 2 trigger chambers
614 :
615 : Int_t nMatchedChambers = 0;
616 0 : for (Int_t ich=10; ich<14; ich++) if (HitsMuonChamber(ich)) nMatchedChambers++;
617 :
618 0 : return (nMatchedChambers >= 2);
619 : }
620 :
621 : //______________________________________________________________________________
622 : Int_t AliAODTrack::GetMuonTrigDevSign() const
623 : {
624 : /// Return the sign of the MTR deviation
625 :
626 0 : Int_t signInfo = (Int_t)((fMUONtrigHitsMapTrg>>30)&0x3);
627 : // Dummy value for old AODs which do not have the info
628 0 : if ( signInfo == 0 ) return -999;
629 0 : return signInfo - 2;
630 0 : }
631 :
632 : //______________________________________________________________________________
633 : Bool_t AliAODTrack::PropagateToDCA(const AliVVertex *vtx,
634 : Double_t b, Double_t maxd, Double_t dz[2], Double_t covar[3])
635 : {
636 : // compute impact parameters to the vertex vtx and their covariance matrix
637 : // b is the Bz, needed to propagate correctly the track to vertex
638 : // only the track parameters are update after the propagation (pos and mom),
639 : // not the covariance matrix. This is OK for propagation over short distance
640 : // inside the beam pipe.
641 : // return kFALSE is something went wrong
642 :
643 : // allowed only for tracks inside the beam pipe
644 0 : Float_t xstart2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
645 0 : if(xstart2 > 3.*3.) { // outside beampipe radius
646 0 : AliError("This method can be used only for propagation inside the beam pipe");
647 0 : return kFALSE;
648 : }
649 :
650 : // convert to AliExternalTrackParam
651 0 : AliExternalTrackParam etp; etp.CopyFromVTrack(this);
652 :
653 : // propagate
654 0 : if(!etp.PropagateToDCA(vtx,b,maxd,dz,covar)) return kFALSE;
655 :
656 : // update track position and momentum
657 0 : Double_t mom[3];
658 0 : etp.GetPxPyPz(mom);
659 0 : SetP(mom,kTRUE);
660 0 : etp.GetXYZ(mom);
661 0 : SetPosition(mom,kFALSE);
662 :
663 :
664 : return kTRUE;
665 0 : }
666 :
667 : //______________________________________________________________________________
668 : Bool_t AliAODTrack::GetPxPyPz(Double_t p[3]) const
669 : {
670 : //---------------------------------------------------------------------
671 : // This function returns the global track momentum components
672 : //---------------------------------------------------------------------
673 0 : p[0]=Px(); p[1]=Py(); p[2]=Pz();
674 0 : return kTRUE;
675 : }
676 :
677 :
678 : //_______________________________________________________________________
679 : Float_t AliAODTrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
680 : {
681 : //
682 : // TPC cluster information
683 : // type 0: get fraction of found/findable clusters with neighbourhood definition
684 : // 1: findable clusters with neighbourhood definition
685 : // 2: found clusters
686 : // bitType:
687 : // 0 - all cluster used
688 : // 1 - clusters used for the kalman update
689 : // definition of findable clusters:
690 : // a cluster is defined as findable if there is another cluster
691 : // within +- nNeighbours pad rows. The idea is to overcome threshold
692 : // effects with a very simple algorithm.
693 : //
694 :
695 :
696 : Int_t found=0;
697 : Int_t findable=0;
698 0 : Int_t last=-nNeighbours;
699 0 : const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
700 :
701 0 : Int_t upperBound=clusterMap.GetNbits();
702 0 : if (upperBound>row1) upperBound=row1;
703 0 : for (Int_t i=row0; i<upperBound; ++i){
704 : //look to current row
705 0 : if (clusterMap[i]) {
706 : last=i;
707 0 : ++found;
708 0 : ++findable;
709 0 : continue;
710 : }
711 : //look to nNeighbours before
712 0 : if ((i-last)<=nNeighbours) {
713 0 : ++findable;
714 0 : continue;
715 : }
716 : //look to nNeighbours after
717 0 : for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
718 0 : if (clusterMap[j]){
719 0 : ++findable;
720 0 : break;
721 : }
722 : }
723 0 : }
724 0 : if (type==2) return found;
725 0 : if (type==1) return findable;
726 :
727 0 : if (type==0){
728 : Float_t fraction=0;
729 0 : if (findable>0)
730 0 : fraction=(Float_t)found/(Float_t)findable;
731 : else
732 : fraction=0;
733 : return fraction;
734 : }
735 0 : return 0; // undefined type - default value
736 0 : }
737 :
738 :
739 : //______________________________________________________________________________
740 : Double_t AliAODTrack::GetTRDslice(Int_t plane, Int_t slice) const {
741 : //
742 : // return TRD Pid information
743 : //
744 0 : if (!fDetPid) return -1;
745 0 : Double32_t *trdSlices=fDetPid->GetTRDslices();
746 0 : if (!trdSlices) return -1;
747 0 : if ((plane<0) || (plane>=kTRDnPlanes)) {
748 0 : return -1.;
749 : }
750 :
751 0 : Int_t ns=fDetPid->GetTRDnSlices();
752 0 : if ((slice<-1) || (slice>=ns)) {
753 0 : return -1.;
754 : }
755 :
756 0 : if(slice>=0) return trdSlices[plane*ns + slice];
757 :
758 : // return average of the dEdx measurements
759 0 : Double_t q=0.; Double32_t *s = &trdSlices[plane*ns];
760 0 : for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
761 0 : return q/ns;
762 0 : }
763 :
764 : //______________________________________________________________________________
765 : UChar_t AliAODTrack::GetTRDntrackletsPID() const{
766 : //
767 : // return number of tracklets calculated from the slices
768 : //
769 0 : if(!fDetPid) return -1;
770 0 : return fDetPid->GetTRDntrackletsPID();
771 0 : }
772 :
773 : //______________________________________________________________________________
774 : UChar_t AliAODTrack::GetTRDncls(Int_t layer) const {
775 : //
776 : // return number of TRD clusters
777 : //
778 0 : if(!fDetPid || layer > 5) return -1;
779 0 : if(layer < 0) return fDetPid->GetTRDncls();
780 0 : else return fDetPid->GetTRDncls(layer);
781 0 : }
782 :
783 : //______________________________________________________________________________
784 : Double_t AliAODTrack::GetTRDmomentum(Int_t plane, Double_t */*sp*/) const
785 : {
786 : //Returns momentum estimation
787 : // in TRD layer "plane".
788 :
789 0 : if (!fDetPid) return -1;
790 0 : const Double_t *trdMomentum=fDetPid->GetTRDmomentum();
791 :
792 0 : if (!trdMomentum) {
793 0 : return -1.;
794 : }
795 0 : if ((plane<0) || (plane>=kTRDnPlanes)) {
796 0 : return -1.;
797 : }
798 :
799 0 : return trdMomentum[plane];
800 0 : }
801 :
802 : //_______________________________________________________________________
803 : Int_t AliAODTrack::GetTOFBunchCrossing(Double_t b, Bool_t) const
804 : {
805 : // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
806 : const double kSpacing = 25e3; // min interbanch spacing
807 : const double kShift = 0;
808 : Int_t bcid = kTOFBCNA; // defualt one
809 0 : if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
810 : //
811 0 : double tdif = GetTOFsignal();
812 0 : if (IsOn(kTIME)) { // integrated time info is there
813 0 : int pid = (int)GetMostProbablePID();
814 0 : double ttimes[10];
815 0 : GetIntegratedTimes(ttimes, pid>=AliPID::kSPECIES ? AliPID::kSPECIESC : AliPID::kSPECIES);
816 0 : tdif -= ttimes[pid];
817 0 : }
818 : else { // assume integrated time info from TOF radius and momentum
819 : const double kRTOF = 385.;
820 : const double kCSpeed = 3.e-2; // cm/ps
821 0 : double p = P();
822 0 : if (p<0.001) p = 1.0;
823 0 : double m = M();
824 : double path = kRTOF; // mean TOF radius
825 0 : if (TMath::Abs(b)>kAlmost0) { // account for curvature
826 0 : double curv = Pt()/(b*kB2C);
827 0 : if (curv>kAlmost0) {
828 0 : double tgl = Pz()/Pt();
829 0 : path = 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+tgl*tgl);
830 0 : }
831 0 : }
832 0 : tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
833 : }
834 0 : bcid = TMath::Nint((tdif - kShift)/kSpacing);
835 : return bcid;
836 0 : }
837 :
838 : void AliAODTrack::SetDetectorPID(const AliDetectorPID *pid)
839 : {
840 : //
841 : // Set the detector PID
842 : //
843 0 : if (fDetectorPID) delete fDetectorPID;
844 0 : fDetectorPID=pid;
845 :
846 0 : }
847 :
848 : //_____________________________________________________________________________
849 : Double_t AliAODTrack::GetHMPIDsignal() const
850 : {
851 0 : if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpSignal();
852 0 : else return -999.;
853 0 : }
854 :
855 : //_____________________________________________________________________________
856 : Double_t AliAODTrack::GetHMPIDoccupancy() const
857 : {
858 0 : if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpOccupancy();
859 0 : else return -999.;
860 0 : }
861 :
862 : //_____________________________________________________________________________
863 : Int_t AliAODTrack::GetHMPIDcluIdx() const
864 : {
865 0 : if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpCluIdx();
866 0 : else return -999;
867 0 : }
868 :
869 : //_____________________________________________________________________________
870 : void AliAODTrack::GetHMPIDtrk(Float_t &x, Float_t &y, Float_t &th, Float_t &ph) const
871 : {
872 0 : x = -999; y = -999.; th = -999.; ph = -999.;
873 :
874 0 : const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
875 0 : if(ring){
876 0 : x = ring->GetHmpTrackX();
877 0 : y = ring->GetHmpTrackY();
878 0 : th = ring->GetHmpTrackTheta();
879 0 : ph = ring->GetHmpTrackPhi();
880 0 : }
881 0 : }
882 :
883 : //_____________________________________________________________________________
884 : void AliAODTrack::GetHMPIDmip(Float_t &x,Float_t &y,Int_t &q, Int_t &nph) const
885 : {
886 0 : x = -999; y = -999.; q = -999; nph = -999;
887 :
888 0 : const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
889 0 : if(ring){
890 0 : x = ring->GetHmpMipX();
891 0 : y = ring->GetHmpMipY();
892 0 : q = (Int_t)ring->GetHmpMipCharge();
893 0 : nph = (Int_t)ring->GetHmpNumOfPhotonClusters();
894 0 : }
895 0 : }
896 :
897 : //_____________________________________________________________________________
898 : Bool_t AliAODTrack::GetOuterHmpPxPyPz(Double_t *p) const
899 : {
900 0 : if(fAODEvent->GetHMPIDringForTrackID(fID)) {fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpMom(p); return kTRUE;}
901 :
902 0 : else return kFALSE;
903 0 : }
904 : //_____________________________________________________________________________
905 : Bool_t AliAODTrack::GetXYZAt(Double_t x, Double_t b, Double_t *r) const
906 : {
907 : //---------------------------------------------------------------------
908 : // This function returns the global track position extrapolated to
909 : // the radial position "x" (cm) in the magnetic field "b" (kG)
910 : //---------------------------------------------------------------------
911 :
912 : //conversion of track parameter representation is
913 : //based on the implementation of AliExternalTrackParam::Set(...)
914 : //maybe some of this code can be moved to AliVTrack to avoid code duplication
915 : Double_t alpha=0.0;
916 0 : Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
917 : Double_t radMax = 45.; // approximately ITS outer radius
918 0 : if (radPos2 < radMax*radMax) { // inside the ITS
919 0 : alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
920 0 : } else { // outside the ITS
921 0 : Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
922 : alpha =
923 0 : TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
924 : }
925 : //
926 : // Get the vertex of origin and the momentum
927 0 : TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
928 0 : TVector3 mom(Px(),Py(),Pz());
929 : //
930 : // Rotate to the local coordinate system
931 0 : ver.RotateZ(-alpha);
932 0 : mom.RotateZ(-alpha);
933 :
934 0 : Double_t param0 = ver.Y();
935 0 : Double_t param1 = ver.Z();
936 0 : Double_t param2 = TMath::Sin(mom.Phi());
937 0 : Double_t param3 = mom.Pz()/mom.Pt();
938 0 : Double_t param4 = TMath::Sign(1/mom.Pt(),(Double_t)fCharge);
939 :
940 : //calculate the propagated coordinates
941 : //this is based on AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r)
942 0 : Double_t dx=x-ver.X();
943 0 : if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
944 :
945 : Double_t f1=param2;
946 0 : Double_t f2=f1 + dx*param4*b*kB2C;
947 :
948 0 : if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
949 0 : if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
950 :
951 0 : Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
952 0 : r[0] = x;
953 0 : r[1] = param0 + dx*(f1+f2)/(r1+r2);
954 0 : r[2] = param1 + dx*(r2 + f2*(f1+f2)/(r1+r2))*param3;//Thanks to Andrea & Peter
955 0 : return Local2GlobalPosition(r,alpha);
956 0 : }
957 :
958 : //_____________________________________________________________________________
959 : Bool_t AliAODTrack::GetXYZatR(Double_t xr,Double_t bz, Double_t *xyz, Double_t* alpSect) const
960 : {
961 : // This method has 3 modes of behaviour
962 : // 1) xyz[3] array is provided but alpSect pointer is 0: calculate the position of track intersection
963 : // with circle of radius xr and fill it in xyz array
964 : // 2) alpSect pointer is provided: find alpha of the sector where the track reaches local coordinate xr
965 : // Note that in this case xr is NOT the radius but the local coordinate.
966 : // If the xyz array is provided, it will be filled by track lab coordinates at local X in this sector
967 : // 3) Neither alpSect nor xyz pointers are provided: just check if the track reaches radius xr
968 : //
969 : //
970 : Double_t alpha=0.0;
971 0 : Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
972 : Double_t radMax = 45.; // approximately ITS outer radius
973 0 : if (radPos2 < radMax*radMax) { // inside the ITS
974 0 : alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
975 0 : } else { // outside the ITS
976 0 : Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
977 : alpha =
978 0 : TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
979 : }
980 : //
981 : // Get the vertex of origin and the momentum
982 0 : TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
983 0 : TVector3 mom(Px(),Py(),Pz());
984 : //
985 : // Rotate to the local coordinate system
986 0 : ver.RotateZ(-alpha);
987 0 : mom.RotateZ(-alpha);
988 : //
989 0 : Double_t fx = ver.X();
990 0 : Double_t fy = ver.Y();
991 0 : Double_t fz = ver.Z();
992 0 : Double_t sn = TMath::Sin(mom.Phi());
993 0 : Double_t tgl = mom.Pz()/mom.Pt();
994 0 : Double_t crv = TMath::Sign(1/mom.Pt(),(Double_t)fCharge)*bz*kB2C;
995 : //
996 0 : if ( (TMath::Abs(bz))<kAlmost0Field ) crv=0.;
997 : //
998 : // general circle parameterization:
999 : // x = (r0+tR)cos(phi0) - tR cos(t+phi0)
1000 : // y = (r0+tR)sin(phi0) - tR sin(t+phi0)
1001 : // where qb is the sign of the curvature, tR is the track's signed radius and r0
1002 : // is the DCA of helix to origin
1003 : //
1004 0 : double tR = 1./crv; // track radius signed
1005 0 : double cs = TMath::Sqrt((1-sn)*(1+sn));
1006 0 : double x0 = fx - sn*tR; // helix center coordinates
1007 0 : double y0 = fy + cs*tR;
1008 0 : double phi0 = TMath::ATan2(y0,x0); // angle of PCA wrt to the origin
1009 0 : if (tR<0) phi0 += TMath::Pi();
1010 0 : if (phi0 > TMath::Pi()) phi0 -= 2.*TMath::Pi();
1011 0 : else if (phi0 <-TMath::Pi()) phi0 += 2.*TMath::Pi();
1012 0 : double cs0 = TMath::Cos(phi0);
1013 0 : double sn0 = TMath::Sin(phi0);
1014 0 : double r0 = x0*cs0 + y0*sn0 - tR; // DCA to origin
1015 0 : double r2R = 1.+r0/tR;
1016 : //
1017 : //
1018 0 : if (r2R<kAlmost0) return kFALSE; // helix is centered at the origin, no specific intersection with other concetric circle
1019 0 : if (!xyz && !alpSect) return kTRUE;
1020 0 : double xr2R = xr/tR;
1021 0 : double r2Ri = 1./r2R;
1022 : // the intersection cos(t) = [1 + (r0/tR+1)^2 - (r0/tR)^2]/[2(1+r0/tR)]
1023 0 : double cosT = 0.5*(r2R + (1-xr2R*xr2R)*r2Ri);
1024 0 : if ( TMath::Abs(cosT)>kAlmost1 ) {
1025 : // printf("Does not reach : %f %f\n",r0,tR);
1026 0 : return kFALSE; // track does not reach the radius xr
1027 : }
1028 : //
1029 0 : double t = TMath::ACos(cosT);
1030 0 : if (tR<0) t = -t;
1031 : // intersection point
1032 0 : double xyzi[3];
1033 0 : xyzi[0] = x0 - tR*TMath::Cos(t+phi0);
1034 0 : xyzi[1] = y0 - tR*TMath::Sin(t+phi0);
1035 0 : if (xyz) { // if postition is requested, then z is needed:
1036 0 : double t0 = TMath::ATan2(cs,-sn) - phi0;
1037 0 : double z0 = fz - t0*tR*tgl;
1038 0 : xyzi[2] = z0 + tR*t*tgl;
1039 0 : }
1040 0 : else xyzi[2] = 0;
1041 : //
1042 0 : Local2GlobalPosition(xyzi,alpha);
1043 : //
1044 0 : if (xyz) {
1045 0 : xyz[0] = xyzi[0];
1046 0 : xyz[1] = xyzi[1];
1047 0 : xyz[2] = xyzi[2];
1048 0 : }
1049 : //
1050 0 : if (alpSect) {
1051 : double &alp = *alpSect;
1052 : // determine the sector of crossing
1053 0 : double phiPos = TMath::Pi()+TMath::ATan2(-xyzi[1],-xyzi[0]);
1054 0 : int sect = ((Int_t)(phiPos*TMath::RadToDeg()))/20;
1055 0 : alp = TMath::DegToRad()*(20*sect+10);
1056 0 : double x2r,f1,f2,r1,r2,dx,dy2dx,yloc=0, ylocMax = xr*TMath::Tan(TMath::Pi()/18); // min max Y within sector at given X
1057 : //
1058 0 : while(1) {
1059 0 : Double_t ca=TMath::Cos(alp-alpha), sa=TMath::Sin(alp-alpha);
1060 0 : if ((cs*ca+sn*sa)<0) {
1061 0 : AliDebug(1,Form("Rotation to target sector impossible: local cos(phi) would become %.2f",cs*ca+sn*sa));
1062 0 : return kFALSE;
1063 : }
1064 : //
1065 0 : f1 = sn*ca - cs*sa;
1066 0 : if (TMath::Abs(f1) >= kAlmost1) {
1067 0 : AliDebug(1,Form("Rotation to target sector impossible: local sin(phi) would become %.2f",f1));
1068 0 : return kFALSE;
1069 : }
1070 : //
1071 0 : double tmpX = fx*ca + fy*sa;
1072 0 : double tmpY = -fx*sa + fy*ca;
1073 : //
1074 : // estimate Y at X=xr
1075 0 : dx=xr-tmpX;
1076 0 : x2r = crv*dx;
1077 0 : f2=f1 + x2r;
1078 0 : if (TMath::Abs(f2) >= kAlmost1) {
1079 0 : AliDebug(1,Form("Propagation in target sector failed ! %.10e",f2));
1080 0 : return kFALSE;
1081 : }
1082 0 : r1 = TMath::Sqrt((1.-f1)*(1.+f1));
1083 0 : r2 = TMath::Sqrt((1.-f2)*(1.+f2));
1084 0 : dy2dx = (f1+f2)/(r1+r2);
1085 0 : yloc = tmpY + dx*dy2dx;
1086 0 : if (yloc>ylocMax) {alp += 2*TMath::Pi()/18; sect++;}
1087 0 : else if (yloc<-ylocMax) {alp -= 2*TMath::Pi()/18; sect--;}
1088 0 : else break;
1089 0 : if (alp >= TMath::Pi()) alp -= 2*TMath::Pi();
1090 0 : else if (alp < -TMath::Pi()) alp += 2*TMath::Pi();
1091 : // if (sect>=18) sect = 0;
1092 : // if (sect<=0) sect = 17;
1093 0 : }
1094 : //
1095 : // if alpha was requested, then recalculate the position at intersection in sector
1096 0 : if (xyz) {
1097 0 : xyz[0] = xr;
1098 0 : xyz[1] = yloc;
1099 0 : if (TMath::Abs(x2r)<0.05) xyz[2] = fz + dx*(r2 + f2*dy2dx)*tgl;
1100 : else {
1101 : // for small dx/R the linear apporximation of the arc by the segment is OK,
1102 : // but at large dx/R the error is very large and leads to incorrect Z propagation
1103 : // angle traversed delta = 2*asin(dist_start_end / R / 2), hence the arc is: R*deltaPhi
1104 : // The dist_start_end is obtained from sqrt(dx^2+dy^2) = x/(r1+r2)*sqrt(2+f1*f2+r1*r2)
1105 : // Similarly, the rotation angle in linear in dx only for dx<<R
1106 0 : double chord = dx*TMath::Sqrt(1+dy2dx*dy2dx); // distance from old position to new one
1107 0 : double rot = 2*TMath::ASin(0.5*chord*crv); // angular difference seen from the circle center
1108 0 : xyz[2] = fz + rot/crv*tgl;
1109 : }
1110 0 : Local2GlobalPosition(xyz,alp);
1111 : }
1112 0 : }
1113 0 : return kTRUE;
1114 : //
1115 0 : }
1116 :
1117 : //_______________________________________________________
1118 : void AliAODTrack::GetITSdEdxSamples(Double_t s[4]) const
1119 : {
1120 : // get ITS dedx samples
1121 0 : if (!fDetPid) for (int i=4;i--;) s[i]=0;
1122 0 : else for (int i=4;i--;) s[i] = fDetPid->GetITSdEdxSample(i);
1123 0 : }
1124 :
1125 : //_____________________________________________
1126 : Double_t AliAODTrack::GetMassForTracking() const
1127 : {
1128 0 : int pid = fPIDForTracking;
1129 0 : if (pid<AliPID::kPion) pid = AliPID::kPion;
1130 0 : double m = AliPID::ParticleMass(fPIDForTracking);
1131 0 : return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
1132 : }
1133 : //_______________________________________________________
1134 : const AliTOFHeader* AliAODTrack::GetTOFHeader() const {
1135 0 : return fAODEvent->GetTOFHeader();
1136 : }
1137 :
1138 : //_______________________________________________________
1139 : Int_t AliAODTrack::GetNcls(Int_t idet) const
1140 : {
1141 : // Get number of clusters by subdetector index
1142 : //
1143 : Int_t ncls = 0;
1144 0 : switch(idet){
1145 : case 0:
1146 0 : ncls = GetITSNcls();
1147 0 : break;
1148 : case 1:
1149 0 : ncls = (Int_t)GetTPCNcls();
1150 0 : break;
1151 : case 2:
1152 0 : ncls = (Int_t)GetTRDncls();
1153 0 : break;
1154 : case 3:
1155 : break;
1156 : /*if (fTOFindex != -1)
1157 : ncls = 1;*/
1158 : break;
1159 : case 4: //PHOS
1160 : break;
1161 : case 5: //HMPID
1162 : break;
1163 : if ((GetHMPIDcluIdx() >= 0) && (GetHMPIDcluIdx() < 7000000)) {
1164 : if ((GetHMPIDcluIdx()%1000000 != 9999) && (GetHMPIDcluIdx()%1000000 != 99999)) {
1165 : ncls = 1;
1166 : }
1167 : }
1168 : break;
1169 : default:
1170 : break;
1171 : }
1172 0 : return ncls;
1173 : }
1174 :
1175 0 : Int_t AliAODTrack::GetTrackParam ( AliExternalTrackParam & ) const {return 0;}
1176 0 : Int_t AliAODTrack::GetTrackParamRefitted ( AliExternalTrackParam & ) const {return 0;}
1177 0 : Int_t AliAODTrack::GetTrackParamIp ( AliExternalTrackParam & ) const {return 0;}
1178 0 : Int_t AliAODTrack::GetTrackParamTPCInner ( AliExternalTrackParam & ) const {return 0;}
1179 0 : Int_t AliAODTrack::GetTrackParamOp ( AliExternalTrackParam & ) const {return 0;}
1180 0 : Int_t AliAODTrack::GetTrackParamCp ( AliExternalTrackParam & ) const {return 0;}
1181 0 : Int_t AliAODTrack::GetTrackParamITSOut ( AliExternalTrackParam & ) const {return 0;}
1182 :
|