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.
37 // a.) Track parameters and covariance - AliExternalTrackParam - snapshots along trajectory at differnt tracking steps
38 // current, fIp, fTPCinner, fCp, fOp, fHMPIDp, + friendTrack (fITSout, fTPCout, fTRDin)
39 // b.) Flags - per detector status bits
40 // c.) Track fit quality -chi2, number of clusters
41 // d.) Detector PID information
42 // d.) Different detector specific information (e.g number of tracklets in TRD, TOF cluster descriptor ...)
45 // The track information is propagated from one tracking detector to
46 // other using the functionality of AliESDtrack (AliExternalTrackParam - current parameters)
48 // Barrel tracking uses Kalman filtering technique (no global fit model is used). Kalman provides optimal local
49 // track parameters estimate at given position under certian assumptions.
50 // Following approximations were used:
51 // a.) gaussian Multiple scattering
52 // b.) gaussian energy loss
53 // c.) gaussian error of the space point residuals
55 // Kalman filter take into account following effects which are
56 // difficult to handle using global fit:
57 // a.) Multiple scattering
59 // c.) Non homogenous magnetic field
61 // In general case, following barrel detectors are contributing to
62 // the Kalman track information:
67 // Track findind/fitting procedure is done in 3 steps:
68 // 1. Cluster2Track(in) - inward sequence TPC->ITS
69 // 2. PropagateBack(out) - outward sequence ITS->TPC->TRD -> Outer PID detectors
70 // 3. RefitInward(refit) - inward sequence TRD->TPC->ITS
71 // After each recosntruction step detector status is updated in the data member fFlags
72 // fFlags|=k<DetectorName><step> where step={1:in,2:out,3:refit,}
73 // For some of detectors a special flags were implemented. Declaration of list of all flags can be find in $ALICE_ROOT/STEER/STEERBase/AliVTrack.h
76 // The current track parameter is updated after each detector (see bellow).
77 // In specical cases a track snapshots (AliExternalTrackParam) are stored
81 // For some type of analysis (+visualization) track local parameters at
82 // different position are neccesary. A snapshots during the track
83 // propagation are created and stored either in track itself (for analysis purposes) or assiciated friend track (for calibration and debugging purposes)
84 // (See AliExternalTrackParam class for desctiption of variables and functionality)
86 // a.) Current parameters (AliESDtrack itself)
87 // Description: as obtained in the last succesfull tracking step
88 // Contributors: best case TRD->TPC->ITS after RefitInward
89 // Recomended way to get track parameters. It includes all of the information.
90 // NOTICE - By default the track parameters are stored at the DCA point to the primary vertex.
91 // Optimal for primary tracks, far from optimal for deeply secondary tracks.
92 // To get optimal track parameters at the secondary vertex, OnTheFly V0s with associated track parameters should be used
94 // b.) Constrained parameters (fCp)
96 // Kalman track updated with the Primary vertex information with corresponding error (soft constraint - see http://en.wikipedia.org/wiki/Constraint_(mathematics)#Hard_and_soft_constraints)
98 // const AliExternalTrackParam *GetConstrainedParam() const {return fCp;}
99 // Contributors: best case TRD->TPC->ITS after RefitInward
100 // Recommended usage: Use only for tracks selected as primary (check GetConstrainedChi2())
101 // NOTICE - not real constraint only soft constraint
103 // c.) Inner parameters (fIp) -
104 // Description: Track parameters at inner wall of the TPC
106 // const AliExternalTrackParam *GetInnerParam() const { return fIp;}
107 // Contributors: general case TRD->TPC (during RefitInward)
108 // Recomended usage: To provide momenta for the TPC PID and to estimate quality of the track determination for further
110 // d.) TPCinnerParam (fTPCinner):
111 // Description: TPC only parameters at DCA to the primary vertex (corrected for the material between TPC and vertex)
113 // const AliExternalTrackParam *GetTPCInnerParam() const {return fTPCInner;}
114 // Contributors: TPC only from in step 1 (Cluster2Tracks)
115 // Recomended usage: Requested for HBT study
116 // (smaller correlations as using also ITS information)
117 // NOTICE: Optimal for primary, far from optimal for secondary tracks (similar to track parameters a.)
118 // ! We should always use the c.) fIp in case of the TPC PID analysis, or undo material budget correction!
120 // e.) Outer parameters - (fOp)
121 // Description: track parameters during PropagateBack in the last sucessfull propagation
122 // Reason to generate backup OuterParameters
123 // a.) Local inclination angle bigger than threshold -
124 // Low momenta tracks
125 // b.) Catastrofic (large relative>~20 %)energy loss in material outside of the TPC
126 // c.) No additional space points contributing to track
128 // const AliExternalTrackParam *GetOuterParam() const { return fOp;}
129 // Contributors: general case - ITS-> TPC -> TRD ( during PropagateBack )
131 // a.) Tracking: Starting parameter for Refit inward
134 // NOTICE: Should be not used for the physic analysis
136 // const AliExternalTrackParam *GetOuterParam() const { return fOp;}
138 //-----------------------------------------------------------------
141 #include <TParticle.h>
142 #include <TDatabasePDG.h>
143 #include <TMatrixD.h>
145 #include "AliESDVertex.h"
146 #include "AliESDtrack.h"
147 #include "AliESDEvent.h"
148 #include "AliKalmanTrack.h"
149 #include "AliVTrack.h"
151 #include "AliTrackPointArray.h"
152 #include "TPolyMarker3D.h"
153 #include "AliTrackerBase.h"
154 #include "AliTPCdEdxInfo.h"
155 #include "AliDetectorPID.h"
156 #include "TTreeStream.h"
157 #include "TObjArray.h"
159 ClassImp(AliESDtrack)
161 void SetPIDValues(Double_t * dest, const Double_t * src, Int_t n) {
162 // This function copies "n" PID weights from "scr" to "dest"
163 // and normalizes their sum to 1 thus producing conditional probabilities.
164 // The negative weights are set to 0.
165 // In case all the weights are non-positive they are replaced by
166 // uniform probabilities
170 Float_t uniform = 1./(Float_t)n;
173 for (Int_t i=0; i<n; i++)
183 for (Int_t i=0; i<n; i++) dest[i] /= sum;
185 for (Int_t i=0; i<n; i++) dest[i] = uniform;
188 //_______________________________________________________________________
189 AliESDtrack::AliESDtrack() :
190 AliExternalTrackParam(),
197 fTPCFitMap(159),//number of padrows
198 fTPCClusterMap(159),//number of padrows
199 fTPCSharedMap(159),//number of padrows
211 fCaloIndex(kEMCALNoMatch),
224 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
227 fCdd(0),fCdz(0),fCzz(0),
245 fTOFsignalTuned(99999),
246 fTOFsignalToT(99999),
247 fTOFsignalRaw(99999),
273 fVertexID(-2),// -2 means an orphan track
274 fPIDForTracking(AliPID::kPion),
276 fCacheNCrossedRows(-10),
277 fCacheChi2TPCConstrainedVsGlobal(-10),
278 fCacheChi2TPCConstrainedVsGlobalVertex(0),
280 fTrackPhiOnEMCal(-999),
281 fTrackEtaOnEMCal(-999),
282 fTrackPtOnEMCal(-999),
287 // The default ESD constructor
289 if (!OnlineMode()) fFriendTrack=new AliESDfriendTrack();
292 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
294 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
295 for (i=0; i<3; i++) { fV0Indexes[i]=0;}
296 for (i=0;i<kTRDnPlanes;i++) {
299 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
300 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
301 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
302 for (i=0;i<12;i++) {fITSModule[i]=-1;}
305 bool AliESDtrack::fgkOnlineMode=false;
307 //_______________________________________________________________________
308 AliESDtrack::AliESDtrack(const AliESDtrack& track):
309 AliExternalTrackParam(track),
316 fTPCFitMap(track.fTPCFitMap),
317 fTPCClusterMap(track.fTPCClusterMap),
318 fTPCSharedMap(track.fTPCSharedMap),
319 fFlags(track.fFlags),
321 fLabel(track.fLabel),
322 fITSLabel(track.fITSLabel),
323 fTPCLabel(track.fTPCLabel),
324 fTRDLabel(track.fTRDLabel),
326 fTOFCalChannel(track.fTOFCalChannel),
327 fTOFindex(track.fTOFindex),
328 fHMPIDqn(track.fHMPIDqn),
329 fHMPIDcluIdx(track.fHMPIDcluIdx),
330 fCaloIndex(track.fCaloIndex),
337 fHMPIDtrkTheta(track.fHMPIDtrkTheta),
338 fHMPIDtrkPhi(track.fHMPIDtrkPhi),
339 fHMPIDsignal(track.fHMPIDsignal),
341 fTrackLength(track.fTrackLength),
342 fdTPC(track.fdTPC),fzTPC(track.fzTPC),
343 fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
344 fCchi2TPC(track.fCchi2TPC),
345 fD(track.fD),fZ(track.fZ),
346 fCdd(track.fCdd),fCdz(track.fCdz),fCzz(track.fCzz),
347 fCchi2(track.fCchi2),
348 fITSchi2(track.fITSchi2),
349 fTPCchi2(track.fTPCchi2),
350 fTPCchi2Iter1(track.fTPCchi2Iter1),
351 fTRDchi2(track.fTRDchi2),
352 fTOFchi2(track.fTOFchi2),
353 fHMPIDchi2(track.fHMPIDchi2),
354 fGlobalChi2(track.fGlobalChi2),
355 fITSsignal(track.fITSsignal),
356 fTPCsignal(track.fTPCsignal),
357 fTPCsignalTuned(track.fTPCsignalTuned),
358 fTPCsignalS(track.fTPCsignalS),
360 fTRDsignal(track.fTRDsignal),
361 fTRDQuality(track.fTRDQuality),
362 fTRDBudget(track.fTRDBudget),
363 fTOFsignal(track.fTOFsignal),
364 fTOFsignalTuned(track.fTOFsignalTuned),
365 fTOFsignalToT(track.fTOFsignalToT),
366 fTOFsignalRaw(track.fTOFsignalRaw),
367 fTOFsignalDz(track.fTOFsignalDz),
368 fTOFsignalDx(track.fTOFsignalDx),
369 fTOFdeltaBC(track.fTOFdeltaBC),
370 fTOFl0l1(track.fTOFl0l1),
371 fCaloDx(track.fCaloDx),
372 fCaloDz(track.fCaloDz),
373 fHMPIDtrkX(track.fHMPIDtrkX),
374 fHMPIDtrkY(track.fHMPIDtrkY),
375 fHMPIDmipX(track.fHMPIDmipX),
376 fHMPIDmipY(track.fHMPIDmipY),
377 fTPCncls(track.fTPCncls),
378 fTPCnclsF(track.fTPCnclsF),
379 fTPCsignalN(track.fTPCsignalN),
380 fTPCnclsIter1(track.fTPCnclsIter1),
381 fTPCnclsFIter1(track.fTPCnclsIter1),
382 fITSncls(track.fITSncls),
383 fITSClusterMap(track.fITSClusterMap),
384 fITSSharedMap(track.fITSSharedMap),
385 fTRDncls(track.fTRDncls),
386 fTRDncls0(track.fTRDncls0),
387 fTRDntracklets(track.fTRDntracklets),
388 fTRDNchamberdEdx(track.fTRDNchamberdEdx),
389 fTRDNclusterdEdx(track.fTRDNclusterdEdx),
390 fTRDnSlices(track.fTRDnSlices),
392 fVertexID(track.fVertexID),
393 fPIDForTracking(AliPID::kPion),
394 fESDEvent(track.fESDEvent),
395 fCacheNCrossedRows(track.fCacheNCrossedRows),
396 fCacheChi2TPCConstrainedVsGlobal(track.fCacheChi2TPCConstrainedVsGlobal),
397 fCacheChi2TPCConstrainedVsGlobalVertex(track.fCacheChi2TPCConstrainedVsGlobalVertex),
399 fTrackPhiOnEMCal(track.fTrackPhiOnEMCal),
400 fTrackEtaOnEMCal(track.fTrackEtaOnEMCal),
401 fTrackPtOnEMCal(track.fTrackPtOnEMCal),
402 fNtofClusters(track.fNtofClusters),
408 for (Int_t i=kNITSchi2Std;i--;) fITSchi2Std[i] = track.fITSchi2Std[i];
410 if(track.fTrackTime){
411 fTrackTime = new Double32_t[AliPID::kSPECIESC];
412 for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i]=track.fTrackTime[i];
416 fR = new Double32_t[AliPID::kSPECIES];
417 for (Int_t i=AliPID::kSPECIES;i--;) fR[i]=track.fR[i];
420 fITSr = new Double32_t[AliPID::kSPECIES];
421 for (Int_t i=AliPID::kSPECIES;i--;) fITSr[i]=track.fITSr[i];
425 fTPCr = new Double32_t[AliPID::kSPECIES];
426 for (Int_t i=AliPID::kSPECIES;i--;) fTPCr[i]=track.fTPCr[i];
429 for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=track.fITSdEdxSamples[i];}
430 for (Int_t i=0;i<4;i++) {fTPCPoints[i]=track.fTPCPoints[i];}
431 for (Int_t i=0; i<3;i++) { fKinkIndexes[i]=track.fKinkIndexes[i];}
432 for (Int_t i=0; i<3;i++) { fV0Indexes[i]=track.fV0Indexes[i];}
434 for (Int_t i=0;i<kTRDnPlanes;i++) {
435 fTRDTimBin[i]=track.fTRDTimBin[i];
439 fTRDslices=new Double32_t[fTRDnSlices];
440 for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=track.fTRDslices[i];
443 if (track.fDetectorPID) fDetectorPID = new AliDetectorPID(*track.fDetectorPID);
446 fTRDr = new Double32_t[AliPID::kSPECIES];
447 for (Int_t i=AliPID::kSPECIES;i--;) fTRDr[i]=track.fTRDr[i];
451 fTOFr = new Double32_t[AliPID::kSPECIES];
452 for (Int_t i=AliPID::kSPECIES;i--;) fTOFr[i]=track.fTOFr[i];
456 if(!fTOFLabel) fTOFLabel = new Int_t[3];
457 for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
460 for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
461 for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
464 fHMPIDr = new Double32_t[AliPID::kSPECIES];
465 for (Int_t i=AliPID::kSPECIES;i--;) fHMPIDr[i]=track.fHMPIDr[i];
468 if (track.fCp) fCp=new AliExternalTrackParam(*track.fCp);
469 if (track.fIp) fIp=new AliExternalTrackParam(*track.fIp);
470 if (track.fTPCInner) fTPCInner=new AliExternalTrackParam(*track.fTPCInner);
471 if (track.fOp) fOp=new AliExternalTrackParam(*track.fOp);
472 if (track.fHMPIDp) fHMPIDp=new AliExternalTrackParam(*track.fHMPIDp);
473 if (track.fTPCdEdxInfo) fTPCdEdxInfo = new AliTPCdEdxInfo(*track.fTPCdEdxInfo);
476 if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
478 if(fNtofClusters > 0){
479 fTOFcluster = new Int_t[fNtofClusters];
480 for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = track.fTOFcluster[i];
484 //_______________________________________________________________________
485 AliESDtrack::AliESDtrack(const AliVTrack *track) :
486 AliExternalTrackParam(track),
493 fTPCFitMap(159),//number of padrows
494 fTPCClusterMap(159),//number of padrows
495 fTPCSharedMap(159),//number of padrows
507 fCaloIndex(kEMCALNoMatch),
520 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
523 fCdd(0),fCdz(0),fCzz(0),
541 fTOFsignalTuned(99999),
542 fTOFsignalToT(99999),
543 fTOFsignalRaw(99999),
569 fVertexID(-2), // -2 means an orphan track
570 fPIDForTracking(track->GetPIDForTracking()),
572 fCacheNCrossedRows(-10),
573 fCacheChi2TPCConstrainedVsGlobal(-10),
574 fCacheChi2TPCConstrainedVsGlobalVertex(0),
576 fTrackPhiOnEMCal(-999),
577 fTrackEtaOnEMCal(-999),
578 fTrackPtOnEMCal(-999),
583 // ESD track from AliVTrack.
584 // This is not a copy constructor !
587 if (track->InheritsFrom("AliExternalTrackParam")) {
588 AliError("This is not a copy constructor. Use AliESDtrack(const AliESDtrack &) !");
589 AliWarning("Calling the default constructor...");
594 // Reset all the arrays
596 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
598 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
599 for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
600 for (i=0;i<kTRDnPlanes;i++) {
603 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
604 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
605 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
606 for (i=0;i<12;i++) {fITSModule[i]=-1;}
609 // Set ITS cluster map
610 fITSClusterMap=track->GetITSClusterMap();
615 if(HasPointOnITSLayer(i)) fITSncls++;
619 fTPCncls=track->GetTPCNcls();
620 fTPCnclsF=track->GetTPCNclsF();
622 const TBits* bmap = track->GetTPCClusterMapPtr();
623 if (bmap) SetTPCClusterMap(*bmap);
624 bmap = GetTPCFitMapPtr();
625 if (bmap) SetTPCFitMap(*bmap);
626 bmap = GetTPCSharedMapPtr();
627 if (bmap) SetTPCSharedMap(*bmap);
629 // Set the combined PID
630 const Double_t *pid = track->PID();
632 fR = new Double32_t[AliPID::kSPECIES];
633 for (i=AliPID::kSPECIES; i--;) fR[i]=pid[i];
636 // calo matched cluster id
637 SetEMCALcluster(track->GetEMCALcluster());
638 // AliESD track label
641 fITSsignal = track->GetITSsignal();
643 track->GetITSdEdxSamples(itsdEdx);
644 SetITSdEdxSamples(itsdEdx);
646 SetTPCsignal(track->GetTPCsignal(),fTPCsignalS,track->GetTPCsignalN()); // No signalS in AODPi
647 AliTPCdEdxInfo * dEdxInfo = track->GetTPCdEdxInfo();
648 if (dEdxInfo) SetTPCdEdxInfo(new AliTPCdEdxInfo(*dEdxInfo));
650 SetTRDsignal(track->GetTRDsignal());
651 int ntrdsl = track->GetNumberOfTRDslices();
653 SetNumberOfTRDslices((ntrdsl+2)*kTRDnPlanes);
654 for (int ipl=kTRDnPlanes;ipl--;){
655 for (int isl=ntrdsl;isl--;) SetTRDslice(track->GetTRDslice(ipl,isl),ipl,isl);
656 Double_t sp, p = track->GetTRDmomentum(ipl, &sp);
657 SetTRDmomentum(p, ipl, &sp);
661 fTRDncls = track->GetTRDncls();
662 fTRDntracklets &= 0xff & track->GetTRDntrackletsPID();
663 fTRDchi2 = track->GetTRDchi2();
665 SetTOFsignal(track->GetTOFsignal());
666 Double_t expt[AliPID::kSPECIESC];
667 track->GetIntegratedTimes(expt,AliPID::kSPECIESC);
668 SetIntegratedTimes(expt);
670 SetTrackPhiEtaPtOnEMCal(track->GetTrackPhiOnEMCal(),track->GetTrackEtaOnEMCal(),track->GetTrackPtOnEMCal());
672 SetLabel(track->GetLabel());
674 SetStatus(track->GetStatus());
677 SetID(track->GetID());
681 //_______________________________________________________________________
682 AliESDtrack::AliESDtrack(TParticle * part) :
683 AliExternalTrackParam(),
690 fTPCFitMap(159),//number of padrows
691 fTPCClusterMap(159),//number of padrows
692 fTPCSharedMap(159),//number of padrows
704 fCaloIndex(kEMCALNoMatch),
717 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
720 fCdd(0),fCdz(0),fCzz(0),
738 fTOFsignalTuned(99999),
739 fTOFsignalToT(99999),
740 fTOFsignalRaw(99999),
766 fVertexID(-2), // -2 means an orphan track
767 fPIDForTracking(AliPID::kPion),
769 fCacheNCrossedRows(-10),
770 fCacheChi2TPCConstrainedVsGlobal(-10),
771 fCacheChi2TPCConstrainedVsGlobalVertex(0),
773 fTrackPhiOnEMCal(-999),
774 fTrackEtaOnEMCal(-999),
775 fTrackPtOnEMCal(-999),
780 // ESD track from TParticle
783 // Reset all the arrays
785 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
787 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
788 for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
789 for (i=0;i<kTRDnPlanes;i++) {
792 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
793 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
794 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
795 for (i=0;i<12;i++) {fITSModule[i]=-1;}
797 // Calculate the AliExternalTrackParam content
804 // Calculate alpha: the rotation angle of the corresponding local system (TPC sector)
805 alpha = part->Phi()*180./TMath::Pi();
806 if (alpha<0) alpha+= 360.;
807 if (alpha>360) alpha -= 360.;
809 Int_t sector = (Int_t)(alpha/20.);
810 alpha = 10. + 20.*sector;
812 alpha *= TMath::Pi();
814 // Covariance matrix: no errors, the parameters are exact
815 for (i=0; i<15; i++) covar[i]=0.;
817 // Get the vertex of origin and the momentum
818 TVector3 ver(part->Vx(),part->Vy(),part->Vz());
819 TVector3 mom(part->Px(),part->Py(),part->Pz());
821 // Rotate to the local coordinate system (TPC sector)
825 // X of the referense plane
828 Int_t pdgCode = part->GetPdgCode();
831 TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge();
835 param[2] = TMath::Sin(mom.Phi());
836 param[3] = mom.Pz()/mom.Pt();
837 param[4] = TMath::Sign(1/mom.Pt(),charge);
839 // Set AliExternalTrackParam
840 Set(xref, alpha, param, covar);
844 if (pdgCode<0) pdgCode = -pdgCode;
845 for (i=0;i<AliPID::kSPECIESC;i++) if (pdgCode==AliPID::ParticleCode(i)) {indexPID = i; break;}
847 if (indexPID < AliPID::kSPECIESC) fPIDForTracking = indexPID;
849 // AliESD track label
850 SetLabel(part->GetUniqueID());
854 //_______________________________________________________________________
855 AliESDtrack::~AliESDtrack(){
857 // This is destructor according Coding Conventrions
859 //printf("Delete track\n");
870 //Reset cached values - needed for TClonesArray in AliESDInputHandler
871 fCacheNCrossedRows = -10.;
872 fCacheChi2TPCConstrainedVsGlobal = -10.;
873 if(fCacheChi2TPCConstrainedVsGlobalVertex) fCacheChi2TPCConstrainedVsGlobalVertex = 0;
876 delete[] fTOFcluster;
889 if(fTrackTime) delete[] fTrackTime;
890 if(fTOFLabel) delete[] fTOFLabel;
893 //_______________________________________________________________________
894 AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source)
898 if(&source == this) return *this;
899 AliExternalTrackParam::operator=(source);
903 // we have the trackparam: assign or copy construct
904 if(fCp)*fCp = *source.fCp;
905 else fCp = new AliExternalTrackParam(*source.fCp);
908 // no track param delete the old one
914 // we have the trackparam: assign or copy construct
915 if(fIp)*fIp = *source.fIp;
916 else fIp = new AliExternalTrackParam(*source.fIp);
919 // no track param delete the old one
925 if(source.fTPCInner){
926 // we have the trackparam: assign or copy construct
927 if(fTPCInner) *fTPCInner = *source.fTPCInner;
928 else fTPCInner = new AliExternalTrackParam(*source.fTPCInner);
931 // no track param delete the old one
936 if(source.fTPCdEdxInfo) {
937 if(fTPCdEdxInfo) *fTPCdEdxInfo = *source.fTPCdEdxInfo;
938 fTPCdEdxInfo = new AliTPCdEdxInfo(*source.fTPCdEdxInfo);
942 // we have the trackparam: assign or copy construct
943 if(fOp) *fOp = *source.fOp;
944 else fOp = new AliExternalTrackParam(*source.fOp);
947 // no track param delete the old one
954 // we have the trackparam: assign or copy construct
955 if(fHMPIDp) *fHMPIDp = *source.fHMPIDp;
956 else fHMPIDp = new AliExternalTrackParam(*source.fHMPIDp);
959 // no track param delete the old one
964 // copy also the friend track
965 // use copy constructor
966 if(source.fFriendTrack){
967 // we have the trackparam: assign or copy construct
968 delete fFriendTrack; fFriendTrack=new AliESDfriendTrack(*source.fFriendTrack);
971 // no track param delete the old one
972 delete fFriendTrack; fFriendTrack= 0;
975 fTPCFitMap = source.fTPCFitMap;
976 fTPCClusterMap = source.fTPCClusterMap;
977 fTPCSharedMap = source.fTPCSharedMap;
979 fFlags = source.fFlags;
981 fLabel = source.fLabel;
982 fITSLabel = source.fITSLabel;
983 for(int i = 0; i< 12;++i){
984 fITSModule[i] = source.fITSModule[i];
986 fTPCLabel = source.fTPCLabel;
987 fTRDLabel = source.fTRDLabel;
988 if(source.fTOFLabel){
989 if(!fTOFLabel) fTOFLabel = new Int_t[3];
990 for(int i = 0; i< 3;++i){
991 fTOFLabel[i] = source.fTOFLabel[i];
994 fTOFCalChannel = source.fTOFCalChannel;
995 fTOFindex = source.fTOFindex;
996 fHMPIDqn = source.fHMPIDqn;
997 fHMPIDcluIdx = source.fHMPIDcluIdx;
998 fCaloIndex = source.fCaloIndex;
999 for (int i=kNITSchi2Std;i--;) fITSchi2Std[i] = source.fITSchi2Std[i];
1000 for(int i = 0; i< 3;++i){
1001 fKinkIndexes[i] = source.fKinkIndexes[i];
1002 fV0Indexes[i] = source.fV0Indexes[i];
1006 if (!fR) fR = new Double32_t[AliPID::kSPECIES];
1007 for (Int_t i=AliPID::kSPECIES;i--;) fR[i]=source.fR[i];
1009 else {delete[] fR; fR = 0;}
1012 if (!fITSr) fITSr = new Double32_t[AliPID::kSPECIES];
1013 for (Int_t i=AliPID::kSPECIES;i--;) fITSr[i]=source.fITSr[i];
1015 else {delete[] fITSr; fITSr = 0;}
1018 if (!fTPCr) fTPCr = new Double32_t[AliPID::kSPECIES];
1019 for (Int_t i=AliPID::kSPECIES;i--;) fTPCr[i]=source.fTPCr[i];
1021 else {delete[] fTPCr; fTPCr = 0;}
1024 if (!fTRDr) fTRDr = new Double32_t[AliPID::kSPECIES];
1025 for (Int_t i=AliPID::kSPECIES;i--;) fTRDr[i]=source.fTRDr[i];
1027 else {delete[] fTRDr; fTRDr = 0;}
1030 if (!fTOFr) fTOFr = new Double32_t[AliPID::kSPECIES];
1031 for (Int_t i=AliPID::kSPECIES;i--;) fTOFr[i]=source.fTOFr[i];
1033 else {delete[] fTOFr; fTOFr = 0;}
1035 if (source.fHMPIDr) {
1036 if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
1037 for (Int_t i=AliPID::kSPECIES;i--;) fHMPIDr[i]=source.fHMPIDr[i];
1039 else {delete[] fHMPIDr; fHMPIDr = 0;}
1041 fPIDForTracking = source.fPIDForTracking;
1043 fHMPIDtrkTheta = source.fHMPIDtrkTheta;
1044 fHMPIDtrkPhi = source.fHMPIDtrkPhi;
1045 fHMPIDsignal = source.fHMPIDsignal;
1049 delete[] fTrackTime;
1051 if(source.fTrackTime){
1052 fTrackTime = new Double32_t[AliPID::kSPECIESC];
1053 for(Int_t i=0;i < AliPID::kSPECIESC;i++)
1054 fTrackTime[i] = source.fTrackTime[i];
1057 fTrackLength = source. fTrackLength;
1058 fdTPC = source.fdTPC;
1059 fzTPC = source.fzTPC;
1060 fCddTPC = source.fCddTPC;
1061 fCdzTPC = source.fCdzTPC;
1062 fCzzTPC = source.fCzzTPC;
1063 fCchi2TPC = source.fCchi2TPC;
1070 fCchi2 = source.fCchi2;
1072 fITSchi2 = source.fITSchi2;
1073 fTPCchi2 = source.fTPCchi2;
1074 fTPCchi2Iter1 = source.fTPCchi2Iter1;
1075 fTRDchi2 = source.fTRDchi2;
1076 fTOFchi2 = source.fTOFchi2;
1077 fHMPIDchi2 = source.fHMPIDchi2;
1079 fGlobalChi2 = source.fGlobalChi2;
1081 fITSsignal = source.fITSsignal;
1082 for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=source.fITSdEdxSamples[i];}
1083 fTPCsignal = source.fTPCsignal;
1084 fTPCsignalTuned = source.fTPCsignalTuned;
1085 fTPCsignalS = source.fTPCsignalS;
1086 for(int i = 0; i< 4;++i){
1087 fTPCPoints[i] = source.fTPCPoints[i];
1089 fTRDsignal = source.fTRDsignal;
1090 fTRDNchamberdEdx = source.fTRDNchamberdEdx;
1091 fTRDNclusterdEdx = source.fTRDNclusterdEdx;
1093 for(int i = 0;i < kTRDnPlanes;++i){
1094 fTRDTimBin[i] = source.fTRDTimBin[i];
1098 delete[] fTRDslices;
1100 fTRDnSlices=source.fTRDnSlices;
1102 fTRDslices=new Double32_t[fTRDnSlices];
1103 for(int j = 0;j < fTRDnSlices;++j) fTRDslices[j] = source.fTRDslices[j];
1106 fTRDQuality = source.fTRDQuality;
1107 fTRDBudget = source.fTRDBudget;
1108 fTOFsignal = source.fTOFsignal;
1109 fTOFsignalTuned = source.fTOFsignalTuned;
1110 fTOFsignalToT = source.fTOFsignalToT;
1111 fTOFsignalRaw = source.fTOFsignalRaw;
1112 fTOFsignalDz = source.fTOFsignalDz;
1113 fTOFsignalDx = source.fTOFsignalDx;
1114 fTOFdeltaBC = source.fTOFdeltaBC;
1115 fTOFl0l1 = source.fTOFl0l1;
1117 for(int i = 0;i<10;++i){
1118 fTOFInfo[i] = source.fTOFInfo[i];
1121 fHMPIDtrkX = source.fHMPIDtrkX;
1122 fHMPIDtrkY = source.fHMPIDtrkY;
1123 fHMPIDmipX = source.fHMPIDmipX;
1124 fHMPIDmipY = source.fHMPIDmipY;
1126 fTPCncls = source.fTPCncls;
1127 fTPCnclsF = source.fTPCnclsF;
1128 fTPCsignalN = source.fTPCsignalN;
1129 fTPCnclsIter1 = source.fTPCnclsIter1;
1130 fTPCnclsFIter1 = source.fTPCnclsFIter1;
1132 fITSncls = source.fITSncls;
1133 fITSClusterMap = source.fITSClusterMap;
1134 fITSSharedMap = source.fITSSharedMap;
1135 fTRDncls = source.fTRDncls;
1136 fTRDncls0 = source.fTRDncls0;
1137 fTRDntracklets = source.fTRDntracklets;
1138 fVertexID = source.fVertexID;
1139 fPIDForTracking = source.fPIDForTracking;
1141 fCacheNCrossedRows = source.fCacheNCrossedRows;
1142 fCacheChi2TPCConstrainedVsGlobal = source.fCacheChi2TPCConstrainedVsGlobal;
1143 fCacheChi2TPCConstrainedVsGlobalVertex = source.fCacheChi2TPCConstrainedVsGlobalVertex;
1145 delete fDetectorPID;
1147 if (source.fDetectorPID) fDetectorPID = new AliDetectorPID(*source.fDetectorPID);
1149 fTrackPhiOnEMCal= source.fTrackPhiOnEMCal;
1150 fTrackEtaOnEMCal= source.fTrackEtaOnEMCal;
1151 fTrackPtOnEMCal= source.fTrackPtOnEMCal;
1154 delete[] fTOFcluster;
1156 fNtofClusters = source.fNtofClusters;
1157 if(fNtofClusters > 0){
1158 fTOFcluster = new Int_t[fNtofClusters];
1159 for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = source.fTOFcluster[i];
1167 void AliESDtrack::Copy(TObject &obj) const {
1169 // this overwrites the virtual TOBject::Copy()
1170 // to allow run time copying without casting
1173 if(this==&obj)return;
1174 AliESDtrack *robj = dynamic_cast<AliESDtrack*>(&obj);
1175 if(!robj)return; // not an AliESDtrack
1182 void AliESDtrack::AddCalibObject(TObject * object){
1184 // add calib object to the list
1186 if (!fFriendTrack) fFriendTrack = new AliESDfriendTrack;
1187 if (!fFriendTrack) return;
1188 fFriendTrack->AddCalibObject(object);
1191 TObject * AliESDtrack::GetCalibObject(Int_t index){
1193 // return calib objct at given position
1195 if (!fFriendTrack) return 0;
1196 return fFriendTrack->GetCalibObject(index);
1200 Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
1202 // Fills the information of the TPC-only first reconstruction pass
1203 // into the passed ESDtrack object. For consistency fTPCInner is also filled
1208 // For data produced before r26675
1209 // RelateToVertexTPC was not properly called during reco
1210 // so you'll have to call it again, before FillTPCOnlyTrack
1211 // Float_t p[2],cov[3];
1212 // track->GetImpactParametersTPC(p,cov);
1213 // if(p[0]==0&&p[1]==0) // <- Default values
1214 // track->RelateToVertexTPC(esd->GetPrimaryVertexTPC(),esd->GetMagneticField(),kVeryBig);
1217 if(!fTPCInner)return kFALSE;
1219 // fill the TPC track params to the global track parameters
1220 track.Set(fTPCInner->GetX(),fTPCInner->GetAlpha(),fTPCInner->GetParameter(),fTPCInner->GetCovariance());
1223 track.fCdd = fCddTPC;
1224 track.fCdz = fCdzTPC;
1225 track.fCzz = fCzzTPC;
1227 // copy the inner params
1228 if(track.fIp) *track.fIp = *fIp;
1229 else track.fIp = new AliExternalTrackParam(*fIp);
1231 // copy the TPCinner parameters
1232 if(track.fTPCInner) *track.fTPCInner = *fTPCInner;
1233 else track.fTPCInner = new AliExternalTrackParam(*fTPCInner);
1234 track.fdTPC = fdTPC;
1235 track.fzTPC = fzTPC;
1236 track.fCddTPC = fCddTPC;
1237 track.fCdzTPC = fCdzTPC;
1238 track.fCzzTPC = fCzzTPC;
1239 track.fCchi2TPC = fCchi2TPC;
1241 // copy all other TPC specific parameters
1243 // replace label by TPC label
1244 track.fLabel = fTPCLabel;
1245 track.fTPCLabel = fTPCLabel;
1247 track.fTPCchi2 = fTPCchi2;
1248 track.fTPCchi2Iter1 = fTPCchi2Iter1;
1249 track.fTPCsignal = fTPCsignal;
1250 track.fTPCsignalTuned = fTPCsignalTuned;
1251 track.fTPCsignalS = fTPCsignalS;
1252 for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
1254 track.fTPCncls = fTPCncls;
1255 track.fTPCnclsF = fTPCnclsF;
1256 track.fTPCsignalN = fTPCsignalN;
1257 track.fTPCnclsIter1 = fTPCnclsIter1;
1258 track.fTPCnclsFIter1 = fTPCnclsFIter1;
1262 if (!track.fTPCr) track.fTPCr = new Double32_t[AliPID::kSPECIES];
1263 for(int i=AliPID::kSPECIES;i--;) track.fTPCr[i] = fTPCr[i];
1267 if (!track.fR) track.fR = new Double32_t[AliPID::kSPECIES];
1268 for(int i=AliPID::kSPECIES;i--;) track.fR[i] = fR[i];
1271 track.fTPCFitMap = fTPCFitMap;
1272 track.fTPCClusterMap = fTPCClusterMap;
1273 track.fTPCSharedMap = fTPCSharedMap;
1277 track.fFlags = kTPCin;
1280 track.fFlags |= fFlags & kTPCpid; //copy the TPCpid status flag
1282 for (Int_t i=0;i<3;i++) track.fKinkIndexes[i] = fKinkIndexes[i];
1288 //_______________________________________________________________________
1289 void AliESDtrack::MakeMiniESDtrack(){
1290 // Resets everything except
1291 // fFlags: Reconstruction status flags
1292 // fLabel: Track label
1293 // fID: Unique ID of the track
1294 // Impact parameter information
1295 // fR[AliPID::kSPECIES]: combined "detector response probability"
1296 // Running track parameters in the base class (AliExternalTrackParam)
1301 for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i] = 0;
1303 // Reset track parameters constrained to the primary vertex
1306 // Reset track parameters at the inner wall of TPC
1308 delete fTPCInner;fTPCInner=0;
1309 // Reset track parameters at the inner wall of the TRD
1311 // Reset track parameters at the HMPID
1312 delete fHMPIDp;fHMPIDp = 0;
1315 // Reset ITS track related information
1321 for (Int_t i=0;i<4;i++) fITSdEdxSamples[i] = 0.;
1322 if (fITSr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0;
1325 // Reset TPC related track information
1339 if (fTPCr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i] = 0;
1341 for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
1342 for (Int_t i=0; i<3;i++) fKinkIndexes[i] = 0;
1343 for (Int_t i=0; i<3;i++) fV0Indexes[i] = 0;
1345 // Reset TRD related track information
1350 fTRDNchamberdEdx = 0;
1351 fTRDNclusterdEdx = 0;
1353 for (Int_t i=0;i<kTRDnPlanes;i++) {
1356 if (fTRDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0;
1361 delete[] fTRDslices;
1366 // Reset TOF related track information
1370 fTOFCalChannel = -1;
1371 fTOFsignalToT = 99999;
1372 fTOFsignalRaw = 99999;
1377 if (fTOFr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
1378 for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
1380 // Reset HMPID related track information
1385 if (fHMPIDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
1392 fCaloIndex = kEMCALNoMatch;
1394 // reset global track chi2
1397 fVertexID = -2; // an orphan track
1398 fPIDForTracking = AliPID::kPion;
1400 delete fFriendTrack; fFriendTrack = 0;
1403 //_______________________________________________________________________
1404 Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const
1406 // Returns the particle most probable id. For backward compatibility first the prob. arrays
1407 // will be checked, but normally the GetPIDForTracking will be returned
1409 const Double32_t *prob = 0;
1410 if (tpcOnly) { // check if TPCpid is valid
1411 if (!fTPCr) return GetPIDForTracking();
1413 for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1414 if (i == AliPID::kSPECIES-1) prob = 0; // not valid, try with combined pid
1416 if (!prob) { // either requested TPCpid is not valid or comb.pid is requested
1417 if (!fR) return GetPIDForTracking();
1419 for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1420 if (i == AliPID::kSPECIES-1) return GetPIDForTracking(); // If all the probabilities are equal, return the pion mass
1425 for (i=0; i<AliPID::kSPECIES; i++) if (prob[i]>max) {k=i; max=prob[i];}
1427 if (k==0) { // dE/dx "crossing points" in the TPC
1430 if ((p>0.38)&&(p<0.48))
1431 if (prob[0]<prob[3]*10.) return AliPID::kKaon;
1432 if ((p>0.75)&&(p<0.85))
1433 if (prob[0]<prob[4]*10.) return AliPID::kProton;
1435 return AliPID::kElectron;
1437 if (k==1) return AliPID::kMuon;
1438 if (k==2||k==-1) return AliPID::kPion;
1439 if (k==3) return AliPID::kKaon;
1440 if (k==4) return AliPID::kProton;
1441 // AliWarning("Undefined PID !");
1442 return GetPIDForTracking();
1445 //_______________________________________________________________________
1446 Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b, Bool_t pidTPConly) const
1448 // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
1449 const double kSpacing = 25e3; // min interbanch spacing
1450 const double kShift = 0;
1451 Int_t bcid = kTOFBCNA; // defualt one
1452 if (!IsOn(kTOFout)/* || !IsOn(kESDpid)*/) return bcid; // no info
1454 double tdif = GetTOFsignal();
1455 if (IsOn(kTIME)) { // integrated time info is there
1456 int pid = GetPID(pidTPConly);
1457 Double_t times[AliPID::kSPECIESC];
1458 // old esd has only AliPID::kSPECIES times
1459 GetIntegratedTimes(times,pid>=AliPID::kSPECIES ? AliPID::kSPECIESC : AliPID::kSPECIES);
1462 else { // assume integrated time info from TOF radius and momentum
1463 const double kRTOF = 385.;
1464 const double kCSpeed = 3.e-2; // cm/ps
1466 if (p<0.01) return bcid;
1467 double m = GetMass(pidTPConly);
1468 double curv = GetC(b);
1469 double path = TMath::Abs(curv)>kAlmost0 ? // account for curvature
1470 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+GetTgl()*GetTgl()) : kRTOF;
1471 tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
1473 bcid = TMath::Nint((tdif - kShift)/kSpacing);
1477 //______________________________________________________________________________
1478 Double_t AliESDtrack::M() const
1480 // Returns the assumed mass
1481 // (the pion mass, if the particle can't be identified properly).
1482 static Bool_t printerr=kTRUE;
1484 AliWarning("WARNING !!! ... THIS WILL BE PRINTED JUST ONCE !!!");
1486 AliWarning("This is the ESD mass. Use it with care !");
1491 //______________________________________________________________________________
1492 Double_t AliESDtrack::E() const
1494 // Returns the energy of the particle given its assumed mass.
1495 // Assumes the pion mass if the particle can't be identified properly.
1499 return TMath::Sqrt(p*p + m*m);
1502 //______________________________________________________________________________
1503 Double_t AliESDtrack::Y() const
1505 // Returns the rapidity of a particle given its assumed mass.
1506 // Assumes the pion mass if the particle can't be identified properly.
1510 if (e != TMath::Abs(pz)) { // energy was not equal to pz
1511 return 0.5*TMath::Log((e+pz)/(e-pz));
1512 } else { // energy was equal to pz
1517 //_______________________________________________________________________
1518 Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
1520 // This function updates track's running parameters
1525 fLabel=t->GetLabel();
1527 if (t->IsStartedTimeIntegral()) {
1529 Double_t times[AliPID::kSPECIESC];
1530 t->GetIntegratedTimes(times);
1531 SetIntegratedTimes(times);
1532 SetIntegratedLength(t->GetIntegratedLength());
1535 Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1537 if (flags==kITSout) fFriendTrack->SetITSOut(*t);
1538 if (flags==kTPCout) fFriendTrack->SetTPCOut(*t);
1539 if (flags==kTRDrefit) fFriendTrack->SetTRDIn(*t);
1545 fITSchi2Std[0] = t->GetChi2();
1548 fITSchi2Std[1] = t->GetChi2();
1551 fITSchi2Std[2] = t->GetChi2();
1553 fITSncls=t->GetNumberOfClusters();
1555 Int_t* indexITS = new Int_t[AliESDfriendTrack::kMaxITScluster];
1556 for (Int_t i=0;i<AliESDfriendTrack::kMaxITScluster;i++) {
1557 indexITS[i]=t->GetClusterIndex(i);
1560 Int_t l=(indexITS[i] & 0xf0000000) >> 28;
1561 SETBIT(fITSClusterMap,l);
1564 fFriendTrack->SetITSIndices(indexITS,AliESDfriendTrack::kMaxITScluster);
1568 fITSchi2=t->GetChi2();
1569 fITSsignal=t->GetPIDsignal();
1570 fITSLabel = t->GetLabel();
1571 // keep in fOp the parameters outside ITS for ITS stand-alone tracks
1572 if (flags==kITSout) {
1573 if (!fOp) fOp=new AliExternalTrackParam(*t);
1575 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1580 case kTPCin: case kTPCrefit:
1582 fTPCLabel = t->GetLabel();
1583 if (flags==kTPCin) {
1584 fTPCInner=new AliExternalTrackParam(*t);
1585 fTPCnclsIter1=t->GetNumberOfClusters();
1586 fTPCchi2Iter1=t->GetChi2();
1588 if (!fIp) fIp=new AliExternalTrackParam(*t);
1590 fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1592 // Intentionally no break statement; need to set general TPC variables as well
1595 if (flags & kTPCout){
1596 if (!fOp) fOp=new AliExternalTrackParam(*t);
1598 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1600 fTPCncls=t->GetNumberOfClusters();
1601 fTPCchi2=t->GetChi2();
1603 if (fFriendTrack) { // Copy cluster indices
1604 Int_t* indexTPC = new Int_t[AliESDfriendTrack::kMaxTPCcluster];
1605 for (Int_t i=0;i<AliESDfriendTrack::kMaxTPCcluster;i++)
1606 indexTPC[i]=t->GetClusterIndex(i);
1607 fFriendTrack->SetTPCIndices(indexTPC,AliESDfriendTrack::kMaxTPCcluster);
1610 fTPCsignal=t->GetPIDsignal();
1614 case kTRDin: case kTRDrefit:
1618 fTRDLabel = t->GetLabel();
1619 fTRDchi2 = t->GetChi2();
1620 fTRDncls = t->GetNumberOfClusters();
1622 Int_t* indexTRD = new Int_t[AliESDfriendTrack::kMaxTRDcluster];
1623 for (Int_t i=0;i<AliESDfriendTrack::kMaxTRDcluster;i++) indexTRD[i]=-2;
1624 for (Int_t i=0;i<6;i++) indexTRD[i]=t->GetTrackletIndex(i);
1625 fFriendTrack->SetTRDIndices(indexTRD,AliESDfriendTrack::kMaxTRDcluster);
1629 //commented out by Xianguo
1630 //fTRDsignal=t->GetPIDsignal();
1634 if (!fOp) fOp=new AliExternalTrackParam(*t);
1636 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1637 fTRDncls0 = t->GetNumberOfClusters();
1646 if (!fHMPIDp) fHMPIDp=new AliExternalTrackParam(*t);
1648 fHMPIDp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1651 AliError("Wrong flag !");
1658 //_______________________________________________________________________
1659 void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const {
1660 //---------------------------------------------------------------------
1661 // This function returns external representation of the track parameters
1662 //---------------------------------------------------------------------
1664 for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i];
1667 //_______________________________________________________________________
1668 void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const {
1669 //---------------------------------------------------------------------
1670 // This function returns external representation of the cov. matrix
1671 //---------------------------------------------------------------------
1672 for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i];
1675 //_______________________________________________________________________
1676 Bool_t AliESDtrack::GetConstrainedExternalParameters
1677 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1678 //---------------------------------------------------------------------
1679 // This function returns the constrained external track parameters
1680 //---------------------------------------------------------------------
1681 if (!fCp) return kFALSE;
1682 alpha=fCp->GetAlpha();
1684 for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i];
1688 //_______________________________________________________________________
1690 AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const {
1691 //---------------------------------------------------------------------
1692 // This function returns the constrained external cov. matrix
1693 //---------------------------------------------------------------------
1694 if (!fCp) return kFALSE;
1695 for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i];
1700 AliESDtrack::GetInnerExternalParameters
1701 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1702 //---------------------------------------------------------------------
1703 // This function returns external representation of the track parameters
1704 // at the inner layer of TPC
1705 //---------------------------------------------------------------------
1706 if (!fIp) return kFALSE;
1707 alpha=fIp->GetAlpha();
1709 for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i];
1714 AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const {
1715 //---------------------------------------------------------------------
1716 // This function returns external representation of the cov. matrix
1717 // at the inner layer of TPC
1718 //---------------------------------------------------------------------
1719 if (!fIp) return kFALSE;
1720 for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i];
1725 AliESDtrack::SetOuterParam(const AliExternalTrackParam *p, ULong_t flags) {
1727 // This is a direct setter for the outer track parameters
1730 if (fOp) delete fOp;
1731 fOp=new AliExternalTrackParam(*p);
1735 AliESDtrack::SetOuterHmpParam(const AliExternalTrackParam *p, ULong_t flags) {
1737 // This is a direct setter for the outer track parameters
1740 if (fHMPIDp) delete fHMPIDp;
1741 fHMPIDp=new AliExternalTrackParam(*p);
1745 AliESDtrack::GetOuterExternalParameters
1746 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1747 //---------------------------------------------------------------------
1748 // This function returns external representation of the track parameters
1749 // at the inner layer of TRD
1750 //---------------------------------------------------------------------
1751 if (!fOp) return kFALSE;
1752 alpha=fOp->GetAlpha();
1754 for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i];
1759 AliESDtrack::GetOuterHmpExternalParameters
1760 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1761 //---------------------------------------------------------------------
1762 // This function returns external representation of the track parameters
1763 // at the inner layer of TRD
1764 //---------------------------------------------------------------------
1765 if (!fHMPIDp) return kFALSE;
1766 alpha=fHMPIDp->GetAlpha();
1768 for (Int_t i=0; i<5; i++) p[i]=fHMPIDp->GetParameter()[i];
1773 AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const {
1774 //---------------------------------------------------------------------
1775 // This function returns external representation of the cov. matrix
1776 // at the inner layer of TRD
1777 //---------------------------------------------------------------------
1778 if (!fOp) return kFALSE;
1779 for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i];
1784 AliESDtrack::GetOuterHmpExternalCovariance(Double_t cov[15]) const {
1785 //---------------------------------------------------------------------
1786 // This function returns external representation of the cov. matrix
1787 // at the inner layer of TRD
1788 //---------------------------------------------------------------------
1789 if (!fHMPIDp) return kFALSE;
1790 for (Int_t i=0; i<15; i++) cov[i]=fHMPIDp->GetCovariance()[i];
1794 Int_t AliESDtrack::GetNcls(Int_t idet) const
1796 // Get number of clusters by subdetector index
1810 if (fTOFindex != -1)
1816 if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1817 if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1828 Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
1830 // Get cluster index array by subdetector index
1835 ncls = GetITSclusters(idx);
1838 ncls = GetTPCclusters(idx);
1841 ncls = GetTRDclusters(idx);
1844 if (fTOFindex != -1) {
1852 if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1853 if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1854 idx[0] = GetHMPIDcluIdx();
1867 //_______________________________________________________________________
1868 void AliESDtrack::GetIntegratedTimes(Double_t *times, Int_t nspec) const
1870 // get integrated time for requested N species
1871 if (nspec<1) return;
1872 if(fNtofClusters>0 && GetESDEvent()){
1873 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
1874 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
1876 for(int i=tofcl->GetNMatchableTracks();i--;){
1877 if(tofcl->GetTrackIndex(i) == GetID()) {
1878 for (int j=nspec; j--;) times[j]=tofcl->GetIntegratedTime(j,i);
1883 else if(fNtofClusters>0)
1884 AliInfo("No AliESDEvent available here!\n");
1886 // Returns the array with integrated times for each particle hypothesis
1888 for (int i=nspec; i--;) times[i]=fTrackTime[i];
1890 for (int i=AliPID::kSPECIESC; i--;) times[i]=0.0;
1893 //_______________________________________________________________________
1894 Double_t AliESDtrack::GetIntegratedLength() const{
1896 if(fNtofClusters>0 && GetESDEvent()){
1897 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
1898 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
1900 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
1901 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
1904 if(fNtofClusters>0 && index > -1)
1905 return tofcl->GetLength(index);
1907 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
1909 return fTrackLength;
1912 //_______________________________________________________________________
1913 void AliESDtrack::SetIntegratedTimes(const Double_t *times)
1915 // Sets the array with integrated times for each particle hypotesis
1916 if(!fTrackTime) fTrackTime = new Double32_t[AliPID::kSPECIESC];
1917 for (int i=AliPID::kSPECIESC; i--;) fTrackTime[i]=times[i];
1920 //_______________________________________________________________________
1921 void AliESDtrack::SetITSpid(const Double_t *p)
1923 // Sets values for the probability of each particle type (in ITS)
1924 if (!fITSr) fITSr = new Double32_t[AliPID::kSPECIESC];
1925 SetPIDValues(fITSr,p,AliPID::kSPECIES);
1926 SetStatus(AliESDtrack::kITSpid);
1929 //_______________________________________________________________________
1930 void AliESDtrack::GetITSpid(Double_t *p) const {
1931 // Gets the probability of each particle type (in ITS)
1932 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fITSr ? fITSr[i] : 0;
1935 //_______________________________________________________________________
1936 Char_t AliESDtrack::GetITSclusters(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->GetITSindices();
1942 for (Int_t i=0; i<AliESDfriendTrack::kMaxITScluster; i++) {
1943 if ( (i>=fITSncls) && (i<6) ) idx[i]=-1;
1955 //_______________________________________________________________________
1956 Bool_t AliESDtrack::GetITSModuleIndexInfo(Int_t ilayer,Int_t &idet,Int_t &status,
1957 Float_t &xloc,Float_t &zloc) const {
1958 //----------------------------------------------------------------------
1959 // This function encodes in the module number also the status of cluster association
1960 // "status" can have the following values:
1961 // 1 "found" (cluster is associated),
1962 // 2 "dead" (module is dead from OCDB),
1963 // 3 "skipped" (module or layer forced to be skipped),
1964 // 4 "outinz" (track out of z acceptance),
1965 // 5 "nocls" (no clusters in the road),
1966 // 6 "norefit" (cluster rejected during refit),
1967 // 7 "deadzspd" (holes in z in SPD)
1968 // Also given are the coordinates of the crossing point of track and module
1969 // (in the local module ref. system)
1970 // WARNING: THIS METHOD HAS TO BE SYNCHRONIZED WITH AliITStrackV2::GetModuleIndexInfo()!
1971 //----------------------------------------------------------------------
1973 if(fITSModule[ilayer]==-1) {
1976 xloc=-99.; zloc=-99.;
1980 Int_t module = fITSModule[ilayer];
1982 idet = Int_t(module/1000000);
1984 module -= idet*1000000;
1986 status = Int_t(module/100000);
1988 module -= status*100000;
1990 Int_t signs = Int_t(module/10000);
1992 module-=signs*10000;
1994 Int_t xInt = Int_t(module/100);
1997 Int_t zInt = module;
1999 if(signs==1) { xInt*=1; zInt*=1; }
2000 if(signs==2) { xInt*=1; zInt*=-1; }
2001 if(signs==3) { xInt*=-1; zInt*=1; }
2002 if(signs==4) { xInt*=-1; zInt*=-1; }
2004 xloc = 0.1*(Float_t)xInt;
2005 zloc = 0.1*(Float_t)zInt;
2007 if(status==4) idet = -1;
2012 //_______________________________________________________________________
2013 UShort_t AliESDtrack::GetTPCclusters(Int_t *idx) const {
2014 //---------------------------------------------------------------------
2015 // This function returns indices of the assgined ITS clusters
2016 //---------------------------------------------------------------------
2017 if (idx && fFriendTrack) {
2018 Int_t *index=fFriendTrack->GetTPCindices();
2021 for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=index[i];
2024 for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=-2;
2030 //_______________________________________________________________________
2031 Float_t AliESDtrack::GetTPCCrossedRows() const
2033 // This function calls GetTPCClusterInfo with some default parameters which are used in the track selection and caches the outcome
2034 // because GetTPCClusterInfo is quite time-consuming
2036 if (fCacheNCrossedRows > -1)
2037 return fCacheNCrossedRows;
2039 fCacheNCrossedRows = GetTPCClusterInfo(2, 1);
2040 return fCacheNCrossedRows;
2043 //_______________________________________________________________________
2044 Float_t AliESDtrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
2047 // TPC cluster information
2048 // type 0: get fraction of found/findable clusters with neighbourhood definition
2049 // 1: findable clusters with neighbourhood definition
2050 // 2: found clusters
2052 // 0 - all cluster used
2053 // 1 - clusters used for the kalman update
2054 // definition of findable clusters:
2055 // a cluster is defined as findable if there is another cluster
2056 // within +- nNeighbours pad rows. The idea is to overcome threshold
2057 // effects with a very simple algorithm.
2063 Int_t last=-nNeighbours;
2064 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
2066 Int_t upperBound=clusterMap.GetNbits();
2067 if (upperBound>row1) upperBound=row1;
2068 for (Int_t i=row0; i<upperBound; ++i){
2069 //look to current row
2070 if (clusterMap[i]) {
2076 //look to nNeighbours before
2077 if ((i-last)<=nNeighbours) {
2081 //look to nNeighbours after
2082 for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
2089 if (type==2) return found;
2090 if (type==1) return findable;
2095 fraction=(Float_t)found/(Float_t)findable;
2100 return 0; // undefined type - default value
2103 //_______________________________________________________________________
2104 Float_t AliESDtrack::GetTPCClusterDensity(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
2107 // TPC cluster density - only rows where signal before and after given row are used
2108 // - slower function
2109 // type 0: get fraction of found/findable clusters with neighbourhood definition
2110 // 1: findable clusters with neighbourhood definition
2111 // 2: found clusters
2113 // 0 - all cluster used
2114 // 1 - clusters used for the kalman update
2115 // definition of findable clusters:
2116 // a cluster is defined as findable if there is another cluster
2117 // within +- nNeighbours pad rows. The idea is to overcome threshold
2118 // effects with a very simple algorithm.
2122 // Int_t last=-nNeighbours;
2123 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
2124 Int_t upperBound=clusterMap.GetNbits();
2125 if (upperBound>row1) upperBound=row1;
2126 for (Int_t i=row0; i<upperBound; ++i){
2128 Bool_t isDown=kFALSE;
2129 for (Int_t idelta=1; idelta<=nNeighbours; idelta++){
2130 if (i-idelta>=0 && clusterMap[i-idelta]) isDown=kTRUE;
2131 if (i+idelta<upperBound && clusterMap[i+idelta]) isUp=kTRUE;
2135 if (clusterMap[i]) ++found;
2138 if (type==2) return found;
2139 if (type==1) return findable;
2144 fraction=(Float_t)found/(Float_t)findable;
2149 return 0; // undefined type - default value
2155 //_______________________________________________________________________
2156 Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
2158 // GetDensity of the clusters on given region between row0 and row1
2159 // Dead zone effect takin into acoount
2161 if (!fFriendTrack) return 0.0;
2165 Int_t *index=fFriendTrack->GetTPCindices();
2166 for (Int_t i=row0;i<=row1;i++){
2167 Int_t idx = index[i];
2168 if (idx!=-1) good++; // track outside of dead zone
2171 Float_t density=0.5;
2172 if (good>TMath::Max((row1-row0)*0.5,0.0)) density = Float_t(found)/Float_t(good);
2176 //_______________________________________________________________________
2177 void AliESDtrack::SetTPCpid(const Double_t *p) {
2178 // Sets values for the probability of each particle type (in TPC)
2179 if (!fTPCr) fTPCr = new Double32_t[AliPID::kSPECIES];
2180 SetPIDValues(fTPCr,p,AliPID::kSPECIES);
2181 SetStatus(AliESDtrack::kTPCpid);
2184 //_______________________________________________________________________
2185 void AliESDtrack::GetTPCpid(Double_t *p) const {
2186 // Gets the probability of each particle type (in TPC)
2187 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTPCr ? fTPCr[i] : 0;
2190 //_______________________________________________________________________
2191 UChar_t AliESDtrack::GetTRDclusters(Int_t *idx) const {
2192 //---------------------------------------------------------------------
2193 // This function returns indices of the assgined TRD clusters
2194 //---------------------------------------------------------------------
2195 if (idx && fFriendTrack) {
2196 Int_t *index=fFriendTrack->GetTRDindices();
2199 for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=index[i];
2202 for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=-2;
2208 //_______________________________________________________________________
2209 UChar_t AliESDtrack::GetTRDtracklets(Int_t *idx) const {
2211 // This function returns the number of TRD tracklets used in tracking
2212 // and it fills the indices of these tracklets in the array "idx" as they
2213 // are registered in the TRD track list.
2216 // 1. The idx array has to be allocated with a size >= AliESDtrack::kTRDnPlanes
2217 // 2. The idx array store not only the index but also the layer of the tracklet.
2218 // Therefore tracks with TRD gaps contain default values for indices [-1]
2220 if (!fFriendTrack) return 0;
2221 if (!idx) return GetTRDntracklets();
2222 Int_t *index=fFriendTrack->GetTRDindices();
2224 for (Int_t i=0; i<kTRDnPlanes; i++){
2226 if(index[i]>=0) n++;
2234 //_______________________________________________________________________
2235 void AliESDtrack::SetTRDpid(const Double_t *p) {
2236 // Sets values for the probability of each particle type (in TRD)
2237 if (!fTRDr) fTRDr = new Double32_t[AliPID::kSPECIES];
2238 SetPIDValues(fTRDr,p,AliPID::kSPECIES);
2239 SetStatus(AliESDtrack::kTRDpid);
2242 //_______________________________________________________________________
2243 void AliESDtrack::GetTRDpid(Double_t *p) const {
2244 // Gets the probability of each particle type (in TRD)
2245 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTRDr ? fTRDr[i]:0;
2248 //_______________________________________________________________________
2249 void AliESDtrack::SetTRDpid(Int_t iSpecies, Float_t p)
2251 // Sets the probability of particle type iSpecies to p (in TRD)
2253 fTRDr = new Double32_t[AliPID::kSPECIES];
2254 for (Int_t i=AliPID::kSPECIES; i--;) fTRDr[i] = 0;
2256 fTRDr[iSpecies] = p;
2259 Double_t AliESDtrack::GetTRDpid(Int_t iSpecies) const
2261 // Returns the probability of particle type iSpecies (in TRD)
2262 return fTRDr ? fTRDr[iSpecies] : 0;
2265 //____________________________________________________
2266 Int_t AliESDtrack::GetNumberOfTRDslices() const
2268 // built in backward compatibility
2269 Int_t idx = fTRDnSlices - (kTRDnPlanes<<1);
2270 return idx<18 ? fTRDnSlices/kTRDnPlanes : idx/kTRDnPlanes;
2273 //____________________________________________________
2274 Double_t AliESDtrack::GetTRDmomentum(Int_t plane, Double_t *sp) const
2276 //Returns momentum estimation and optional its error (sp)
2277 // in TRD layer "plane".
2280 AliDebug(2, "No TRD info allocated for this track.");
2283 if ((plane<0) || (plane>=kTRDnPlanes)) {
2284 AliWarning(Form("Request for TRD plane[%d] outside range.", plane));
2288 Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2289 // Protection for backward compatibility
2290 if(idx<(GetNumberOfTRDslices()*kTRDnPlanes)) return -1.;
2292 if(sp) (*sp) = fTRDslices[idx+kTRDnPlanes];
2293 return fTRDslices[idx];
2296 //____________________________________________________
2297 Double_t AliESDtrack::GetTRDslice(Int_t plane, Int_t slice) const {
2298 //Gets the charge from the slice of the plane
2301 //AliError("No TRD slices allocated for this track !");
2304 if ((plane<0) || (plane>=kTRDnPlanes)) {
2305 AliError("Info for TRD plane not available !");
2308 Int_t ns=GetNumberOfTRDslices();
2309 if ((slice<-1) || (slice>=ns)) {
2310 //AliError("Wrong TRD slice !");
2314 if(slice>=0) return fTRDslices[plane*ns + slice];
2316 // return average of the dEdx measurements
2317 Double_t q=0.; Double32_t *s = &fTRDslices[plane*ns];
2318 for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
2322 //____________________________________________________
2323 void AliESDtrack::SetNumberOfTRDslices(Int_t n) {
2324 //Sets the number of slices used for PID
2325 if (fTRDnSlices) return;
2328 fTRDslices=new Double32_t[fTRDnSlices];
2330 // set-up correctly the allocated memory
2331 memset(fTRDslices, 0, n*sizeof(Double32_t));
2332 for (Int_t i=GetNumberOfTRDslices(); i--;) fTRDslices[i]=-1.;
2335 //____________________________________________________
2336 void AliESDtrack::SetTRDslice(Double_t q, Int_t plane, Int_t slice) {
2337 //Sets the charge q in the slice of the plane
2339 AliError("No TRD slices allocated for this track !");
2342 if ((plane<0) || (plane>=kTRDnPlanes)) {
2343 AliError("Info for TRD plane not allocated !");
2346 Int_t ns=GetNumberOfTRDslices();
2347 if ((slice<0) || (slice>=ns)) {
2348 AliError(Form("Wrong TRD slice %d/%d, NSlices=%d",plane,slice,ns));
2351 Int_t n=plane*ns + slice;
2356 //____________________________________________________
2357 void AliESDtrack::SetTRDmomentum(Double_t p, Int_t plane, Double_t *sp)
2360 AliError("No TRD slices allocated for this track !");
2363 if ((plane<0) || (plane>=kTRDnPlanes)) {
2364 AliError("Info for TRD plane not allocated !");
2368 Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2369 // Protection for backward compatibility
2370 if(idx<GetNumberOfTRDslices()*kTRDnPlanes) return;
2372 if(sp) fTRDslices[idx+kTRDnPlanes] = (*sp);
2373 fTRDslices[idx] = p;
2377 //_______________________________________________________________________
2378 void AliESDtrack::SetTOFpid(const Double_t *p) {
2379 // Sets the probability of each particle type (in TOF)
2380 if (!fTOFr) fTOFr = new Double32_t[AliPID::kSPECIES];
2381 SetPIDValues(fTOFr,p,AliPID::kSPECIES);
2382 SetStatus(AliESDtrack::kTOFpid);
2385 //_______________________________________________________________________
2386 void AliESDtrack::SetTOFLabel(const Int_t *p) {
2388 if(fNtofClusters>0){
2389 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
2390 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
2391 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
2393 if(hit) hit->SetTOFLabel(p);
2397 if(!fTOFLabel) fTOFLabel = new Int_t[3];
2398 for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
2402 //_______________________________________________________________________
2403 void AliESDtrack::GetTOFpid(Double_t *p) const {
2404 // Gets probabilities of each particle type (in TOF)
2405 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTOFr ? fTOFr[i]:0;
2408 //_______________________________________________________________________
2409 void AliESDtrack::GetTOFLabel(Int_t *p) const {
2411 if(fNtofClusters>0){
2412 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
2413 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
2415 for (Int_t i=0; i<3; i++) p[i]=tofcl->GetLabel(i);
2418 if(fTOFLabel) for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
2419 else for (int i=3;i--;) p[i] = -1;
2423 //_______________________________________________________________________
2424 void AliESDtrack::GetTOFInfo(Float_t *info) const {
2426 for (Int_t i=0; i<10; i++) info[i]=fTOFInfo[i];
2429 //_______________________________________________________________________
2430 void AliESDtrack::SetTOFInfo(Float_t*info) {
2432 for (Int_t i=0; i<10; i++) fTOFInfo[i]=info[i];
2437 //_______________________________________________________________________
2438 void AliESDtrack::SetHMPIDpid(const Double_t *p) {
2439 // Sets the probability of each particle type (in HMPID)
2440 if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
2441 SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
2442 SetStatus(AliESDtrack::kHMPIDpid);
2445 //_______________________________________________________________________
2446 void AliESDtrack::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo){
2447 if(fTPCdEdxInfo) delete fTPCdEdxInfo;
2448 fTPCdEdxInfo = dEdxInfo;
2451 //_______________________________________________________________________
2452 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
2453 // Gets probabilities of each particle type (in HMPID)
2454 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fHMPIDr ? fHMPIDr[i]:0;
2459 //_______________________________________________________________________
2460 void AliESDtrack::SetESDpid(const Double_t *p) {
2461 // Sets the probability of each particle type for the ESD track
2462 if (!fR) fR = new Double32_t[AliPID::kSPECIES];
2463 SetPIDValues(fR,p,AliPID::kSPECIES);
2464 SetStatus(AliESDtrack::kESDpid);
2467 //_______________________________________________________________________
2468 void AliESDtrack::GetESDpid(Double_t *p) const {
2469 // Gets probability of each particle type for the ESD track
2470 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fR ? fR[i]:0;
2473 //_______________________________________________________________________
2474 Bool_t AliESDtrack::RelateToVertexTPC(const AliESDVertex *vtx,
2475 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2477 // Try to relate the TPC-only track parameters to the vertex "vtx",
2478 // if the (rough) transverse impact parameter is not bigger then "maxd".
2479 // Magnetic field is "b" (kG).
2481 // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2482 // b) The impact parameters and their covariance matrix are calculated.
2483 // c) An attempt to constrain the TPC-only params to the vertex is done.
2484 // The constrained params are returned via "cParam".
2486 // In the case of success, the returned value is kTRUE
2487 // otherwise, it's kFALSE)
2490 if (!fTPCInner) return kFALSE;
2491 if (!vtx) return kFALSE;
2493 Double_t dz[2],cov[3];
2494 if (!fTPCInner->PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2502 Double_t covar[6]; vtx->GetCovMatrix(covar);
2503 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2504 Double_t c[3]={covar[2],0.,covar[5]};
2506 Double_t chi2=GetPredictedChi2(p,c);
2507 if (chi2>kVeryBig) return kFALSE;
2511 if (!cParam) return kTRUE;
2513 *cParam = *fTPCInner;
2514 if (!cParam->Update(p,c)) return kFALSE;
2519 //_______________________________________________________________________
2520 Bool_t AliESDtrack::RelateToVertexTPCBxByBz(const AliESDVertex *vtx,
2521 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2523 // Try to relate the TPC-only track parameters to the vertex "vtx",
2524 // if the (rough) transverse impact parameter is not bigger then "maxd".
2526 // All three components of the magnetic field ,"b[3]" (kG),
2527 // are taken into account.
2529 // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2530 // b) The impact parameters and their covariance matrix are calculated.
2531 // c) An attempt to constrain the TPC-only params to the vertex is done.
2532 // The constrained params are returned via "cParam".
2534 // In the case of success, the returned value is kTRUE
2535 // otherwise, it's kFALSE)
2538 if (!fTPCInner) return kFALSE;
2539 if (!vtx) return kFALSE;
2541 Double_t dz[2],cov[3];
2542 if (!fTPCInner->PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2550 Double_t covar[6]; vtx->GetCovMatrix(covar);
2551 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2552 Double_t c[3]={covar[2],0.,covar[5]};
2554 Double_t chi2=GetPredictedChi2(p,c);
2555 if (chi2>kVeryBig) return kFALSE;
2559 if (!cParam) return kTRUE;
2561 *cParam = *fTPCInner;
2562 if (!cParam->Update(p,c)) return kFALSE;
2567 //_______________________________________________________________________
2568 Bool_t AliESDtrack::RelateToVertex(const AliESDVertex *vtx,
2569 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2571 // Try to relate this track to the vertex "vtx",
2572 // if the (rough) transverse impact parameter is not bigger then "maxd".
2573 // Magnetic field is "b" (kG).
2575 // a) The track gets extapolated to the DCA to the vertex.
2576 // b) The impact parameters and their covariance matrix are calculated.
2577 // c) An attempt to constrain this track to the vertex is done.
2578 // The constrained params are returned via "cParam".
2580 // In the case of success, the returned value is kTRUE
2581 // (otherwise, it's kFALSE)
2584 if (!vtx) return kFALSE;
2586 Double_t dz[2],cov[3];
2587 if (!PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2595 Double_t covar[6]; vtx->GetCovMatrix(covar);
2596 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2597 Double_t c[3]={covar[2],0.,covar[5]};
2599 Double_t chi2=GetPredictedChi2(p,c);
2600 if (chi2>kVeryBig) return kFALSE;
2605 //--- Could now these lines be removed ? ---
2607 fCp=new AliExternalTrackParam(*this);
2609 if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2610 //----------------------------------------
2612 fVertexID = vtx->GetID();
2614 if (!cParam) return kTRUE;
2617 if (!cParam->Update(p,c)) return kFALSE;
2622 //_______________________________________________________________________
2623 Bool_t AliESDtrack::RelateToVertexBxByBz(const AliESDVertex *vtx,
2624 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2626 // Try to relate this track to the vertex "vtx",
2627 // if the (rough) transverse impact parameter is not bigger then "maxd".
2628 // Magnetic field is "b" (kG).
2630 // a) The track gets extapolated to the DCA to the vertex.
2631 // b) The impact parameters and their covariance matrix are calculated.
2632 // c) An attempt to constrain this track to the vertex is done.
2633 // The constrained params are returned via "cParam".
2635 // In the case of success, the returned value is kTRUE
2636 // (otherwise, it's kFALSE)
2639 if (!vtx) return kFALSE;
2641 Double_t dz[2],cov[3];
2642 if (!PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2650 Double_t covar[6]; vtx->GetCovMatrix(covar);
2651 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2652 Double_t c[3]={covar[2],0.,covar[5]};
2654 Double_t chi2=GetPredictedChi2(p,c);
2655 if (chi2>kVeryBig) return kFALSE;
2660 //--- Could now these lines be removed ? ---
2662 fCp=new AliExternalTrackParam(*this);
2664 if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2665 //----------------------------------------
2667 fVertexID = vtx->GetID();
2669 if (!cParam) return kTRUE;
2672 if (!cParam->Update(p,c)) return kFALSE;
2677 //_______________________________________________________________________
2678 void AliESDtrack::Print(Option_t *) const {
2679 // Prints info on the track
2680 AliExternalTrackParam::Print();
2681 printf("ESD track info\n") ;
2682 Double_t p[AliPID::kSPECIES] ;
2684 if( IsOn(kITSpid) ){
2685 printf("From ITS: ") ;
2687 for(index = 0 ; index < AliPID::kSPECIES; index++)
2688 printf("%f, ", p[index]) ;
2689 printf("\n signal = %f\n", GetITSsignal()) ;
2691 if( IsOn(kTPCpid) ){
2692 printf("From TPC: ") ;
2694 for(index = 0 ; index < AliPID::kSPECIES; index++)
2695 printf("%f, ", p[index]) ;
2696 printf("\n signal = %f\n", GetTPCsignal()) ;
2698 if( IsOn(kTRDpid) ){
2699 printf("From TRD: ") ;
2701 for(index = 0 ; index < AliPID::kSPECIES; index++)
2702 printf("%f, ", p[index]) ;
2703 printf("\n signal = %f\n", GetTRDsignal()) ;
2704 printf("\n NchamberdEdx = %d\n", GetTRDNchamberdEdx()) ;
2705 printf("\n NclusterdEdx = %d\n", GetTRDNclusterdEdx()) ;
2707 if( IsOn(kTOFpid) ){
2708 printf("From TOF: ") ;
2710 for(index = 0 ; index < AliPID::kSPECIES; index++)
2711 printf("%f, ", p[index]) ;
2712 printf("\n signal = %f\n", GetTOFsignal()) ;
2714 if( IsOn(kHMPIDpid) ){
2715 printf("From HMPID: ") ;
2717 for(index = 0 ; index < AliPID::kSPECIES; index++)
2718 printf("%f, ", p[index]) ;
2719 printf("\n signal = %f\n", GetHMPIDsignal()) ;
2725 // Draw functionality
2726 // Origin: Marian Ivanov, Marian.Ivanov@cern.ch
2728 void AliESDtrack::FillPolymarker(TPolyMarker3D *pol, Float_t magF, Float_t minR, Float_t maxR, Float_t stepR){
2730 // Fill points in the polymarker
2733 arrayRef.AddLast(new AliExternalTrackParam(*this));
2734 if (fIp) arrayRef.AddLast(new AliExternalTrackParam(*fIp));
2735 if (fOp) arrayRef.AddLast(new AliExternalTrackParam(*fOp));
2736 if (fHMPIDp) arrayRef.AddLast(new AliExternalTrackParam(*fHMPIDp));
2738 Double_t mpos[3]={0,0,0};
2739 Int_t entries=arrayRef.GetEntries();
2740 for (Int_t i=0;i<entries;i++){
2742 ((AliExternalTrackParam*)arrayRef.At(i))->GetXYZ(pos);
2743 mpos[0]+=pos[0]/entries;
2744 mpos[1]+=pos[1]/entries;
2745 mpos[2]+=pos[2]/entries;
2747 // Rotate to the mean position
2749 Float_t fi= TMath::ATan2(mpos[1],mpos[0]);
2750 for (Int_t i=0;i<entries;i++){
2751 Bool_t res = ((AliExternalTrackParam*)arrayRef.At(i))->Rotate(fi);
2752 if (!res) delete arrayRef.RemoveAt(i);
2755 for (Double_t r=minR; r<maxR; r+=stepR){
2757 Double_t mlpos[3]={0,0,0};
2758 for (Int_t i=0;i<entries;i++){
2759 Double_t point[3]={0,0,0};
2760 AliExternalTrackParam *param = ((AliExternalTrackParam*)arrayRef.At(i));
2761 if (!param) continue;
2762 if (param->GetXYZAt(r,magF,point)){
2763 Double_t weight = 1./(10.+(r-param->GetX())*(r-param->GetX()));
2765 mlpos[0]+=point[0]*weight;
2766 mlpos[1]+=point[1]*weight;
2767 mlpos[2]+=point[2]*weight;
2774 pol->SetPoint(counter,mlpos[0],mlpos[1], mlpos[2]);
2775 // printf("xyz\t%f\t%f\t%f\n",mlpos[0], mlpos[1],mlpos[2]);
2781 //_______________________________________________________________________
2782 void AliESDtrack::SetITSdEdxSamples(const Double_t s[4]) {
2784 // Store the dE/dx samples measured by the two SSD and two SDD layers.
2785 // These samples are corrected for the track segment length.
2787 for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
2790 //_______________________________________________________________________
2791 void AliESDtrack::GetITSdEdxSamples(Double_t s[4]) const {
2793 // Get the dE/dx samples measured by the two SSD and two SDD layers.
2794 // These samples are corrected for the track segment length.
2796 for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
2800 UShort_t AliESDtrack::GetTPCnclsS(Int_t i0,Int_t i1) const{
2802 // get number of shared TPC clusters
2804 return fTPCSharedMap.CountBits(i0)-fTPCSharedMap.CountBits(i1);
2807 UShort_t AliESDtrack::GetTPCncls(Int_t i0,Int_t i1) const{
2809 // get number of TPC clusters
2811 return fTPCClusterMap.CountBits(i0)-fTPCClusterMap.CountBits(i1);
2814 //____________________________________________________________________
2815 Double_t AliESDtrack::GetChi2TPCConstrainedVsGlobal(const AliESDVertex* vtx) const
2817 // Calculates the chi2 between the TPC track (TPCinner) constrained to the primary vertex and the global track
2819 // Returns -1 in case the calculation failed
2821 // Value is cached as a non-persistent member.
2823 // Code adapted from original code by GSI group (Jacek, Marian, Michael)
2825 // cache, ignoring that a different vertex might be passed
2826 if (fCacheChi2TPCConstrainedVsGlobalVertex == vtx)
2827 return fCacheChi2TPCConstrainedVsGlobal;
2829 fCacheChi2TPCConstrainedVsGlobal = -1;
2830 fCacheChi2TPCConstrainedVsGlobalVertex = vtx;
2835 AliTrackerBase::GetBxByBz(x,b);
2838 AliWarning("Could not get TPC Inner Param.");
2839 return fCacheChi2TPCConstrainedVsGlobal;
2842 // clone for constraining
2843 AliExternalTrackParam* tpcInnerC = new AliExternalTrackParam(*fTPCInner);
2845 AliWarning("Clone of TPCInnerParam failed.");
2846 return fCacheChi2TPCConstrainedVsGlobal;
2849 // transform to the track reference frame
2850 Bool_t isOK = tpcInnerC->Rotate(GetAlpha());
2851 isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2855 AliWarning("Rotation/Propagation of track failed.") ;
2856 return fCacheChi2TPCConstrainedVsGlobal;
2859 // constrain TPCinner
2860 isOK = tpcInnerC->ConstrainToVertex(vtx, b);
2862 // transform to the track reference frame
2863 isOK &= tpcInnerC->Rotate(GetAlpha());
2864 isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2867 AliWarning("ConstrainTPCInner failed.") ;
2870 return fCacheChi2TPCConstrainedVsGlobal;
2873 // calculate chi2 between vi and vj vectors
2874 // with covi and covj covariance matrices
2875 // chi2ij = (vi-vj)^(T)*(covi+covj)^(-1)*(vi-vj)
2876 TMatrixD deltaT(5,1);
2877 TMatrixD delta(1,5);
2878 TMatrixD covarM(5,5);
2880 for (Int_t ipar=0; ipar<5; ipar++) {
2881 deltaT(ipar,0) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2882 delta(0,ipar) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2884 for (Int_t jpar=0; jpar<5; jpar++) {
2885 Int_t index = GetIndex(ipar,jpar);
2886 covarM(ipar,jpar) = GetCovariance()[index]+tpcInnerC->GetCovariance()[index];
2889 // chi2 distance TPC constrained and TPC+ITS
2890 TMatrixD covarMInv = covarM.Invert();
2891 TMatrixD mat2 = covarMInv*deltaT;
2892 TMatrixD chi2 = delta*mat2;
2897 fCacheChi2TPCConstrainedVsGlobal = chi2(0,0);
2898 return fCacheChi2TPCConstrainedVsGlobal;
2901 void AliESDtrack::SetDetectorPID(const AliDetectorPID *pid)
2904 // Set the detector PID
2906 if (fDetectorPID) delete fDetectorPID;
2911 Double_t AliESDtrack::GetLengthInActiveZone( Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
2913 // Input parameters:
2914 // mode - type of external track parameters
2915 // deltaY - user defined "dead region" in cm
2916 // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2917 // bz - magnetic field
2918 // exbPhi - optional rotation due to the ExB effect
2920 // the length of the track in cm in "active volume" of the TPC
2922 if (mode==0) return GetLengthInActiveZone(this, deltaY,deltaZ,bz, exbPhi,pcstream);
2923 if (mode==1) return GetLengthInActiveZone(fIp, deltaY,deltaZ,bz, exbPhi,pcstream);
2924 if (mode==2) return GetLengthInActiveZone(fOp, deltaY,deltaZ,bz, exbPhi,pcstream);
2928 Double_t AliESDtrack::GetLengthInActiveZone(const AliExternalTrackParam *paramT, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) {
2930 // Numerical code to calculate the length of the track in active region of the TPC
2931 // ( can be speed up if somebody wants to invest time - analysical version shoult be possible)
2933 // Input parameters:
2934 // paramT - external track parameters
2935 // deltaY - user defined "dead region" in cm
2936 // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2937 // bz - magnetic field
2938 // exbPhi - optional rotation due to the ExB effect
2940 // the length of the track in cm in "active volume" of the TPC
2942 const Double_t rIn=85;
2943 const Double_t rOut=245;
2944 Double_t xyz[3], pxyz[3];
2945 if (paramT->GetXYZAt(rIn,bz,xyz)){
2946 paramT->GetPxPyPzAt(rIn,bz,pxyz);
2948 paramT->GetXYZ(xyz);
2949 paramT->GetPxPyPz(pxyz);
2952 Double_t dca = -paramT->GetD(0,0,bz); // get impact parameter distance to point (0,0)
2953 Double_t radius= TMath::Abs(1/paramT->GetC(bz)); //
2954 Double_t sign = paramT->GetSign();
2955 Double_t R0 = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); // radius at current point
2956 Double_t phiR0 = TMath::ATan2(xyz[1],xyz[0]); // angle of given point
2957 Double_t dPhiR0= -TMath::ASin((dca*dca-2*dca*radius*sign+R0*R0)/(2*R0*(dca-radius*sign)));
2958 Double_t phi0 = phiR0-(dPhiR0); // global phi offset to be added
2961 AliExternalTrackParam paramR=(*paramT);
2963 for (Double_t R=rIn; R<=rOut; R++){
2964 Double_t sinPhi=(dca*dca-2*dca*radius*sign+R*R)/(2*R*(dca-radius*sign));
2965 if (TMath::Abs(sinPhi)>=1) continue;
2966 Double_t dphi = -TMath::ASin(sinPhi);
2967 Double_t phi = phi0+dphi; // global phi
2968 Int_t sector = TMath::Nint(9*phi/(TMath::Pi()));
2969 Double_t dPhiEdge = phi-(sector*TMath::Pi()/9)+exbPhi; // distance to sector boundary in rphi
2970 Double_t dX = R*TMath::Cos(phi)-xyz[0];
2971 Double_t dY = R*TMath::Sin(phi)-xyz[1];
2972 Double_t deltaPhi = 2*TMath::ASin(0.5*TMath::Sqrt(dX*dX+dY*dY)/radius);
2973 Double_t z = xyz[2]+deltaPhi*radius*paramT->GetTgl();
2974 if (TMath::Abs(dPhiEdge*R)>deltaY && TMath::Abs(z)<deltaZ){
2977 // Double_t deltaZ= dphi*radius;
2979 //should we keep debug possibility ?
2980 AliExternalTrackParam paramTcopy=(*paramT);
2982 paramR.PropagateTo(R,bz);
2983 (*pcstream)<<"debugEdge"<<
2985 "dphiEdge="<<dPhiEdge<< // distance to edge
2986 "phi0="<<phi0<< // phi0 -phi at the track initial position
2989 "pT.="<<¶mTcopy<<
2997 Double_t AliESDtrack::GetMassForTracking() const
2999 int pid = fPIDForTracking;
3000 if (pid<AliPID::kPion) pid = AliPID::kPion;
3001 double m = AliPID::ParticleMass(pid);
3002 return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
3006 void AliESDtrack::SetTOFclusterArray(Int_t /*ncluster*/,Int_t */*TOFcluster*/){
3007 AliInfo("Method has to be implemented!");
3008 // fNtofClusters=ncluster;
3009 // if(TOFcluster == fTOFcluster) return;
3010 // if(fTOFcluster){ // reset previous content
3011 // delete[] fTOFcluster;
3012 // fTOFcluster = NULL;
3016 // if(ncluster){ // set new content
3017 // fTOFcluster = new Int_t[fNtofClusters];
3018 // for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = TOFcluster[i];
3024 //____________________________________________
3025 void AliESDtrack::SuppressTOFMatches()
3027 // remove reference to this track from TOF clusters
3028 if (!fNtofClusters || !GetESDEvent()) return;
3029 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3030 for (;fNtofClusters--;) {
3031 AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[fNtofClusters]);
3032 clTOF->SuppressMatchedTrack(GetID());
3033 if (!clTOF->GetNMatchableTracks()) { // remove this cluster
3034 int last = tofclArray->GetEntriesFast()-1;
3035 AliESDTOFCluster* clTOFL = (AliESDTOFCluster*)tofclArray->At(last);
3036 if (last != fTOFcluster[fNtofClusters]) {
3037 *clTOF = *clTOFL; // move last cluster to the place of eliminated one
3038 // fix the references on this cluster
3039 clTOF->FixSelfReferences(last,fTOFcluster[fNtofClusters]);
3041 tofclArray->RemoveAt(last);
3046 //____________________________________________
3047 void AliESDtrack::ReplaceTOFTrackID(int oldID, int newID)
3049 // replace the ID in TOF clusters references to this track
3050 if (!fNtofClusters || !GetESDEvent()) return;
3051 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3052 for (int it=fNtofClusters;it--;) {
3053 AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
3054 clTOF->ReplaceMatchedTrackID(oldID,newID);
3058 //____________________________________________
3059 void AliESDtrack::ReplaceTOFClusterID(int oldID, int newID)
3061 // replace the referenc on TOF cluster oldID by newID
3062 if (!fNtofClusters || !GetESDEvent()) return;
3063 for (int it=fNtofClusters;it--;) {
3064 if (fTOFcluster[it] == oldID) {
3065 fTOFcluster[it] = newID;
3071 //____________________________________________
3072 void AliESDtrack::ReplaceTOFMatchID(int oldID, int newID)
3074 // replace in the ESDTOFCluster associated with this track the id of the corresponding
3075 // ESDTOFMatch from oldID to newID
3076 if (!fNtofClusters || !GetESDEvent()) return;
3077 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3078 for (int it=fNtofClusters;it--;) {
3079 AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
3080 clTOF->ReplaceMatchID(oldID,newID);
3084 //____________________________________________
3085 void AliESDtrack::AddTOFcluster(Int_t icl)
3089 Int_t *old = fTOFcluster;
3090 fTOFcluster = new Int_t[fNtofClusters];
3092 for(Int_t i=0;i < fNtofClusters-1;i++) fTOFcluster[i] = old[i];
3093 fTOFcluster[fNtofClusters-1] = icl;
3095 if(fNtofClusters-1) delete[] old; // delete previous content
3099 //____________________________________________
3100 void AliESDtrack::SetTOFsignal(Double_t tof)
3102 if(fNtofClusters>0 && GetESDEvent()){
3103 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3104 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3105 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3106 if(hit) hit->SetTime(tof);
3109 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3113 //____________________________________________
3114 void AliESDtrack::SetTOFCalChannel(Int_t index){
3115 if(fNtofClusters>0 && GetESDEvent()){
3116 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3117 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3118 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3119 if(hit) hit->SetTOFchannel(index);
3122 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3123 fTOFCalChannel=index;
3126 //____________________________________________
3127 void AliESDtrack::SetTOFsignalToT(Double_t ToT){
3128 if(fNtofClusters>0 && GetESDEvent()){
3129 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3130 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3131 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3132 if(hit) hit->SetTOT(ToT);
3135 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3139 //____________________________________________
3140 void AliESDtrack::SetTOFsignalRaw(Double_t tof){
3141 if(fNtofClusters>0 && GetESDEvent()){
3142 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3143 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3144 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3145 if(hit) hit->SetTimeRaw(tof);
3148 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3152 //____________________________________________
3153 void AliESDtrack::SetTOFsignalDz(Double_t dz){
3155 AliESDTOFCluster *tofcl;
3157 if(fNtofClusters>0 && GetESDEvent()){
3158 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3159 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3161 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3162 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3167 AliESDTOFMatch* match = tofcl->GetTOFMatch(index);
3173 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3179 //____________________________________________
3180 void AliESDtrack::SetTOFsignalDx(Double_t dx){
3182 AliESDTOFCluster *tofcl;
3184 if(fNtofClusters>0 && GetESDEvent()){
3185 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3186 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3188 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3189 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3194 AliESDTOFMatch* match = tofcl->GetTOFMatch(index);
3200 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3204 //____________________________________________
3205 void AliESDtrack::SetTOFDeltaBC(Short_t deltaBC){
3206 if(fNtofClusters>0 && GetESDEvent()){
3207 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3208 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3209 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3210 if(hit) hit->SetDeltaBC(deltaBC);
3213 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3214 fTOFdeltaBC=deltaBC;
3217 //____________________________________________
3218 void AliESDtrack::SetTOFL0L1(Short_t l0l1){
3219 if(fNtofClusters>0 && GetESDEvent()){
3220 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3221 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3222 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3223 if(hit) hit->SetL0L1Latency(l0l1);
3226 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3230 //____________________________________________
3231 Double_t AliESDtrack::GetTOFsignal() const
3233 if(fNtofClusters>0 && GetESDEvent()){
3234 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3235 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3237 return tofcl->GetTime();
3239 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3244 //____________________________________________
3245 Double_t AliESDtrack::GetTOFsignalToT() const
3247 if(fNtofClusters>0 && GetESDEvent()){
3248 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3249 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3251 return tofcl->GetTOT();
3253 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3255 return fTOFsignalToT;
3258 //____________________________________________
3259 Double_t AliESDtrack::GetTOFsignalRaw() const
3261 if(fNtofClusters>0 && GetESDEvent()){
3262 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3263 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3265 return tofcl->GetTimeRaw();
3267 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3269 return fTOFsignalRaw;
3272 //____________________________________________
3273 Double_t AliESDtrack::GetTOFsignalDz() const
3276 AliESDTOFCluster *tofcl;
3279 if(fNtofClusters>0 && GetESDEvent()){
3280 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3281 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3283 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3284 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3287 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3289 if(fNtofClusters>0 && index > -1){
3290 return tofcl->GetDz(index);
3292 return fTOFsignalDz;
3295 //____________________________________________
3296 Double_t AliESDtrack::GetTOFsignalDx() const
3298 AliESDTOFCluster *tofcl;
3301 if(fNtofClusters>0 && GetESDEvent()){
3302 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3303 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3304 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3305 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3308 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3309 if(fNtofClusters>0 && index > -1){
3310 return tofcl->GetDx(index);
3312 return fTOFsignalDx;
3315 //____________________________________________
3316 Short_t AliESDtrack::GetTOFDeltaBC() const
3318 if(fNtofClusters>0 && GetESDEvent()){
3319 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3320 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3321 return tofcl->GetDeltaBC();
3323 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3328 //____________________________________________
3329 Short_t AliESDtrack::GetTOFL0L1() const
3331 if(fNtofClusters>0 && GetESDEvent()){
3332 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3333 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3335 return tofcl->GetL0L1Latency();
3337 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3342 //____________________________________________
3343 Int_t AliESDtrack::GetTOFCalChannel() const
3345 if(fNtofClusters>0 && GetESDEvent()){
3346 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3347 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3349 return tofcl->GetTOFchannel();
3351 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3353 return fTOFCalChannel;
3356 //____________________________________________
3357 Int_t AliESDtrack::GetTOFcluster() const
3359 if(fNtofClusters>0 && GetESDEvent()){
3360 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3361 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3363 return tofcl->GetClusterIndex();
3365 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3370 //____________________________________________
3371 Int_t AliESDtrack::GetTOFclusterN() const
3373 return fNtofClusters;
3376 //____________________________________________
3377 Bool_t AliESDtrack::IsTOFHitAlreadyMatched() const{
3378 if(fNtofClusters>0 && GetESDEvent()){
3379 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3380 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3382 if (tofcl->GetNMatchableTracks() > 1)
3385 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3390 //____________________________________________
3391 void AliESDtrack::ReMapTOFcluster(Int_t ncl,Int_t *mapping){
3392 for(Int_t i=0;i<fNtofClusters;i++){
3393 if(fTOFcluster[i]<ncl && fTOFcluster[i]>-1)
3394 fTOFcluster[i] = mapping[fTOFcluster[i]];
3396 AliInfo(Form("TOF cluster re-mapping in AliESDtrack: out of range (%i > %i)\n",fTOFcluster[i],ncl));
3400 //____________________________________________
3401 void AliESDtrack::SortTOFcluster(){
3402 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3404 for(Int_t i=0;i<fNtofClusters-1;i++){
3405 for(Int_t j=i+1;j<fNtofClusters;j++){
3406 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[i]);
3408 for(Int_t it=0;it < tofcl->GetNMatchableTracks();it++){
3409 if(tofcl->GetTrackIndex(it) == GetID()) index1 = it;
3411 Double_t timedist1 = 10000;
3412 for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3413 Double_t timec = TMath::Abs(tofcl->GetTime() - tofcl->GetIntegratedTime(isp));
3414 if(timec < timedist1) timedist1 = timec;
3416 timedist1 *= 0.03; // in cm
3417 Double_t radius1 = tofcl->GetDx(index1)*tofcl->GetDx(index1) + tofcl->GetDz(index1)*tofcl->GetDz(index1) + timedist1*timedist1;
3419 AliESDTOFCluster *tofcl2 = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[j]);
3421 for(Int_t it=0;it < tofcl2->GetNMatchableTracks();it++){
3422 if(tofcl2->GetTrackIndex(it) == GetID()) index2 = it;
3424 if(index1 == -1 || index2 == -1){
3426 Double_t timedist2 = 10000;
3427 for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3428 Double_t timec = TMath::Abs(tofcl2->GetTime() - tofcl2->GetIntegratedTime(isp));
3429 if(timec < timedist2) timedist2 = timec;
3431 timedist2 *= 0.03; // in cm
3432 Double_t radius2 = tofcl2->GetDx(index2)*tofcl2->GetDx(index2) + tofcl2->GetDz(index2)*tofcl2->GetDz(index2) + timedist2*timedist2;
3434 if(radius2 < radius1){
3435 Int_t change = fTOFcluster[i];
3436 fTOFcluster[i] = fTOFcluster[j];
3437 fTOFcluster[j] = change;
3443 //____________________________________________
3444 const AliTOFHeader* AliESDtrack::GetTOFHeader() const {
3445 return fESDEvent->GetTOFHeader();
3448 //___________________________________________
3449 void AliESDtrack::SetID(Short_t id)
3451 // set track ID taking care about dependencies
3452 if (fNtofClusters) ReplaceTOFTrackID(fID,id);
3457 Double_t AliESDtrack::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t qID, Int_t valueID){
3459 // Interface to get the calibrated dEdx information
3460 // For details of arguments and return values see
3461 // AliTPCdEdxInfo::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t valueID)
3463 if (!fTPCdEdxInfo) return 0;
3465 return fTPCdEdxInfo->GetdEdxInfo(fIp, regionID, calibID, qID, valueID);
3469 Double_t AliESDtrack::GetdEdxInfoTRD(Int_t method, Double_t p0, Double_t p1, Double_t p2){
3481 Int_t nSlicesPerLayer=GetNumberOfTRDslices();
3482 Int_t nSlicesAll=GetNumberOfTRDslices()*kTRDnPlanes;
3487 for (Int_t ibin=0; ibin<nSlicesAll; ibin++){
3488 if (fTRDslices[ibin]<=0) continue;
3490 if (method==0) sumAmp+=fTRDslices[ibin];
3491 if (method==1) sumAmp+=TMath::Log(TMath::Abs(fTRDslices[ibin])+p0);
3492 if (method==2) sumAmp+=1/TMath::Sqrt(TMath::Abs(fTRDslices[ibin])+p0);
3493 if (method==3) sumAmp+=TMath::Power(TMath::Abs(fTRDslices[ibin])+p0,p1);
3495 if (sumW==0) return 0;
3496 Double_t dEdx=sumAmp/sumW;
3497 if (method==1) dEdx= TMath::Exp(dEdx);
3498 if (method==2) dEdx= 1/(dEdx*dEdx);
3499 if (method==3) dEdx= TMath::Power(dEdx,1/p1);
3505 for (Int_t ibin=0; ibin<nSlicesAll; ibin++){
3506 if (fTRDslices[ibin]<=0) continue;
3507 Double_t time=(ibin%nSlicesPerLayer);
3508 Double_t weight=fTRDslices[ibin];
3509 if (method==5) weight=TMath::Log((weight+p0)/p0);
3510 if (method==6) weight=TMath::Power(weight+p0,p1);
3514 if (sumW<=0) return 0;
3515 Double_t meanTime=sumWT/sumW;