1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 // Implementation of the ESD track class
17 // ESD = Event Summary Data
18 // This is the class to deal with during the phisics analysis of data
19 // Origin: Iouri Belikov, CERN
20 // e-mail: Jouri.Belikov@cern.ch
24 // What do you need to know before starting analysis
25 // (by Marian Ivanov: marian.ivanov@cern.ch)
29 // 1. What is the AliESDtrack
30 // 2. What informations do we store
31 // 3. How to use the information for analysis
34 // 1.AliESDtrack is the container of the information about the track/particle
35 // reconstructed during Barrel Tracking.
36 // The track information is propagated from one tracking detector to
37 // other using the functionality of AliESDtrack - Current parameters.
39 // No global fit model is used.
40 // Barrel tracking use Kalman filtering technique, it gives optimal local
41 // track parameters at given point under certian assumptions.
43 // Kalman filter take into account additional effect which are
44 // difficult to handle using global fit.
46 // a.) Multiple scattering
48 // c.) Non homogenous magnetic field
50 // In general case, following barrel detectors are contributing to
51 // the Kalman track information:
56 // In general 3 reconstruction itteration are performed:
57 // 1. Find tracks - sequence TPC->ITS
58 // 2. PropagateBack - sequence ITS->TPC->TRD -> Outer PID detectors
59 // 3. Refit invward - sequence TRD->TPC->ITS
60 // The current tracks are updated after each detector (see bellow).
61 // In specical cases a track sanpshots are stored.
64 // For some type of analysis (+visualization) track local parameters at
65 // different position are neccesary. A snapshots during the track
66 // propagation are created.
67 // (See AliExternalTrackParam class for desctiption of variables and
70 // a. Current parameters - class itself (AliExternalTrackParam)
71 // Contributors: general case TRD->TPC->ITS
72 // Preferable usage: Decission - primary or secondary track
73 // NOTICE - By default the track parameters are stored at the DCA point
74 // to the primary vertex. optimal for primary tracks,
75 // far from optimal for secondary tracks.
76 // b. Constrained parameters - Kalman information updated with
77 // the Primary vertex information
78 // Contributors: general case TRD->TPC->ITS
79 // Preferable usage: Use only for tracks selected as primary
80 // NOTICE - not real constrain - taken as additional measurement
81 // with corresponding error
83 // const AliExternalTrackParam *GetConstrainedParam() const {return fCp;}
84 // c. Inner parameters - Track parameters at inner wall of the TPC
85 // Contributors: general case TRD->TPC
87 // const AliExternalTrackParam *GetInnerParam() const { return fIp;}
89 // d. TPCinnerparam - contributors - TPC only
91 // Preferable usage: Requested for HBT study
92 // (smaller correlations as using also ITS information)
93 // NOTICE - the track parameters are propagated to the DCA to
95 // Optimal for primary, far from optimal for secondary tracks
97 // const AliExternalTrackParam *GetTPCInnerParam() const {return fTPCInner;}
99 // e. Outer parameters -
100 // Contributors- general case - ITS-> TPC -> TRD
101 // The last point - Outer parameters radius is determined
102 // e.a) Local inclination angle bigger than threshold -
103 // Low momenta tracks
104 // e.a) Catastrofic energy losss in material
105 // e.b) Not further improvement (no space points)
107 // a.) Tracking: Starting parameter for Refit inward
110 // NOTICE: Should be not used for the physic analysis
112 // const AliExternalTrackParam *GetOuterParam() const { return fOp;}
114 //-----------------------------------------------------------------
117 #include <TParticle.h>
118 #include <TDatabasePDG.h>
119 #include <TMatrixD.h>
121 #include "AliESDVertex.h"
122 #include "AliESDtrack.h"
123 #include "AliESDEvent.h"
124 #include "AliKalmanTrack.h"
125 #include "AliVTrack.h"
127 #include "AliTrackPointArray.h"
128 #include "TPolyMarker3D.h"
129 #include "AliTrackerBase.h"
130 #include "AliTPCdEdxInfo.h"
131 #include "AliDetectorPID.h"
132 #include "TTreeStream.h"
133 #include "TObjArray.h"
135 ClassImp(AliESDtrack)
137 void SetPIDValues(Double_t * dest, const Double_t * src, Int_t n) {
138 // This function copies "n" PID weights from "scr" to "dest"
139 // and normalizes their sum to 1 thus producing conditional probabilities.
140 // The negative weights are set to 0.
141 // In case all the weights are non-positive they are replaced by
142 // uniform probabilities
146 Float_t uniform = 1./(Float_t)n;
149 for (Int_t i=0; i<n; i++)
159 for (Int_t i=0; i<n; i++) dest[i] /= sum;
161 for (Int_t i=0; i<n; i++) dest[i] = uniform;
164 //_______________________________________________________________________
165 AliESDtrack::AliESDtrack() :
166 AliExternalTrackParam(),
173 fTPCFitMap(159),//number of padrows
174 fTPCClusterMap(159),//number of padrows
175 fTPCSharedMap(159),//number of padrows
187 fCaloIndex(kEMCALNoMatch),
194 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
197 fCdd(0),fCdz(0),fCzz(0),
215 fTOFsignalTuned(99999),
216 fTOFsignalToT(99999),
217 fTOFsignalRaw(99999),
243 fVertexID(-2),// -2 means an orphan track
245 fCacheNCrossedRows(-10),
246 fCacheChi2TPCConstrainedVsGlobal(-10),
247 fCacheChi2TPCConstrainedVsGlobalVertex(0),
249 fTrackPhiOnEMCal(-999),
250 fTrackEtaOnEMCal(-999),
251 fTrackPtOnEMCal(-999),
256 // The default ESD constructor
258 if (!OnlineMode()) fFriendTrack=new AliESDfriendTrack();
261 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
262 for (i=0; i<AliPID::kSPECIES; i++) {
271 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
272 for (i=0; i<3; i++) { fV0Indexes[i]=0;}
273 for (i=0;i<kTRDnPlanes;i++) {
276 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
277 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
278 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
279 for (i=0;i<12;i++) {fITSModule[i]=-1;}
282 bool AliESDtrack::fgkOnlineMode=false;
284 //_______________________________________________________________________
285 AliESDtrack::AliESDtrack(const AliESDtrack& track):
286 AliExternalTrackParam(track),
293 fTPCFitMap(track.fTPCFitMap),
294 fTPCClusterMap(track.fTPCClusterMap),
295 fTPCSharedMap(track.fTPCSharedMap),
296 fFlags(track.fFlags),
298 fLabel(track.fLabel),
299 fITSLabel(track.fITSLabel),
300 fTPCLabel(track.fTPCLabel),
301 fTRDLabel(track.fTRDLabel),
303 fTOFCalChannel(track.fTOFCalChannel),
304 fTOFindex(track.fTOFindex),
305 fHMPIDqn(track.fHMPIDqn),
306 fHMPIDcluIdx(track.fHMPIDcluIdx),
307 fCaloIndex(track.fCaloIndex),
308 fHMPIDtrkTheta(track.fHMPIDtrkTheta),
309 fHMPIDtrkPhi(track.fHMPIDtrkPhi),
310 fHMPIDsignal(track.fHMPIDsignal),
312 fTrackLength(track.fTrackLength),
313 fdTPC(track.fdTPC),fzTPC(track.fzTPC),
314 fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
315 fCchi2TPC(track.fCchi2TPC),
316 fD(track.fD),fZ(track.fZ),
317 fCdd(track.fCdd),fCdz(track.fCdz),fCzz(track.fCzz),
318 fCchi2(track.fCchi2),
319 fITSchi2(track.fITSchi2),
320 fTPCchi2(track.fTPCchi2),
321 fTPCchi2Iter1(track.fTPCchi2Iter1),
322 fTRDchi2(track.fTRDchi2),
323 fTOFchi2(track.fTOFchi2),
324 fHMPIDchi2(track.fHMPIDchi2),
325 fGlobalChi2(track.fGlobalChi2),
326 fITSsignal(track.fITSsignal),
327 fTPCsignal(track.fTPCsignal),
328 fTPCsignalTuned(track.fTPCsignalTuned),
329 fTPCsignalS(track.fTPCsignalS),
331 fTRDsignal(track.fTRDsignal),
332 fTRDQuality(track.fTRDQuality),
333 fTRDBudget(track.fTRDBudget),
334 fTOFsignal(track.fTOFsignal),
335 fTOFsignalTuned(track.fTOFsignalTuned),
336 fTOFsignalToT(track.fTOFsignalToT),
337 fTOFsignalRaw(track.fTOFsignalRaw),
338 fTOFsignalDz(track.fTOFsignalDz),
339 fTOFsignalDx(track.fTOFsignalDx),
340 fTOFdeltaBC(track.fTOFdeltaBC),
341 fTOFl0l1(track.fTOFl0l1),
342 fCaloDx(track.fCaloDx),
343 fCaloDz(track.fCaloDz),
344 fHMPIDtrkX(track.fHMPIDtrkX),
345 fHMPIDtrkY(track.fHMPIDtrkY),
346 fHMPIDmipX(track.fHMPIDmipX),
347 fHMPIDmipY(track.fHMPIDmipY),
348 fTPCncls(track.fTPCncls),
349 fTPCnclsF(track.fTPCnclsF),
350 fTPCsignalN(track.fTPCsignalN),
351 fTPCnclsIter1(track.fTPCnclsIter1),
352 fTPCnclsFIter1(track.fTPCnclsIter1),
353 fITSncls(track.fITSncls),
354 fITSClusterMap(track.fITSClusterMap),
355 fITSSharedMap(track.fITSSharedMap),
356 fTRDncls(track.fTRDncls),
357 fTRDncls0(track.fTRDncls0),
358 fTRDntracklets(track.fTRDntracklets),
359 fTRDNchamberdEdx(track.fTRDNchamberdEdx),
360 fTRDNclusterdEdx(track.fTRDNclusterdEdx),
361 fTRDnSlices(track.fTRDnSlices),
363 fVertexID(track.fVertexID),
364 fESDEvent(track.fESDEvent),
365 fCacheNCrossedRows(track.fCacheNCrossedRows),
366 fCacheChi2TPCConstrainedVsGlobal(track.fCacheChi2TPCConstrainedVsGlobal),
367 fCacheChi2TPCConstrainedVsGlobalVertex(track.fCacheChi2TPCConstrainedVsGlobalVertex),
369 fTrackPhiOnEMCal(track.fTrackPhiOnEMCal),
370 fTrackEtaOnEMCal(track.fTrackEtaOnEMCal),
371 fTrackPtOnEMCal(track.fTrackPtOnEMCal),
372 fNtofClusters(track.fNtofClusters),
378 for (Int_t i=kNITSchi2Std;i--;) fITSchi2Std[i] = track.fITSchi2Std[i];
380 if(track.fTrackTime){
381 fTrackTime = new Double32_t[AliPID::kSPECIESC];
382 for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i]=track.fTrackTime[i];
385 for (Int_t i=0;i<AliPID::kSPECIES;i++) fR[i]=track.fR[i];
387 for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=track.fITSr[i];
389 for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=track.fTPCr[i];
390 for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=track.fITSdEdxSamples[i];}
391 for (Int_t i=0;i<4;i++) {fTPCPoints[i]=track.fTPCPoints[i];}
392 for (Int_t i=0; i<3;i++) { fKinkIndexes[i]=track.fKinkIndexes[i];}
393 for (Int_t i=0; i<3;i++) { fV0Indexes[i]=track.fV0Indexes[i];}
395 for (Int_t i=0;i<kTRDnPlanes;i++) {
396 fTRDTimBin[i]=track.fTRDTimBin[i];
400 fTRDslices=new Double32_t[fTRDnSlices];
401 for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=track.fTRDslices[i];
404 if (track.fDetectorPID) fDetectorPID = new AliDetectorPID(*track.fDetectorPID);
406 for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i]=track.fTRDr[i];
407 for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i]=track.fTOFr[i];
409 if(!fTOFLabel) fTOFLabel = new Int_t[3];
410 for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
413 for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
414 for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
415 for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i]=track.fHMPIDr[i];
417 if (track.fCp) fCp=new AliExternalTrackParam(*track.fCp);
418 if (track.fIp) fIp=new AliExternalTrackParam(*track.fIp);
419 if (track.fTPCInner) fTPCInner=new AliExternalTrackParam(*track.fTPCInner);
420 if (track.fOp) fOp=new AliExternalTrackParam(*track.fOp);
421 if (track.fHMPIDp) fHMPIDp=new AliExternalTrackParam(*track.fHMPIDp);
422 if (track.fTPCdEdxInfo) fTPCdEdxInfo = new AliTPCdEdxInfo(*track.fTPCdEdxInfo);
425 if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
427 if(fNtofClusters > 0){
428 fTOFcluster = new Int_t[fNtofClusters];
429 for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = track.fTOFcluster[i];
433 //_______________________________________________________________________
434 AliESDtrack::AliESDtrack(const AliVTrack *track) :
435 AliExternalTrackParam(track),
442 fTPCFitMap(159),//number of padrows
443 fTPCClusterMap(159),//number of padrows
444 fTPCSharedMap(159),//number of padrows
456 fCaloIndex(kEMCALNoMatch),
463 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
466 fCdd(0),fCdz(0),fCzz(0),
484 fTOFsignalTuned(99999),
485 fTOFsignalToT(99999),
486 fTOFsignalRaw(99999),
512 fVertexID(-2), // -2 means an orphan track
514 fCacheNCrossedRows(-10),
515 fCacheChi2TPCConstrainedVsGlobal(-10),
516 fCacheChi2TPCConstrainedVsGlobalVertex(0),
518 fTrackPhiOnEMCal(-999),
519 fTrackEtaOnEMCal(-999),
520 fTrackPtOnEMCal(-999),
525 // ESD track from AliVTrack.
526 // This is not a copy constructor !
529 if (track->InheritsFrom("AliExternalTrackParam")) {
530 AliError("This is not a copy constructor. Use AliESDtrack(const AliESDtrack &) !");
531 AliWarning("Calling the default constructor...");
536 // Reset all the arrays
538 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
539 for (i=0; i<AliPID::kSPECIES; i++) {
548 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
549 for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
550 for (i=0;i<kTRDnPlanes;i++) {
553 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
554 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
555 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
556 for (i=0;i<12;i++) {fITSModule[i]=-1;}
559 SetID(track->GetID());
561 // Set ITS cluster map
562 fITSClusterMap=track->GetITSClusterMap();
567 if(HasPointOnITSLayer(i)) fITSncls++;
571 fTPCncls=track->GetTPCNcls();
572 fTPCnclsF=track->GetTPCNclsF();
574 const TBits* bmap = track->GetTPCClusterMapPtr();
575 if (bmap) SetTPCClusterMap(*bmap);
576 bmap = GetTPCFitMapPtr();
577 if (bmap) SetTPCFitMap(*bmap);
578 bmap = GetTPCSharedMapPtr();
579 if (bmap) SetTPCSharedMap(*bmap);
581 // Set the combined PID
582 const Double_t *pid = track->PID();
583 if(pid) for (i=0; i<AliPID::kSPECIES; i++) fR[i]=pid[i];
585 // calo matched cluster id
586 SetEMCALcluster(track->GetEMCALcluster());
587 // AliESD track label
590 fITSsignal = track->GetITSsignal();
592 track->GetITSdEdxSamples(itsdEdx);
593 SetITSdEdxSamples(itsdEdx);
595 SetTPCsignal(track->GetTPCsignal(),fTPCsignalS,track->GetTPCsignalN()); // No signalS in AODPi
596 AliTPCdEdxInfo * dEdxInfo = track->GetTPCdEdxInfo();
597 if (dEdxInfo) SetTPCdEdxInfo(new AliTPCdEdxInfo(*dEdxInfo));
599 SetTRDsignal(track->GetTRDsignal());
600 int ntrdsl = track->GetNumberOfTRDslices();
602 SetNumberOfTRDslices((ntrdsl+2)*kTRDnPlanes);
603 for (int ipl=kTRDnPlanes;ipl--;){
604 for (int isl=ntrdsl;isl--;) SetTRDslice(track->GetTRDslice(ipl,isl),ipl,isl);
605 Double_t sp, p = track->GetTRDmomentum(ipl, &sp);
606 SetTRDmomentum(p, ipl, &sp);
610 fTRDncls = track->GetTRDncls();
611 fTRDntracklets &= 0xff & track->GetTRDntrackletsPID();
612 fTRDchi2 = track->GetTRDchi2();
614 SetTOFsignal(track->GetTOFsignal());
615 Double_t expt[AliPID::kSPECIESC];
616 track->GetIntegratedTimes(expt);
617 SetIntegratedTimes(expt);
619 SetTrackPhiEtaPtOnEMCal(track->GetTrackPhiOnEMCal(),track->GetTrackEtaOnEMCal(),track->GetTrackPtOnEMCal());
621 SetLabel(track->GetLabel());
623 SetStatus(track->GetStatus());
626 //_______________________________________________________________________
627 AliESDtrack::AliESDtrack(TParticle * part) :
628 AliExternalTrackParam(),
635 fTPCFitMap(159),//number of padrows
636 fTPCClusterMap(159),//number of padrows
637 fTPCSharedMap(159),//number of padrows
649 fCaloIndex(kEMCALNoMatch),
656 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
659 fCdd(0),fCdz(0),fCzz(0),
677 fTOFsignalTuned(99999),
678 fTOFsignalToT(99999),
679 fTOFsignalRaw(99999),
705 fVertexID(-2), // -2 means an orphan track
707 fCacheNCrossedRows(-10),
708 fCacheChi2TPCConstrainedVsGlobal(-10),
709 fCacheChi2TPCConstrainedVsGlobalVertex(0),
711 fTrackPhiOnEMCal(-999),
712 fTrackEtaOnEMCal(-999),
713 fTrackPtOnEMCal(-999),
718 // ESD track from TParticle
721 // Reset all the arrays
723 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
724 for (i=0; i<AliPID::kSPECIES; i++) {
733 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
734 for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
735 for (i=0;i<kTRDnPlanes;i++) {
738 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
739 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
740 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
741 for (i=0;i<12;i++) {fITSModule[i]=-1;}
743 // Calculate the AliExternalTrackParam content
750 // Calculate alpha: the rotation angle of the corresponding local system (TPC sector)
751 alpha = part->Phi()*180./TMath::Pi();
752 if (alpha<0) alpha+= 360.;
753 if (alpha>360) alpha -= 360.;
755 Int_t sector = (Int_t)(alpha/20.);
756 alpha = 10. + 20.*sector;
758 alpha *= TMath::Pi();
760 // Covariance matrix: no errors, the parameters are exact
761 for (i=0; i<15; i++) covar[i]=0.;
763 // Get the vertex of origin and the momentum
764 TVector3 ver(part->Vx(),part->Vy(),part->Vz());
765 TVector3 mom(part->Px(),part->Py(),part->Pz());
767 // Rotate to the local coordinate system (TPC sector)
771 // X of the referense plane
774 Int_t pdgCode = part->GetPdgCode();
777 TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge();
781 param[2] = TMath::Sin(mom.Phi());
782 param[3] = mom.Pz()/mom.Pt();
783 param[4] = TMath::Sign(1/mom.Pt(),charge);
785 // Set AliExternalTrackParam
786 Set(xref, alpha, param, covar);
791 switch (TMath::Abs(pdgCode)) {
817 // If the particle is not e,mu,pi,K or p the PID probabilities are set to 0
818 if (indexPID < AliPID::kSPECIES) {
824 fHMPIDr[indexPID]=1.;
827 // AliESD track label
828 SetLabel(part->GetUniqueID());
832 //_______________________________________________________________________
833 AliESDtrack::~AliESDtrack(){
835 // This is destructor according Coding Conventrions
837 //printf("Delete track\n");
848 //Reset cached values - needed for TClonesArray in AliESDInputHandler
849 fCacheNCrossedRows = -10.;
850 fCacheChi2TPCConstrainedVsGlobal = -10.;
851 if(fCacheChi2TPCConstrainedVsGlobalVertex) fCacheChi2TPCConstrainedVsGlobalVertex = 0;
854 delete[] fTOFcluster;
860 if(fTrackTime) delete[] fTrackTime;
861 if(fTOFLabel) delete[] fTOFLabel;
864 AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
867 if(&source == this) return *this;
868 AliExternalTrackParam::operator=(source);
872 // we have the trackparam: assign or copy construct
873 if(fCp)*fCp = *source.fCp;
874 else fCp = new AliExternalTrackParam(*source.fCp);
877 // no track param delete the old one
883 // we have the trackparam: assign or copy construct
884 if(fIp)*fIp = *source.fIp;
885 else fIp = new AliExternalTrackParam(*source.fIp);
888 // no track param delete the old one
894 if(source.fTPCInner){
895 // we have the trackparam: assign or copy construct
896 if(fTPCInner) *fTPCInner = *source.fTPCInner;
897 else fTPCInner = new AliExternalTrackParam(*source.fTPCInner);
900 // no track param delete the old one
905 if(source.fTPCdEdxInfo) {
906 if(fTPCdEdxInfo) *fTPCdEdxInfo = *source.fTPCdEdxInfo;
907 fTPCdEdxInfo = new AliTPCdEdxInfo(*source.fTPCdEdxInfo);
911 // we have the trackparam: assign or copy construct
912 if(fOp) *fOp = *source.fOp;
913 else fOp = new AliExternalTrackParam(*source.fOp);
916 // no track param delete the old one
923 // we have the trackparam: assign or copy construct
924 if(fHMPIDp) *fHMPIDp = *source.fHMPIDp;
925 else fHMPIDp = new AliExternalTrackParam(*source.fHMPIDp);
928 // no track param delete the old one
933 // copy also the friend track
934 // use copy constructor
935 if(source.fFriendTrack){
936 // we have the trackparam: assign or copy construct
937 delete fFriendTrack; fFriendTrack=new AliESDfriendTrack(*source.fFriendTrack);
940 // no track param delete the old one
941 delete fFriendTrack; fFriendTrack= 0;
944 fTPCFitMap = source.fTPCFitMap;
945 fTPCClusterMap = source.fTPCClusterMap;
946 fTPCSharedMap = source.fTPCSharedMap;
948 fFlags = source.fFlags;
950 fLabel = source.fLabel;
951 fITSLabel = source.fITSLabel;
952 for(int i = 0; i< 12;++i){
953 fITSModule[i] = source.fITSModule[i];
955 fTPCLabel = source.fTPCLabel;
956 fTRDLabel = source.fTRDLabel;
957 if(source.fTOFLabel){
958 if(!fTOFLabel) fTOFLabel = new Int_t[3];
959 for(int i = 0; i< 3;++i){
960 fTOFLabel[i] = source.fTOFLabel[i];
963 fTOFCalChannel = source.fTOFCalChannel;
964 fTOFindex = source.fTOFindex;
965 fHMPIDqn = source.fHMPIDqn;
966 fHMPIDcluIdx = source.fHMPIDcluIdx;
967 fCaloIndex = source.fCaloIndex;
968 for (int i=kNITSchi2Std;i--;) fITSchi2Std[i] = source.fITSchi2Std[i];
969 for(int i = 0; i< 3;++i){
970 fKinkIndexes[i] = source.fKinkIndexes[i];
971 fV0Indexes[i] = source.fV0Indexes[i];
974 for(int i = 0; i< AliPID::kSPECIES;++i){
975 fR[i] = source.fR[i];
976 fITSr[i] = source.fITSr[i];
977 fTPCr[i] = source.fTPCr[i];
978 fTRDr[i] = source.fTRDr[i];
979 fTOFr[i] = source.fTOFr[i];
980 fHMPIDr[i] = source.fHMPIDr[i];
983 fHMPIDtrkTheta = source.fHMPIDtrkTheta;
984 fHMPIDtrkPhi = source.fHMPIDtrkPhi;
985 fHMPIDsignal = source.fHMPIDsignal;
991 if(source.fTrackTime){
992 fTrackTime = new Double32_t[AliPID::kSPECIESC];
993 for(Int_t i=0;i < AliPID::kSPECIESC;i++)
994 fTrackTime[i] = source.fTrackTime[i];
997 fTrackLength = source. fTrackLength;
998 fdTPC = source.fdTPC;
999 fzTPC = source.fzTPC;
1000 fCddTPC = source.fCddTPC;
1001 fCdzTPC = source.fCdzTPC;
1002 fCzzTPC = source.fCzzTPC;
1003 fCchi2TPC = source.fCchi2TPC;
1010 fCchi2 = source.fCchi2;
1012 fITSchi2 = source.fITSchi2;
1013 fTPCchi2 = source.fTPCchi2;
1014 fTPCchi2Iter1 = source.fTPCchi2Iter1;
1015 fTRDchi2 = source.fTRDchi2;
1016 fTOFchi2 = source.fTOFchi2;
1017 fHMPIDchi2 = source.fHMPIDchi2;
1019 fGlobalChi2 = source.fGlobalChi2;
1021 fITSsignal = source.fITSsignal;
1022 for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=source.fITSdEdxSamples[i];}
1023 fTPCsignal = source.fTPCsignal;
1024 fTPCsignalTuned = source.fTPCsignalTuned;
1025 fTPCsignalS = source.fTPCsignalS;
1026 for(int i = 0; i< 4;++i){
1027 fTPCPoints[i] = source.fTPCPoints[i];
1029 fTRDsignal = source.fTRDsignal;
1030 fTRDNchamberdEdx = source.fTRDNchamberdEdx;
1031 fTRDNclusterdEdx = source.fTRDNclusterdEdx;
1033 for(int i = 0;i < kTRDnPlanes;++i){
1034 fTRDTimBin[i] = source.fTRDTimBin[i];
1038 delete[] fTRDslices;
1040 fTRDnSlices=source.fTRDnSlices;
1042 fTRDslices=new Double32_t[fTRDnSlices];
1043 for(int j = 0;j < fTRDnSlices;++j) fTRDslices[j] = source.fTRDslices[j];
1046 fTRDQuality = source.fTRDQuality;
1047 fTRDBudget = source.fTRDBudget;
1048 fTOFsignal = source.fTOFsignal;
1049 fTOFsignalTuned = source.fTOFsignalTuned;
1050 fTOFsignalToT = source.fTOFsignalToT;
1051 fTOFsignalRaw = source.fTOFsignalRaw;
1052 fTOFsignalDz = source.fTOFsignalDz;
1053 fTOFsignalDx = source.fTOFsignalDx;
1054 fTOFdeltaBC = source.fTOFdeltaBC;
1055 fTOFl0l1 = source.fTOFl0l1;
1057 for(int i = 0;i<10;++i){
1058 fTOFInfo[i] = source.fTOFInfo[i];
1061 fHMPIDtrkX = source.fHMPIDtrkX;
1062 fHMPIDtrkY = source.fHMPIDtrkY;
1063 fHMPIDmipX = source.fHMPIDmipX;
1064 fHMPIDmipY = source.fHMPIDmipY;
1066 fTPCncls = source.fTPCncls;
1067 fTPCnclsF = source.fTPCnclsF;
1068 fTPCsignalN = source.fTPCsignalN;
1069 fTPCnclsIter1 = source.fTPCnclsIter1;
1070 fTPCnclsFIter1 = source.fTPCnclsFIter1;
1072 fITSncls = source.fITSncls;
1073 fITSClusterMap = source.fITSClusterMap;
1074 fITSSharedMap = source.fITSSharedMap;
1075 fTRDncls = source.fTRDncls;
1076 fTRDncls0 = source.fTRDncls0;
1077 fTRDntracklets = source.fTRDntracklets;
1078 fVertexID = source.fVertexID;
1080 fCacheNCrossedRows = source.fCacheNCrossedRows;
1081 fCacheChi2TPCConstrainedVsGlobal = source.fCacheChi2TPCConstrainedVsGlobal;
1082 fCacheChi2TPCConstrainedVsGlobalVertex = source.fCacheChi2TPCConstrainedVsGlobalVertex;
1084 delete fDetectorPID;
1086 if (source.fDetectorPID) fDetectorPID = new AliDetectorPID(*source.fDetectorPID);
1088 fTrackPhiOnEMCal= source.fTrackPhiOnEMCal;
1089 fTrackEtaOnEMCal= source.fTrackEtaOnEMCal;
1090 fTrackPtOnEMCal= source.fTrackPtOnEMCal;
1093 delete[] fTOFcluster;
1095 fNtofClusters = source.fNtofClusters;
1096 if(fNtofClusters > 0){
1097 fTOFcluster = new Int_t[fNtofClusters];
1098 for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = source.fTOFcluster[i];
1106 void AliESDtrack::Copy(TObject &obj) const {
1108 // this overwrites the virtual TOBject::Copy()
1109 // to allow run time copying without casting
1112 if(this==&obj)return;
1113 AliESDtrack *robj = dynamic_cast<AliESDtrack*>(&obj);
1114 if(!robj)return; // not an AliESDtrack
1121 void AliESDtrack::AddCalibObject(TObject * object){
1123 // add calib object to the list
1125 if (!fFriendTrack) fFriendTrack = new AliESDfriendTrack;
1126 if (!fFriendTrack) return;
1127 fFriendTrack->AddCalibObject(object);
1130 TObject * AliESDtrack::GetCalibObject(Int_t index){
1132 // return calib objct at given position
1134 if (!fFriendTrack) return 0;
1135 return fFriendTrack->GetCalibObject(index);
1139 Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
1141 // Fills the information of the TPC-only first reconstruction pass
1142 // into the passed ESDtrack object. For consistency fTPCInner is also filled
1147 // For data produced before r26675
1148 // RelateToVertexTPC was not properly called during reco
1149 // so you'll have to call it again, before FillTPCOnlyTrack
1150 // Float_t p[2],cov[3];
1151 // track->GetImpactParametersTPC(p,cov);
1152 // if(p[0]==0&&p[1]==0) // <- Default values
1153 // track->RelateToVertexTPC(esd->GetPrimaryVertexTPC(),esd->GetMagneticField(),kVeryBig);
1156 if(!fTPCInner)return kFALSE;
1158 // fill the TPC track params to the global track parameters
1159 track.Set(fTPCInner->GetX(),fTPCInner->GetAlpha(),fTPCInner->GetParameter(),fTPCInner->GetCovariance());
1162 track.fCdd = fCddTPC;
1163 track.fCdz = fCdzTPC;
1164 track.fCzz = fCzzTPC;
1166 // copy the inner params
1167 if(track.fIp) *track.fIp = *fIp;
1168 else track.fIp = new AliExternalTrackParam(*fIp);
1170 // copy the TPCinner parameters
1171 if(track.fTPCInner) *track.fTPCInner = *fTPCInner;
1172 else track.fTPCInner = new AliExternalTrackParam(*fTPCInner);
1173 track.fdTPC = fdTPC;
1174 track.fzTPC = fzTPC;
1175 track.fCddTPC = fCddTPC;
1176 track.fCdzTPC = fCdzTPC;
1177 track.fCzzTPC = fCzzTPC;
1178 track.fCchi2TPC = fCchi2TPC;
1180 // copy all other TPC specific parameters
1182 // replace label by TPC label
1183 track.fLabel = fTPCLabel;
1184 track.fTPCLabel = fTPCLabel;
1186 track.fTPCchi2 = fTPCchi2;
1187 track.fTPCchi2Iter1 = fTPCchi2Iter1;
1188 track.fTPCsignal = fTPCsignal;
1189 track.fTPCsignalTuned = fTPCsignalTuned;
1190 track.fTPCsignalS = fTPCsignalS;
1191 for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
1193 track.fTPCncls = fTPCncls;
1194 track.fTPCnclsF = fTPCnclsF;
1195 track.fTPCsignalN = fTPCsignalN;
1196 track.fTPCnclsIter1 = fTPCnclsIter1;
1197 track.fTPCnclsFIter1 = fTPCnclsFIter1;
1200 for(int i=0;i<AliPID::kSPECIES;++i){
1201 track.fTPCr[i] = fTPCr[i];
1202 // combined PID is TPC only!
1203 track.fR[i] = fTPCr[i];
1205 track.fTPCFitMap = fTPCFitMap;
1206 track.fTPCClusterMap = fTPCClusterMap;
1207 track.fTPCSharedMap = fTPCSharedMap;
1211 track.fFlags = kTPCin;
1214 track.fFlags |= fFlags & kTPCpid; //copy the TPCpid status flag
1216 for (Int_t i=0;i<3;i++) track.fKinkIndexes[i] = fKinkIndexes[i];
1222 //_______________________________________________________________________
1223 void AliESDtrack::MakeMiniESDtrack(){
1224 // Resets everything except
1225 // fFlags: Reconstruction status flags
1226 // fLabel: Track label
1227 // fID: Unique ID of the track
1228 // Impact parameter information
1229 // fR[AliPID::kSPECIES]: combined "detector response probability"
1230 // Running track parameters in the base class (AliExternalTrackParam)
1235 for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i] = 0;
1237 // Reset track parameters constrained to the primary vertex
1240 // Reset track parameters at the inner wall of TPC
1242 delete fTPCInner;fTPCInner=0;
1243 // Reset track parameters at the inner wall of the TRD
1245 // Reset track parameters at the HMPID
1246 delete fHMPIDp;fHMPIDp = 0;
1249 // Reset ITS track related information
1255 for (Int_t i=0;i<4;i++) fITSdEdxSamples[i] = 0.;
1256 for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0;
1259 // Reset TPC related track information
1273 for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=0;
1275 for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
1276 for (Int_t i=0; i<3;i++) fKinkIndexes[i] = 0;
1277 for (Int_t i=0; i<3;i++) fV0Indexes[i] = 0;
1279 // Reset TRD related track information
1284 fTRDNchamberdEdx = 0;
1285 fTRDNclusterdEdx = 0;
1287 for (Int_t i=0;i<kTRDnPlanes;i++) {
1290 for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0;
1295 delete[] fTRDslices;
1300 // Reset TOF related track information
1304 fTOFCalChannel = -1;
1305 fTOFsignalToT = 99999;
1306 fTOFsignalRaw = 99999;
1311 for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
1312 for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
1314 // Reset HMPID related track information
1319 for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
1326 fCaloIndex = kEMCALNoMatch;
1328 // reset global track chi2
1331 fVertexID = -2; // an orphan track
1333 delete fFriendTrack; fFriendTrack = 0;
1336 //_______________________________________________________________________
1337 Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const
1339 // Returns the particle most probable id
1341 const Double32_t *prob = 0;
1342 if (tpcOnly) { // check if TPCpid is valid
1344 for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1345 if (i == AliPID::kSPECIES-1) prob = 0; // not valid, try with combined pid
1347 if (!prob) { // either requested TPCpid is not valid or comb.pid is requested
1349 for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1350 if (i == AliPID::kSPECIES-1) return AliPID::kPion; // If all the probabilities are equal, return the pion mass
1355 for (i=0; i<AliPID::kSPECIES; i++) if (prob[i]>max) {k=i; max=prob[i];}
1357 if (k==0) { // dE/dx "crossing points" in the TPC
1359 if ((p>0.38)&&(p<0.48))
1360 if (prob[0]<prob[3]*10.) return AliPID::kKaon;
1361 if ((p>0.75)&&(p<0.85))
1362 if (prob[0]<prob[4]*10.) return AliPID::kProton;
1363 return AliPID::kElectron;
1365 if (k==1) return AliPID::kMuon;
1366 if (k==2||k==-1) return AliPID::kPion;
1367 if (k==3) return AliPID::kKaon;
1368 if (k==4) return AliPID::kProton;
1369 AliWarning("Undefined PID !");
1370 return AliPID::kPion;
1373 //_______________________________________________________________________
1374 Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b, Bool_t pidTPConly) const
1376 // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
1377 const double kSpacing = 25e3; // min interbanch spacing
1378 const double kShift = 0;
1379 Int_t bcid = kTOFBCNA; // defualt one
1380 if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
1382 double tdif = fTOFsignal;
1383 Double_t times[AliPID::kSPECIESC];
1384 GetIntegratedTimes(times);
1385 if (IsOn(kTIME)) { // integrated time info is there
1386 int pid = GetPID(pidTPConly);
1390 else { // assume integrated time info from TOF radius and momentum
1391 const double kRTOF = 385.;
1392 const double kCSpeed = 3.e-2; // cm/ps
1394 if (p<0.01) return bcid;
1395 double m = GetMass(pidTPConly);
1396 double curv = GetC(b);
1397 double path = TMath::Abs(curv)>kAlmost0 ? // account for curvature
1398 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+GetTgl()*GetTgl()) : kRTOF;
1399 tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
1401 bcid = TMath::Nint((tdif - kShift)/kSpacing);
1405 //______________________________________________________________________________
1406 Double_t AliESDtrack::M() const
1408 // Returns the assumed mass
1409 // (the pion mass, if the particle can't be identified properly).
1410 static Bool_t printerr=kTRUE;
1412 AliWarning("WARNING !!! ... THIS WILL BE PRINTED JUST ONCE !!!");
1414 AliWarning("This is the ESD mass. Use it with care !");
1419 //______________________________________________________________________________
1420 Double_t AliESDtrack::E() const
1422 // Returns the energy of the particle given its assumed mass.
1423 // Assumes the pion mass if the particle can't be identified properly.
1427 return TMath::Sqrt(p*p + m*m);
1430 //______________________________________________________________________________
1431 Double_t AliESDtrack::Y() const
1433 // Returns the rapidity of a particle given its assumed mass.
1434 // Assumes the pion mass if the particle can't be identified properly.
1438 if (e != TMath::Abs(pz)) { // energy was not equal to pz
1439 return 0.5*TMath::Log((e+pz)/(e-pz));
1440 } else { // energy was equal to pz
1445 //_______________________________________________________________________
1446 Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
1448 // This function updates track's running parameters
1453 fLabel=t->GetLabel();
1455 if (t->IsStartedTimeIntegral()) {
1457 Double_t times[AliPID::kSPECIESC];t->GetIntegratedTimes(times); SetIntegratedTimes(times);
1458 SetIntegratedLength(t->GetIntegratedLength());
1461 Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1463 if (flags==kITSout) fFriendTrack->SetITSOut(*t);
1464 if (flags==kTPCout) fFriendTrack->SetTPCOut(*t);
1465 if (flags==kTRDrefit) fFriendTrack->SetTRDIn(*t);
1471 fITSchi2Std[0] = t->GetChi2();
1474 fITSchi2Std[1] = t->GetChi2();
1477 fITSchi2Std[2] = t->GetChi2();
1479 fITSncls=t->GetNumberOfClusters();
1481 Int_t* indexITS = new Int_t[AliESDfriendTrack::kMaxITScluster];
1482 for (Int_t i=0;i<AliESDfriendTrack::kMaxITScluster;i++) {
1483 indexITS[i]=t->GetClusterIndex(i);
1486 Int_t l=(indexITS[i] & 0xf0000000) >> 28;
1487 SETBIT(fITSClusterMap,l);
1490 fFriendTrack->SetITSIndices(indexITS,AliESDfriendTrack::kMaxITScluster);
1494 fITSchi2=t->GetChi2();
1495 fITSsignal=t->GetPIDsignal();
1496 fITSLabel = t->GetLabel();
1497 // keep in fOp the parameters outside ITS for ITS stand-alone tracks
1498 if (flags==kITSout) {
1499 if (!fOp) fOp=new AliExternalTrackParam(*t);
1501 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1506 case kTPCin: case kTPCrefit:
1508 fTPCLabel = t->GetLabel();
1509 if (flags==kTPCin) {
1510 fTPCInner=new AliExternalTrackParam(*t);
1511 fTPCnclsIter1=t->GetNumberOfClusters();
1512 fTPCchi2Iter1=t->GetChi2();
1514 if (!fIp) fIp=new AliExternalTrackParam(*t);
1516 fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1518 // Intentionally no break statement; need to set general TPC variables as well
1521 if (flags & kTPCout){
1522 if (!fOp) fOp=new AliExternalTrackParam(*t);
1524 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1526 fTPCncls=t->GetNumberOfClusters();
1527 fTPCchi2=t->GetChi2();
1529 if (fFriendTrack) { // Copy cluster indices
1530 Int_t* indexTPC = new Int_t[AliESDfriendTrack::kMaxTPCcluster];
1531 for (Int_t i=0;i<AliESDfriendTrack::kMaxTPCcluster;i++)
1532 indexTPC[i]=t->GetClusterIndex(i);
1533 fFriendTrack->SetTPCIndices(indexTPC,AliESDfriendTrack::kMaxTPCcluster);
1536 fTPCsignal=t->GetPIDsignal();
1540 case kTRDin: case kTRDrefit:
1544 fTRDLabel = t->GetLabel();
1545 fTRDchi2 = t->GetChi2();
1546 fTRDncls = t->GetNumberOfClusters();
1548 Int_t* indexTRD = new Int_t[AliESDfriendTrack::kMaxTRDcluster];
1549 for (Int_t i=0;i<AliESDfriendTrack::kMaxTRDcluster;i++) indexTRD[i]=-2;
1550 for (Int_t i=0;i<6;i++) indexTRD[i]=t->GetTrackletIndex(i);
1551 fFriendTrack->SetTRDIndices(indexTRD,AliESDfriendTrack::kMaxTRDcluster);
1555 //commented out by Xianguo
1556 //fTRDsignal=t->GetPIDsignal();
1560 if (!fOp) fOp=new AliExternalTrackParam(*t);
1562 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1563 fTRDncls0 = t->GetNumberOfClusters();
1572 if (!fHMPIDp) fHMPIDp=new AliExternalTrackParam(*t);
1574 fHMPIDp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1577 AliError("Wrong flag !");
1584 //_______________________________________________________________________
1585 void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const {
1586 //---------------------------------------------------------------------
1587 // This function returns external representation of the track parameters
1588 //---------------------------------------------------------------------
1590 for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i];
1593 //_______________________________________________________________________
1594 void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const {
1595 //---------------------------------------------------------------------
1596 // This function returns external representation of the cov. matrix
1597 //---------------------------------------------------------------------
1598 for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i];
1601 //_______________________________________________________________________
1602 Bool_t AliESDtrack::GetConstrainedExternalParameters
1603 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1604 //---------------------------------------------------------------------
1605 // This function returns the constrained external track parameters
1606 //---------------------------------------------------------------------
1607 if (!fCp) return kFALSE;
1608 alpha=fCp->GetAlpha();
1610 for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i];
1614 //_______________________________________________________________________
1616 AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const {
1617 //---------------------------------------------------------------------
1618 // This function returns the constrained external cov. matrix
1619 //---------------------------------------------------------------------
1620 if (!fCp) return kFALSE;
1621 for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i];
1626 AliESDtrack::GetInnerExternalParameters
1627 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1628 //---------------------------------------------------------------------
1629 // This function returns external representation of the track parameters
1630 // at the inner layer of TPC
1631 //---------------------------------------------------------------------
1632 if (!fIp) return kFALSE;
1633 alpha=fIp->GetAlpha();
1635 for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i];
1640 AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const {
1641 //---------------------------------------------------------------------
1642 // This function returns external representation of the cov. matrix
1643 // at the inner layer of TPC
1644 //---------------------------------------------------------------------
1645 if (!fIp) return kFALSE;
1646 for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i];
1651 AliESDtrack::SetOuterParam(const AliExternalTrackParam *p, ULong_t flags) {
1653 // This is a direct setter for the outer track parameters
1656 if (fOp) delete fOp;
1657 fOp=new AliExternalTrackParam(*p);
1661 AliESDtrack::SetOuterHmpParam(const AliExternalTrackParam *p, ULong_t flags) {
1663 // This is a direct setter for the outer track parameters
1666 if (fHMPIDp) delete fHMPIDp;
1667 fHMPIDp=new AliExternalTrackParam(*p);
1671 AliESDtrack::GetOuterExternalParameters
1672 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1673 //---------------------------------------------------------------------
1674 // This function returns external representation of the track parameters
1675 // at the inner layer of TRD
1676 //---------------------------------------------------------------------
1677 if (!fOp) return kFALSE;
1678 alpha=fOp->GetAlpha();
1680 for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i];
1685 AliESDtrack::GetOuterHmpExternalParameters
1686 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1687 //---------------------------------------------------------------------
1688 // This function returns external representation of the track parameters
1689 // at the inner layer of TRD
1690 //---------------------------------------------------------------------
1691 if (!fHMPIDp) return kFALSE;
1692 alpha=fHMPIDp->GetAlpha();
1694 for (Int_t i=0; i<5; i++) p[i]=fHMPIDp->GetParameter()[i];
1699 AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const {
1700 //---------------------------------------------------------------------
1701 // This function returns external representation of the cov. matrix
1702 // at the inner layer of TRD
1703 //---------------------------------------------------------------------
1704 if (!fOp) return kFALSE;
1705 for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i];
1710 AliESDtrack::GetOuterHmpExternalCovariance(Double_t cov[15]) const {
1711 //---------------------------------------------------------------------
1712 // This function returns external representation of the cov. matrix
1713 // at the inner layer of TRD
1714 //---------------------------------------------------------------------
1715 if (!fHMPIDp) return kFALSE;
1716 for (Int_t i=0; i<15; i++) cov[i]=fHMPIDp->GetCovariance()[i];
1720 Int_t AliESDtrack::GetNcls(Int_t idet) const
1722 // Get number of clusters by subdetector index
1736 if (fTOFindex != -1)
1742 if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1743 if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1754 Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
1756 // Get cluster index array by subdetector index
1761 ncls = GetITSclusters(idx);
1764 ncls = GetTPCclusters(idx);
1767 ncls = GetTRDclusters(idx);
1770 if (fTOFindex != -1) {
1778 if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1779 if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1780 idx[0] = GetHMPIDcluIdx();
1793 //_______________________________________________________________________
1794 void AliESDtrack::GetIntegratedTimes(Double_t *times) const {
1797 if(fNtofClusters>0 && GetESDEvent()){
1798 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
1799 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
1801 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
1802 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
1804 if(fNtofClusters>0 && index > -1){
1805 for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=tofcl->GetIntegratedTime(i,index);
1809 else if(fNtofClusters>0)
1810 AliInfo("No AliESDEvent available here!\n");
1812 // Returns the array with integrated times for each particle hypothesis
1814 for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=fTrackTime[i];
1816 for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=0.0;
1818 //_______________________________________________________________________
1819 Double_t AliESDtrack::GetIntegratedLength() const{
1821 if(fNtofClusters>0 && GetESDEvent()){
1822 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
1823 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
1825 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
1826 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
1829 if(fNtofClusters>0 && index > -1)
1830 return tofcl->GetLength(index);
1832 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
1834 return fTrackLength;
1837 //_______________________________________________________________________
1838 void AliESDtrack::SetIntegratedTimes(const Double_t *times) {
1839 // Sets the array with integrated times for each particle hypotesis
1841 fTrackTime = new Double32_t[AliPID::kSPECIESC];
1842 for (Int_t i=0; i<AliPID::kSPECIESC; i++) fTrackTime[i]=times[i];
1845 //_______________________________________________________________________
1846 void AliESDtrack::SetITSpid(const Double_t *p) {
1847 // Sets values for the probability of each particle type (in ITS)
1848 SetPIDValues(fITSr,p,AliPID::kSPECIES);
1849 SetStatus(AliESDtrack::kITSpid);
1852 //_______________________________________________________________________
1853 void AliESDtrack::GetITSpid(Double_t *p) const {
1854 // Gets the probability of each particle type (in ITS)
1855 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fITSr[i];
1858 //_______________________________________________________________________
1859 Char_t AliESDtrack::GetITSclusters(Int_t *idx) const {
1860 //---------------------------------------------------------------------
1861 // This function returns indices of the assgined ITS clusters
1862 //---------------------------------------------------------------------
1863 if (idx && fFriendTrack) {
1864 Int_t *index=fFriendTrack->GetITSindices();
1865 for (Int_t i=0; i<AliESDfriendTrack::kMaxITScluster; i++) {
1866 if ( (i>=fITSncls) && (i<6) ) idx[i]=-1;
1878 //_______________________________________________________________________
1879 Bool_t AliESDtrack::GetITSModuleIndexInfo(Int_t ilayer,Int_t &idet,Int_t &status,
1880 Float_t &xloc,Float_t &zloc) const {
1881 //----------------------------------------------------------------------
1882 // This function encodes in the module number also the status of cluster association
1883 // "status" can have the following values:
1884 // 1 "found" (cluster is associated),
1885 // 2 "dead" (module is dead from OCDB),
1886 // 3 "skipped" (module or layer forced to be skipped),
1887 // 4 "outinz" (track out of z acceptance),
1888 // 5 "nocls" (no clusters in the road),
1889 // 6 "norefit" (cluster rejected during refit),
1890 // 7 "deadzspd" (holes in z in SPD)
1891 // Also given are the coordinates of the crossing point of track and module
1892 // (in the local module ref. system)
1893 // WARNING: THIS METHOD HAS TO BE SYNCHRONIZED WITH AliITStrackV2::GetModuleIndexInfo()!
1894 //----------------------------------------------------------------------
1896 if(fITSModule[ilayer]==-1) {
1899 xloc=-99.; zloc=-99.;
1903 Int_t module = fITSModule[ilayer];
1905 idet = Int_t(module/1000000);
1907 module -= idet*1000000;
1909 status = Int_t(module/100000);
1911 module -= status*100000;
1913 Int_t signs = Int_t(module/10000);
1915 module-=signs*10000;
1917 Int_t xInt = Int_t(module/100);
1920 Int_t zInt = module;
1922 if(signs==1) { xInt*=1; zInt*=1; }
1923 if(signs==2) { xInt*=1; zInt*=-1; }
1924 if(signs==3) { xInt*=-1; zInt*=1; }
1925 if(signs==4) { xInt*=-1; zInt*=-1; }
1927 xloc = 0.1*(Float_t)xInt;
1928 zloc = 0.1*(Float_t)zInt;
1930 if(status==4) idet = -1;
1935 //_______________________________________________________________________
1936 UShort_t AliESDtrack::GetTPCclusters(Int_t *idx) const {
1937 //---------------------------------------------------------------------
1938 // This function returns indices of the assgined ITS clusters
1939 //---------------------------------------------------------------------
1940 if (idx && fFriendTrack) {
1941 Int_t *index=fFriendTrack->GetTPCindices();
1944 for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=index[i];
1947 for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=-2;
1953 //_______________________________________________________________________
1954 Float_t AliESDtrack::GetTPCCrossedRows() const
1956 // This function calls GetTPCClusterInfo with some default parameters which are used in the track selection and caches the outcome
1957 // because GetTPCClusterInfo is quite time-consuming
1959 if (fCacheNCrossedRows > -1)
1960 return fCacheNCrossedRows;
1962 fCacheNCrossedRows = GetTPCClusterInfo(2, 1);
1963 return fCacheNCrossedRows;
1966 //_______________________________________________________________________
1967 Float_t AliESDtrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
1970 // TPC cluster information
1971 // type 0: get fraction of found/findable clusters with neighbourhood definition
1972 // 1: findable clusters with neighbourhood definition
1973 // 2: found clusters
1975 // 0 - all cluster used
1976 // 1 - clusters used for the kalman update
1977 // definition of findable clusters:
1978 // a cluster is defined as findable if there is another cluster
1979 // within +- nNeighbours pad rows. The idea is to overcome threshold
1980 // effects with a very simple algorithm.
1986 Int_t last=-nNeighbours;
1987 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
1989 Int_t upperBound=clusterMap.GetNbits();
1990 if (upperBound>row1) upperBound=row1;
1991 for (Int_t i=row0; i<upperBound; ++i){
1992 //look to current row
1993 if (clusterMap[i]) {
1999 //look to nNeighbours before
2000 if ((i-last)<=nNeighbours) {
2004 //look to nNeighbours after
2005 for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
2012 if (type==2) return found;
2013 if (type==1) return findable;
2018 fraction=(Float_t)found/(Float_t)findable;
2023 return 0; // undefined type - default value
2026 //_______________________________________________________________________
2027 Float_t AliESDtrack::GetTPCClusterDensity(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
2030 // TPC cluster density - only rows where signal before and after given row are used
2031 // - slower function
2032 // type 0: get fraction of found/findable clusters with neighbourhood definition
2033 // 1: findable clusters with neighbourhood definition
2034 // 2: found clusters
2036 // 0 - all cluster used
2037 // 1 - clusters used for the kalman update
2038 // definition of findable clusters:
2039 // a cluster is defined as findable if there is another cluster
2040 // within +- nNeighbours pad rows. The idea is to overcome threshold
2041 // effects with a very simple algorithm.
2045 // Int_t last=-nNeighbours;
2046 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
2047 Int_t upperBound=clusterMap.GetNbits();
2048 if (upperBound>row1) upperBound=row1;
2049 for (Int_t i=row0; i<upperBound; ++i){
2051 Bool_t isDown=kFALSE;
2052 for (Int_t idelta=1; idelta<=nNeighbours; idelta++){
2053 if (i-idelta>=0 && clusterMap[i-idelta]) isDown=kTRUE;
2054 if (i+idelta<upperBound && clusterMap[i+idelta]) isUp=kTRUE;
2058 if (clusterMap[i]) ++found;
2061 if (type==2) return found;
2062 if (type==1) return findable;
2067 fraction=(Float_t)found/(Float_t)findable;
2072 return 0; // undefined type - default value
2078 //_______________________________________________________________________
2079 Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
2081 // GetDensity of the clusters on given region between row0 and row1
2082 // Dead zone effect takin into acoount
2084 if (!fFriendTrack) return 0.0;
2088 Int_t *index=fFriendTrack->GetTPCindices();
2089 for (Int_t i=row0;i<=row1;i++){
2090 Int_t idx = index[i];
2091 if (idx!=-1) good++; // track outside of dead zone
2094 Float_t density=0.5;
2095 if (good>TMath::Max((row1-row0)*0.5,0.0)) density = Float_t(found)/Float_t(good);
2099 //_______________________________________________________________________
2100 void AliESDtrack::SetTPCpid(const Double_t *p) {
2101 // Sets values for the probability of each particle type (in TPC)
2102 SetPIDValues(fTPCr,p,AliPID::kSPECIES);
2103 SetStatus(AliESDtrack::kTPCpid);
2106 //_______________________________________________________________________
2107 void AliESDtrack::GetTPCpid(Double_t *p) const {
2108 // Gets the probability of each particle type (in TPC)
2109 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTPCr[i];
2112 //_______________________________________________________________________
2113 UChar_t AliESDtrack::GetTRDclusters(Int_t *idx) const {
2114 //---------------------------------------------------------------------
2115 // This function returns indices of the assgined TRD clusters
2116 //---------------------------------------------------------------------
2117 if (idx && fFriendTrack) {
2118 Int_t *index=fFriendTrack->GetTRDindices();
2121 for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=index[i];
2124 for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=-2;
2130 //_______________________________________________________________________
2131 UChar_t AliESDtrack::GetTRDtracklets(Int_t *idx) const {
2133 // This function returns the number of TRD tracklets used in tracking
2134 // and it fills the indices of these tracklets in the array "idx" as they
2135 // are registered in the TRD track list.
2138 // 1. The idx array has to be allocated with a size >= AliESDtrack::kTRDnPlanes
2139 // 2. The idx array store not only the index but also the layer of the tracklet.
2140 // Therefore tracks with TRD gaps contain default values for indices [-1]
2142 if (!fFriendTrack) return 0;
2143 if (!idx) return GetTRDntracklets();
2144 Int_t *index=fFriendTrack->GetTRDindices();
2146 for (Int_t i=0; i<kTRDnPlanes; i++){
2148 if(index[i]>=0) n++;
2156 //_______________________________________________________________________
2157 void AliESDtrack::SetTRDpid(const Double_t *p) {
2158 // Sets values for the probability of each particle type (in TRD)
2159 SetPIDValues(fTRDr,p,AliPID::kSPECIES);
2160 SetStatus(AliESDtrack::kTRDpid);
2163 //_______________________________________________________________________
2164 void AliESDtrack::GetTRDpid(Double_t *p) const {
2165 // Gets the probability of each particle type (in TRD)
2166 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTRDr[i];
2169 //_______________________________________________________________________
2170 void AliESDtrack::SetTRDpid(Int_t iSpecies, Float_t p)
2172 // Sets the probability of particle type iSpecies to p (in TRD)
2173 fTRDr[iSpecies] = p;
2176 Double_t AliESDtrack::GetTRDpid(Int_t iSpecies) const
2178 // Returns the probability of particle type iSpecies (in TRD)
2179 return fTRDr[iSpecies];
2182 //____________________________________________________
2183 Int_t AliESDtrack::GetNumberOfTRDslices() const
2185 // built in backward compatibility
2186 Int_t idx = fTRDnSlices - (kTRDnPlanes<<1);
2187 return idx<18 ? fTRDnSlices/kTRDnPlanes : idx/kTRDnPlanes;
2190 //____________________________________________________
2191 Double_t AliESDtrack::GetTRDmomentum(Int_t plane, Double_t *sp) const
2193 //Returns momentum estimation and optional its error (sp)
2194 // in TRD layer "plane".
2197 AliDebug(2, "No TRD info allocated for this track.");
2200 if ((plane<0) || (plane>=kTRDnPlanes)) {
2201 AliWarning(Form("Request for TRD plane[%d] outside range.", plane));
2205 Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2206 // Protection for backward compatibility
2207 if(idx<(GetNumberOfTRDslices()*kTRDnPlanes)) return -1.;
2209 if(sp) (*sp) = fTRDslices[idx+kTRDnPlanes];
2210 return fTRDslices[idx];
2213 //____________________________________________________
2214 Double_t AliESDtrack::GetTRDslice(Int_t plane, Int_t slice) const {
2215 //Gets the charge from the slice of the plane
2218 //AliError("No TRD slices allocated for this track !");
2221 if ((plane<0) || (plane>=kTRDnPlanes)) {
2222 AliError("Info for TRD plane not available !");
2225 Int_t ns=GetNumberOfTRDslices();
2226 if ((slice<-1) || (slice>=ns)) {
2227 //AliError("Wrong TRD slice !");
2231 if(slice>=0) return fTRDslices[plane*ns + slice];
2233 // return average of the dEdx measurements
2234 Double_t q=0.; Double32_t *s = &fTRDslices[plane*ns];
2235 for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
2239 //____________________________________________________
2240 void AliESDtrack::SetNumberOfTRDslices(Int_t n) {
2241 //Sets the number of slices used for PID
2242 if (fTRDnSlices) return;
2245 fTRDslices=new Double32_t[fTRDnSlices];
2247 // set-up correctly the allocated memory
2248 memset(fTRDslices, 0, n*sizeof(Double32_t));
2249 for (Int_t i=GetNumberOfTRDslices(); i--;) fTRDslices[i]=-1.;
2252 //____________________________________________________
2253 void AliESDtrack::SetTRDslice(Double_t q, Int_t plane, Int_t slice) {
2254 //Sets the charge q in the slice of the plane
2256 AliError("No TRD slices allocated for this track !");
2259 if ((plane<0) || (plane>=kTRDnPlanes)) {
2260 AliError("Info for TRD plane not allocated !");
2263 Int_t ns=GetNumberOfTRDslices();
2264 if ((slice<0) || (slice>=ns)) {
2265 AliError(Form("Wrong TRD slice %d/%d, NSlices=%d",plane,slice,ns));
2268 Int_t n=plane*ns + slice;
2273 //____________________________________________________
2274 void AliESDtrack::SetTRDmomentum(Double_t p, Int_t plane, Double_t *sp)
2277 AliError("No TRD slices allocated for this track !");
2280 if ((plane<0) || (plane>=kTRDnPlanes)) {
2281 AliError("Info for TRD plane not allocated !");
2285 Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2286 // Protection for backward compatibility
2287 if(idx<GetNumberOfTRDslices()*kTRDnPlanes) return;
2289 if(sp) fTRDslices[idx+kTRDnPlanes] = (*sp);
2290 fTRDslices[idx] = p;
2294 //_______________________________________________________________________
2295 void AliESDtrack::SetTOFpid(const Double_t *p) {
2296 // Sets the probability of each particle type (in TOF)
2297 SetPIDValues(fTOFr,p,AliPID::kSPECIES);
2298 SetStatus(AliESDtrack::kTOFpid);
2301 //_______________________________________________________________________
2302 void AliESDtrack::SetTOFLabel(const Int_t *p) {
2304 if(!fTOFLabel) fTOFLabel = new Int_t[3];
2305 for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
2308 //_______________________________________________________________________
2309 void AliESDtrack::GetTOFpid(Double_t *p) const {
2310 // Gets probabilities of each particle type (in TOF)
2311 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTOFr[i];
2314 //_______________________________________________________________________
2315 void AliESDtrack::GetTOFLabel(Int_t *p) const {
2317 if(fNtofClusters>0){
2318 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2319 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2321 for (Int_t i=0; i<3; i++) p[i]=tofcl->GetLabel(i);
2325 for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
2329 //_______________________________________________________________________
2330 void AliESDtrack::GetTOFInfo(Float_t *info) const {
2332 for (Int_t i=0; i<10; i++) info[i]=fTOFInfo[i];
2335 //_______________________________________________________________________
2336 void AliESDtrack::SetTOFInfo(Float_t*info) {
2338 for (Int_t i=0; i<10; i++) fTOFInfo[i]=info[i];
2343 //_______________________________________________________________________
2344 void AliESDtrack::SetHMPIDpid(const Double_t *p) {
2345 // Sets the probability of each particle type (in HMPID)
2346 SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
2347 SetStatus(AliESDtrack::kHMPIDpid);
2350 //_______________________________________________________________________
2351 void AliESDtrack::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo){
2352 if(fTPCdEdxInfo) delete fTPCdEdxInfo;
2353 fTPCdEdxInfo = dEdxInfo;
2356 //_______________________________________________________________________
2357 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
2358 // Gets probabilities of each particle type (in HMPID)
2359 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fHMPIDr[i];
2364 //_______________________________________________________________________
2365 void AliESDtrack::SetESDpid(const Double_t *p) {
2366 // Sets the probability of each particle type for the ESD track
2367 SetPIDValues(fR,p,AliPID::kSPECIES);
2368 SetStatus(AliESDtrack::kESDpid);
2371 //_______________________________________________________________________
2372 void AliESDtrack::GetESDpid(Double_t *p) const {
2373 // Gets probability of each particle type for the ESD track
2374 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fR[i];
2377 //_______________________________________________________________________
2378 Bool_t AliESDtrack::RelateToVertexTPC(const AliESDVertex *vtx,
2379 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2381 // Try to relate the TPC-only track parameters to the vertex "vtx",
2382 // if the (rough) transverse impact parameter is not bigger then "maxd".
2383 // Magnetic field is "b" (kG).
2385 // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2386 // b) The impact parameters and their covariance matrix are calculated.
2387 // c) An attempt to constrain the TPC-only params to the vertex is done.
2388 // The constrained params are returned via "cParam".
2390 // In the case of success, the returned value is kTRUE
2391 // otherwise, it's kFALSE)
2394 if (!fTPCInner) return kFALSE;
2395 if (!vtx) return kFALSE;
2397 Double_t dz[2],cov[3];
2398 if (!fTPCInner->PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2406 Double_t covar[6]; vtx->GetCovMatrix(covar);
2407 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2408 Double_t c[3]={covar[2],0.,covar[5]};
2410 Double_t chi2=GetPredictedChi2(p,c);
2411 if (chi2>kVeryBig) return kFALSE;
2415 if (!cParam) return kTRUE;
2417 *cParam = *fTPCInner;
2418 if (!cParam->Update(p,c)) return kFALSE;
2423 //_______________________________________________________________________
2424 Bool_t AliESDtrack::RelateToVertexTPCBxByBz(const AliESDVertex *vtx,
2425 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2427 // Try to relate the TPC-only track parameters to the vertex "vtx",
2428 // if the (rough) transverse impact parameter is not bigger then "maxd".
2430 // All three components of the magnetic field ,"b[3]" (kG),
2431 // are taken into account.
2433 // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2434 // b) The impact parameters and their covariance matrix are calculated.
2435 // c) An attempt to constrain the TPC-only params to the vertex is done.
2436 // The constrained params are returned via "cParam".
2438 // In the case of success, the returned value is kTRUE
2439 // otherwise, it's kFALSE)
2442 if (!fTPCInner) return kFALSE;
2443 if (!vtx) return kFALSE;
2445 Double_t dz[2],cov[3];
2446 if (!fTPCInner->PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2454 Double_t covar[6]; vtx->GetCovMatrix(covar);
2455 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2456 Double_t c[3]={covar[2],0.,covar[5]};
2458 Double_t chi2=GetPredictedChi2(p,c);
2459 if (chi2>kVeryBig) return kFALSE;
2463 if (!cParam) return kTRUE;
2465 *cParam = *fTPCInner;
2466 if (!cParam->Update(p,c)) return kFALSE;
2471 //_______________________________________________________________________
2472 Bool_t AliESDtrack::RelateToVertex(const AliESDVertex *vtx,
2473 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2475 // Try to relate this track to the vertex "vtx",
2476 // if the (rough) transverse impact parameter is not bigger then "maxd".
2477 // Magnetic field is "b" (kG).
2479 // a) The track gets extapolated to the DCA to the vertex.
2480 // b) The impact parameters and their covariance matrix are calculated.
2481 // c) An attempt to constrain this track to the vertex is done.
2482 // The constrained params are returned via "cParam".
2484 // In the case of success, the returned value is kTRUE
2485 // (otherwise, it's kFALSE)
2488 if (!vtx) return kFALSE;
2490 Double_t dz[2],cov[3];
2491 if (!PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2499 Double_t covar[6]; vtx->GetCovMatrix(covar);
2500 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2501 Double_t c[3]={covar[2],0.,covar[5]};
2503 Double_t chi2=GetPredictedChi2(p,c);
2504 if (chi2>kVeryBig) return kFALSE;
2509 //--- Could now these lines be removed ? ---
2511 fCp=new AliExternalTrackParam(*this);
2513 if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2514 //----------------------------------------
2516 fVertexID = vtx->GetID();
2518 if (!cParam) return kTRUE;
2521 if (!cParam->Update(p,c)) return kFALSE;
2526 //_______________________________________________________________________
2527 Bool_t AliESDtrack::RelateToVertexBxByBz(const AliESDVertex *vtx,
2528 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2530 // Try to relate this track to the vertex "vtx",
2531 // if the (rough) transverse impact parameter is not bigger then "maxd".
2532 // Magnetic field is "b" (kG).
2534 // a) The track gets extapolated to the DCA to the vertex.
2535 // b) The impact parameters and their covariance matrix are calculated.
2536 // c) An attempt to constrain this track to the vertex is done.
2537 // The constrained params are returned via "cParam".
2539 // In the case of success, the returned value is kTRUE
2540 // (otherwise, it's kFALSE)
2543 if (!vtx) return kFALSE;
2545 Double_t dz[2],cov[3];
2546 if (!PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2554 Double_t covar[6]; vtx->GetCovMatrix(covar);
2555 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2556 Double_t c[3]={covar[2],0.,covar[5]};
2558 Double_t chi2=GetPredictedChi2(p,c);
2559 if (chi2>kVeryBig) return kFALSE;
2564 //--- Could now these lines be removed ? ---
2566 fCp=new AliExternalTrackParam(*this);
2568 if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2569 //----------------------------------------
2571 fVertexID = vtx->GetID();
2573 if (!cParam) return kTRUE;
2576 if (!cParam->Update(p,c)) return kFALSE;
2581 //_______________________________________________________________________
2582 void AliESDtrack::Print(Option_t *) const {
2583 // Prints info on the track
2584 AliExternalTrackParam::Print();
2585 printf("ESD track info\n") ;
2586 Double_t p[AliPID::kSPECIES] ;
2588 if( IsOn(kITSpid) ){
2589 printf("From ITS: ") ;
2591 for(index = 0 ; index < AliPID::kSPECIES; index++)
2592 printf("%f, ", p[index]) ;
2593 printf("\n signal = %f\n", GetITSsignal()) ;
2595 if( IsOn(kTPCpid) ){
2596 printf("From TPC: ") ;
2598 for(index = 0 ; index < AliPID::kSPECIES; index++)
2599 printf("%f, ", p[index]) ;
2600 printf("\n signal = %f\n", GetTPCsignal()) ;
2602 if( IsOn(kTRDpid) ){
2603 printf("From TRD: ") ;
2605 for(index = 0 ; index < AliPID::kSPECIES; index++)
2606 printf("%f, ", p[index]) ;
2607 printf("\n signal = %f\n", GetTRDsignal()) ;
2608 printf("\n NchamberdEdx = %d\n", GetTRDNchamberdEdx()) ;
2609 printf("\n NclusterdEdx = %d\n", GetTRDNclusterdEdx()) ;
2611 if( IsOn(kTOFpid) ){
2612 printf("From TOF: ") ;
2614 for(index = 0 ; index < AliPID::kSPECIES; index++)
2615 printf("%f, ", p[index]) ;
2616 printf("\n signal = %f\n", GetTOFsignal()) ;
2618 if( IsOn(kHMPIDpid) ){
2619 printf("From HMPID: ") ;
2621 for(index = 0 ; index < AliPID::kSPECIES; index++)
2622 printf("%f, ", p[index]) ;
2623 printf("\n signal = %f\n", GetHMPIDsignal()) ;
2629 // Draw functionality
2630 // Origin: Marian Ivanov, Marian.Ivanov@cern.ch
2632 void AliESDtrack::FillPolymarker(TPolyMarker3D *pol, Float_t magF, Float_t minR, Float_t maxR, Float_t stepR){
2634 // Fill points in the polymarker
2637 arrayRef.AddLast(new AliExternalTrackParam(*this));
2638 if (fIp) arrayRef.AddLast(new AliExternalTrackParam(*fIp));
2639 if (fOp) arrayRef.AddLast(new AliExternalTrackParam(*fOp));
2640 if (fHMPIDp) arrayRef.AddLast(new AliExternalTrackParam(*fHMPIDp));
2642 Double_t mpos[3]={0,0,0};
2643 Int_t entries=arrayRef.GetEntries();
2644 for (Int_t i=0;i<entries;i++){
2646 ((AliExternalTrackParam*)arrayRef.At(i))->GetXYZ(pos);
2647 mpos[0]+=pos[0]/entries;
2648 mpos[1]+=pos[1]/entries;
2649 mpos[2]+=pos[2]/entries;
2651 // Rotate to the mean position
2653 Float_t fi= TMath::ATan2(mpos[1],mpos[0]);
2654 for (Int_t i=0;i<entries;i++){
2655 Bool_t res = ((AliExternalTrackParam*)arrayRef.At(i))->Rotate(fi);
2656 if (!res) delete arrayRef.RemoveAt(i);
2659 for (Double_t r=minR; r<maxR; r+=stepR){
2661 Double_t mlpos[3]={0,0,0};
2662 for (Int_t i=0;i<entries;i++){
2663 Double_t point[3]={0,0,0};
2664 AliExternalTrackParam *param = ((AliExternalTrackParam*)arrayRef.At(i));
2665 if (!param) continue;
2666 if (param->GetXYZAt(r,magF,point)){
2667 Double_t weight = 1./(10.+(r-param->GetX())*(r-param->GetX()));
2669 mlpos[0]+=point[0]*weight;
2670 mlpos[1]+=point[1]*weight;
2671 mlpos[2]+=point[2]*weight;
2678 pol->SetPoint(counter,mlpos[0],mlpos[1], mlpos[2]);
2679 // printf("xyz\t%f\t%f\t%f\n",mlpos[0], mlpos[1],mlpos[2]);
2685 //_______________________________________________________________________
2686 void AliESDtrack::SetITSdEdxSamples(const Double_t s[4]) {
2688 // Store the dE/dx samples measured by the two SSD and two SDD layers.
2689 // These samples are corrected for the track segment length.
2691 for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
2694 //_______________________________________________________________________
2695 void AliESDtrack::GetITSdEdxSamples(Double_t s[4]) const {
2697 // Get the dE/dx samples measured by the two SSD and two SDD layers.
2698 // These samples are corrected for the track segment length.
2700 for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
2704 UShort_t AliESDtrack::GetTPCnclsS(Int_t i0,Int_t i1) const{
2706 // get number of shared TPC clusters
2708 return fTPCSharedMap.CountBits(i0)-fTPCSharedMap.CountBits(i1);
2711 UShort_t AliESDtrack::GetTPCncls(Int_t i0,Int_t i1) const{
2713 // get number of TPC clusters
2715 return fTPCClusterMap.CountBits(i0)-fTPCClusterMap.CountBits(i1);
2718 //____________________________________________________________________
2719 Double_t AliESDtrack::GetChi2TPCConstrainedVsGlobal(const AliESDVertex* vtx) const
2721 // Calculates the chi2 between the TPC track (TPCinner) constrained to the primary vertex and the global track
2723 // Returns -1 in case the calculation failed
2725 // Value is cached as a non-persistent member.
2727 // Code adapted from original code by GSI group (Jacek, Marian, Michael)
2729 // cache, ignoring that a different vertex might be passed
2730 if (fCacheChi2TPCConstrainedVsGlobalVertex == vtx)
2731 return fCacheChi2TPCConstrainedVsGlobal;
2733 fCacheChi2TPCConstrainedVsGlobal = -1;
2734 fCacheChi2TPCConstrainedVsGlobalVertex = vtx;
2739 AliTrackerBase::GetBxByBz(x,b);
2742 AliWarning("Could not get TPC Inner Param.");
2743 return fCacheChi2TPCConstrainedVsGlobal;
2746 // clone for constraining
2747 AliExternalTrackParam* tpcInnerC = new AliExternalTrackParam(*fTPCInner);
2749 AliWarning("Clone of TPCInnerParam failed.");
2750 return fCacheChi2TPCConstrainedVsGlobal;
2753 // transform to the track reference frame
2754 Bool_t isOK = tpcInnerC->Rotate(GetAlpha());
2755 isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2759 AliWarning("Rotation/Propagation of track failed.") ;
2760 return fCacheChi2TPCConstrainedVsGlobal;
2763 // constrain TPCinner
2764 isOK = tpcInnerC->ConstrainToVertex(vtx, b);
2766 // transform to the track reference frame
2767 isOK &= tpcInnerC->Rotate(GetAlpha());
2768 isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2771 AliWarning("ConstrainTPCInner failed.") ;
2774 return fCacheChi2TPCConstrainedVsGlobal;
2777 // calculate chi2 between vi and vj vectors
2778 // with covi and covj covariance matrices
2779 // chi2ij = (vi-vj)^(T)*(covi+covj)^(-1)*(vi-vj)
2780 TMatrixD deltaT(5,1);
2781 TMatrixD delta(1,5);
2782 TMatrixD covarM(5,5);
2784 for (Int_t ipar=0; ipar<5; ipar++) {
2785 deltaT(ipar,0) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2786 delta(0,ipar) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2788 for (Int_t jpar=0; jpar<5; jpar++) {
2789 Int_t index = GetIndex(ipar,jpar);
2790 covarM(ipar,jpar) = GetCovariance()[index]+tpcInnerC->GetCovariance()[index];
2793 // chi2 distance TPC constrained and TPC+ITS
2794 TMatrixD covarMInv = covarM.Invert();
2795 TMatrixD mat2 = covarMInv*deltaT;
2796 TMatrixD chi2 = delta*mat2;
2801 fCacheChi2TPCConstrainedVsGlobal = chi2(0,0);
2802 return fCacheChi2TPCConstrainedVsGlobal;
2805 void AliESDtrack::SetDetectorPID(const AliDetectorPID *pid)
2808 // Set the detector PID
2810 if (fDetectorPID) delete fDetectorPID;
2815 Double_t AliESDtrack::GetLengthInActiveZone( Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
2817 // Input parameters:
2818 // mode - type of external track parameters
2819 // deltaY - user defined "dead region" in cm
2820 // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2821 // bz - magnetic field
2822 // exbPhi - optional rotation due to the ExB effect
2824 // the length of the track in cm in "active volume" of the TPC
2826 if (mode==0) return GetLengthInActiveZone(this, deltaY,deltaZ,bz, exbPhi,pcstream);
2827 if (mode==1) return GetLengthInActiveZone(fIp, deltaY,deltaZ,bz, exbPhi,pcstream);
2828 if (mode==2) return GetLengthInActiveZone(fOp, deltaY,deltaZ,bz, exbPhi,pcstream);
2832 Double_t AliESDtrack::GetLengthInActiveZone(const AliExternalTrackParam *paramT, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
2834 // Numerical code to calculate the length of the track in active region of the TPC
2835 // ( can be speed up if somebody wants to invest time - analysical version shoult be possible)
2837 // Input parameters:
2838 // paramT - external track parameters
2839 // deltaY - user defined "dead region" in cm
2840 // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2841 // bz - magnetic field
2842 // exbPhi - optional rotation due to the ExB effect
2844 // the length of the track in cm in "active volume" of the TPC
2846 const Double_t rIn=85;
2847 const Double_t rOut=245;
2848 Double_t xyz[3], pxyz[3];
2849 if (paramT->GetXYZAt(rIn,bz,xyz)){
2850 paramT->GetPxPyPzAt(rIn,bz,pxyz);
2852 paramT->GetXYZ(xyz);
2853 paramT->GetPxPyPz(pxyz);
2856 Double_t dca = -paramT->GetD(0,0,bz); // get impact parameter distance to point (0,0)
2857 Double_t radius= TMath::Abs(1/paramT->GetC(bz)); //
2858 Double_t sign = paramT->GetSign();
2859 Double_t R0 = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); // radius at current point
2860 Double_t phiR0 = TMath::ATan2(xyz[1],xyz[0]); // angle of given point
2861 Double_t dPhiR0= -TMath::ASin((dca*dca-2*dca*radius*sign+R0*R0)/(2*R0*(dca-radius*sign)));
2862 Double_t phi0 = phiR0-(dPhiR0); // global phi offset to be added
2865 AliExternalTrackParam paramR=(*paramT);
2867 for (Double_t R=rIn; R<=rOut; R++){
2868 Double_t sinPhi=(dca*dca-2*dca*radius*sign+R*R)/(2*R*(dca-radius*sign));
2869 if (TMath::Abs(sinPhi)>=1) continue;
2870 Double_t dphi = -TMath::ASin(sinPhi);
2871 Double_t phi = phi0+dphi; // global phi
2872 Int_t sector = TMath::Nint(9*phi/(TMath::Pi()));
2873 Double_t dPhiEdge = phi-(sector*TMath::Pi()/9)+exbPhi; // distance to sector boundary in rphi
2874 Double_t dX = R*TMath::Cos(phi)-xyz[0];
2875 Double_t dY = R*TMath::Sin(phi)-xyz[1];
2876 Double_t deltaPhi = 2*TMath::ASin(0.5*TMath::Sqrt(dX*dX+dY*dY)/radius);
2877 Double_t z = xyz[2]+deltaPhi*radius*paramT->GetTgl();
2878 if (TMath::Abs(dPhiEdge*R)>deltaY && TMath::Abs(z)<deltaZ){
2881 // Double_t deltaZ= dphi*radius;
2883 //should we keep debug possibility ?
2884 AliExternalTrackParam paramTcopy=(*paramT);
2886 paramR.PropagateTo(R,bz);
2887 (*pcstream)<<"debugEdge"<<
2889 "dphiEdge="<<dPhiEdge<< // distance to edge
2890 "phi0="<<phi0<< // phi0 -phi at the track initial position
2893 "pT.="<<¶mTcopy<<
2901 void AliESDtrack::SetTOFclusterArray(Int_t ncluster,Int_t *TOFcluster){
2902 AliInfo("Method has to be implemented!");
2903 // fNtofClusters=ncluster;
2904 // if(TOFcluster == fTOFcluster) return;
2905 // if(fTOFcluster){ // reset previous content
2906 // delete[] fTOFcluster;
2907 // fTOFcluster = NULL;
2911 // if(ncluster){ // set new content
2912 // fTOFcluster = new Int_t[fNtofClusters];
2913 // for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = TOFcluster[i];
2919 void AliESDtrack::AddTOFcluster(Int_t icl){
2922 Int_t *old = fTOFcluster;
2923 fTOFcluster = new Int_t[fNtofClusters];
2925 for(Int_t i=0;i < fNtofClusters-1;i++) fTOFcluster[i] = old[i];
2926 fTOFcluster[fNtofClusters-1] = icl;
2928 if(fNtofClusters-1){ // delete previous content
2935 Double_t AliESDtrack::GetTOFsignal() const {
2936 if(fNtofClusters>0 && GetESDEvent()){
2937 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2938 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2940 return tofcl->GetTime();
2942 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2947 Double_t AliESDtrack::GetTOFsignalToT() const
2949 if(fNtofClusters>0 && GetESDEvent()){
2950 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2951 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2953 return tofcl->GetTOT();
2955 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2957 return fTOFsignalToT;
2960 Double_t AliESDtrack::GetTOFsignalRaw() const
2962 if(fNtofClusters>0 && GetESDEvent()){
2963 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2964 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2966 return tofcl->GetTimeRaw();
2968 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2970 return fTOFsignalRaw;
2973 Double_t AliESDtrack::GetTOFsignalDz() const
2976 AliESDTOFcluster *tofcl;
2979 if(fNtofClusters>0 && GetESDEvent()){
2980 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2981 tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2983 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
2984 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
2987 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2989 if(fNtofClusters>0 && index > -1){
2990 return tofcl->GetDz(index);
2992 return fTOFsignalDz;
2995 Double_t AliESDtrack::GetTOFsignalDx() const
2997 AliESDTOFcluster *tofcl;
3000 if(fNtofClusters>0 && GetESDEvent()){
3001 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3002 tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3003 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3004 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3007 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3008 if(fNtofClusters>0 && index > -1){
3009 return tofcl->GetDx(index);
3011 return fTOFsignalDx;
3014 Short_t AliESDtrack::GetTOFDeltaBC() const
3016 if(fNtofClusters>0 && GetESDEvent()){
3017 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3018 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3019 return tofcl->GetDeltaBC();
3021 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3026 Short_t AliESDtrack::GetTOFL0L1() const
3028 if(fNtofClusters>0 && GetESDEvent()){
3029 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3030 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3032 return tofcl->GetL0L1Latency();
3034 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3039 Int_t AliESDtrack::GetTOFCalChannel() const
3041 if(fNtofClusters>0 && GetESDEvent()){
3042 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3043 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3045 tofcl->GetTOFchannel();
3047 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3049 return fTOFCalChannel;
3052 Int_t AliESDtrack::GetTOFcluster() const
3054 if(fNtofClusters>0 && GetESDEvent()){
3055 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3056 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3058 tofcl->GetClusterIndex();
3060 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3065 Int_t AliESDtrack::GetTOFclusterN() const
3067 return fNtofClusters;
3070 Bool_t AliESDtrack::IsTOFHitAlreadyMatched() const{
3071 if(fNtofClusters>0 && GetESDEvent()){
3072 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3073 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3075 if (tofcl->GetNMatchableTracks() > 1)
3078 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3083 void AliESDtrack::ReMapTOFcluster(Int_t ncl,Int_t *mapping){
3084 for(Int_t i=0;i<fNtofClusters;i++){
3085 if(fTOFcluster[i]<ncl && fTOFcluster[i]>-1)
3086 fTOFcluster[i] = mapping[fTOFcluster[i]];
3088 AliInfo(Form("TOF cluster re-mapping in AliESDtrack: out of range (%i > %i)\n",fTOFcluster[i],ncl));
3092 void AliESDtrack::SortTOFcluster(){
3093 TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3095 for(Int_t i=0;i<fNtofClusters-1;i++){
3096 for(Int_t j=i+1;j<fNtofClusters;j++){
3097 AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[i]);
3099 for(Int_t it=0;it < tofcl->GetNMatchableTracks();it++){
3100 if(tofcl->GetTrackIndex(it) == GetID()) index1 = it;
3102 Double_t timedist1 = 10000;
3103 for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3104 Double_t timec = TMath::Abs(tofcl->GetTime() - tofcl->GetIntegratedTime(isp));
3105 if(timec < timedist1) timedist1 = timec;
3107 timedist1 *= 0.03; // in cm
3108 Double_t radius1 = tofcl->GetDx(index1)*tofcl->GetDx(index1) + tofcl->GetDz(index1)*tofcl->GetDz(index1) + timedist1*timedist1;
3110 AliESDTOFcluster *tofcl2 = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[j]);
3112 for(Int_t it=0;it < tofcl2->GetNMatchableTracks();it++){
3113 if(tofcl2->GetTrackIndex(it) == GetID()) index2 = it;
3115 if(index1 == -1 || index2 == -1){
3117 Double_t timedist2 = 10000;
3118 for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3119 Double_t timec = TMath::Abs(tofcl2->GetTime() - tofcl2->GetIntegratedTime(isp));
3120 if(timec < timedist2) timedist2 = timec;
3122 timedist2 *= 0.03; // in cm
3123 Double_t radius2 = tofcl2->GetDx(index2)*tofcl2->GetDx(index2) + tofcl2->GetDz(index2)*tofcl2->GetDz(index2) + timedist2*timedist2;
3125 if(radius2 < radius1){
3126 Int_t change = fTOFcluster[i];
3127 fTOFcluster[i] = fTOFcluster[j];
3128 fTOFcluster[j] = change;