]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDtrack.cxx
Update of the TOF code, see the presentation at
[u/mrichter/AliRoot.git] / STEER / ESD / AliESDtrack.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 //-----------------------------------------------------------------
16 //           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
21 //
22 //
23 //
24 //  What do you need to know before starting analysis
25 //  (by Marian Ivanov: marian.ivanov@cern.ch)
26 //
27 //
28 //   AliESDtrack:
29 //   1.  What is the AliESDtrack
30 //   2.  What informations do we store
31 //   3.  How to use the information for analysis
32 //   
33 //
34 //   1.AliESDtrack is the container of the information about the track/particle
35 //     reconstructed during Barrel Tracking.
36 //     The track information is propagated from one tracking detector to 
37 //     other using the functionality of AliESDtrack - Current parameters.  
38 //
39 //     No global fit model is used.
40 //     Barrel tracking use Kalman filtering technique, it gives optimal local 
41 //     track parameters at given point under certian assumptions.
42 //             
43 //     Kalman filter take into account additional effect which are 
44 //     difficult to handle using global fit.
45 //     Effects:
46 //        a.) Multiple scattering
47 //        b.) Energy loss
48 //        c.) Non homogenous magnetic field
49 //
50 //     In general case, following barrel detectors are contributing to 
51 //     the Kalman track information:
52 //         a. TPC
53 //         b. ITS
54 //         c. TRD
55 //
56 //      In general 3 reconstruction itteration are performed:
57 //         1. Find tracks   - sequence TPC->ITS
58 //         2. PropagateBack - sequence ITS->TPC->TRD -> Outer PID detectors
59 //         3. Refit invward - sequence TRD->TPC->ITS
60 //      The current tracks are updated after each detector (see bellow).
61 //      In specical cases a track  sanpshots are stored.   
62 // 
63 //
64 //      For some type of analysis (+visualization) track local parameters at 
65 //      different position are neccesary. A snapshots during the track 
66 //      propagation are created.
67 //      (See AliExternalTrackParam class for desctiption of variables and 
68 //      functionality)
69 //      Snapshots:
70 //      a. Current parameters - class itself (AliExternalTrackParam)
71 //         Contributors: general case TRD->TPC->ITS
72 //         Preferable usage:  Decission  - primary or secondary track
73 //         NOTICE - By default the track parameters are stored at the DCA point
74 //                  to the primary vertex. optimal for primary tracks, 
75 //                  far from optimal for secondary tracks.
76 //      b. Constrained parameters - Kalman information updated with 
77 //         the Primary vertex information 
78 //         Contributors: general case TRD->TPC->ITS
79 //         Preferable usage: Use only for tracks selected as primary
80 //         NOTICE - not real constrain - taken as additional measurement 
81 //         with corresponding error
82 //         Function:  
83 //       const AliExternalTrackParam *GetConstrainedParam() const {return fCp;}
84 //      c. Inner parameters -  Track parameters at inner wall of the TPC 
85 //         Contributors: general case TRD->TPC
86 //         function:
87 //           const AliExternalTrackParam *GetInnerParam() const { return fIp;}
88 //
89 //      d. TPCinnerparam  - contributors - TPC only
90 //         Contributors:  TPC
91 //         Preferable usage: Requested for HBT study 
92 //                         (smaller correlations as using also ITS information)
93 //         NOTICE - the track parameters are propagated to the DCA to  
94 //         to primary vertex
95 //         Optimal for primary, far from optimal for secondary tracks
96 //         Function:
97 //    const AliExternalTrackParam *GetTPCInnerParam() const {return fTPCInner;}
98 //     
99 //      e. Outer parameters - 
100 //           Contributors-  general case - ITS-> TPC -> TRD
101 //           The last point - Outer parameters radius is determined
102 //           e.a) Local inclination angle bigger than threshold - 
103 //                Low momenta tracks 
104 //           e.a) Catastrofic energy losss in material
105 //           e.b) Not further improvement (no space points)
106 //           Usage:             
107 //              a.) Tracking: Starting parameter for Refit inward 
108 //              b.) Visualization
109 //              c.) QA
110 //         NOTICE: Should be not used for the physic analysis
111 //         Function:
112 //            const AliExternalTrackParam *GetOuterParam() const { return fOp;}
113 //
114 //-----------------------------------------------------------------
115
116 #include <TMath.h>
117 #include <TParticle.h>
118 #include <TDatabasePDG.h>
119 #include <TMatrixD.h>
120
121 #include "AliESDVertex.h"
122 #include "AliESDtrack.h"
123 #include "AliESDEvent.h"
124 #include "AliKalmanTrack.h"
125 #include "AliVTrack.h"
126 #include "AliLog.h"
127 #include "AliTrackPointArray.h"
128 #include "TPolyMarker3D.h"
129 #include "AliTrackerBase.h"
130 #include "AliTPCdEdxInfo.h"
131 #include "AliDetectorPID.h"
132 #include "TTreeStream.h"
133 #include "TObjArray.h"
134
135 ClassImp(AliESDtrack)
136
137 void SetPIDValues(Double_t * dest, const Double_t * src, Int_t n) {
138   // This function copies "n" PID weights from "scr" to "dest"
139   // and normalizes their sum to 1 thus producing conditional probabilities.
140   // The negative weights are set to 0.
141   // In case all the weights are non-positive they are replaced by
142   // uniform probabilities
143
144   if (n<=0) return;
145
146   Float_t uniform = 1./(Float_t)n;
147
148   Float_t sum = 0;
149   for (Int_t i=0; i<n; i++) 
150     if (src[i]>=0) {
151       sum+=src[i];
152       dest[i] = src[i];
153     }
154     else {
155       dest[i] = 0;
156     }
157
158   if(sum>0)
159     for (Int_t i=0; i<n; i++) dest[i] /= sum;
160   else
161     for (Int_t i=0; i<n; i++) dest[i] = uniform;
162 }
163
164 //_______________________________________________________________________
165 AliESDtrack::AliESDtrack() : 
166   AliExternalTrackParam(),
167   fCp(0),
168   fIp(0),
169   fTPCInner(0),
170   fOp(0),
171   fHMPIDp(0),  
172   fFriendTrack(NULL),
173   fTPCFitMap(159),//number of padrows
174   fTPCClusterMap(159),//number of padrows
175   fTPCSharedMap(159),//number of padrows
176   fFlags(0),
177   fID(0),
178   fLabel(0),
179   fITSLabel(0),
180   fTPCLabel(0),
181   fTRDLabel(0),
182   fTOFLabel(NULL),
183   fTOFCalChannel(-1),
184   fTOFindex(-1),
185   fHMPIDqn(0),
186   fHMPIDcluIdx(-1),
187   fCaloIndex(kEMCALNoMatch),
188   fHMPIDtrkTheta(0),
189   fHMPIDtrkPhi(0),
190   fHMPIDsignal(0),
191   fTrackTime(0),
192   fTrackLength(0),
193   fdTPC(0),fzTPC(0),
194   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
195   fCchi2TPC(0),
196   fD(0),fZ(0),
197   fCdd(0),fCdz(0),fCzz(0),
198   fCchi2(0),
199   fITSchi2(0),
200   fTPCchi2(0),
201   fTPCchi2Iter1(0),
202   fTRDchi2(0),
203   fTOFchi2(0),
204   fHMPIDchi2(0),
205   fGlobalChi2(0),
206   fITSsignal(0),
207   fTPCsignal(0),
208   fTPCsignalTuned(0),
209   fTPCsignalS(0),
210   fTPCdEdxInfo(0),
211   fTRDsignal(0),
212   fTRDQuality(0),
213   fTRDBudget(0),
214   fTOFsignal(99999),
215   fTOFsignalTuned(99999),
216   fTOFsignalToT(99999),
217   fTOFsignalRaw(99999),
218   fTOFsignalDz(999),
219   fTOFsignalDx(999),
220   fTOFdeltaBC(999),
221   fTOFl0l1(999),
222   fCaloDx(0),
223   fCaloDz(0),
224   fHMPIDtrkX(0),
225   fHMPIDtrkY(0),
226   fHMPIDmipX(0),
227   fHMPIDmipY(0),
228   fTPCncls(0),
229   fTPCnclsF(0),
230   fTPCsignalN(0),
231   fTPCnclsIter1(0),
232   fTPCnclsFIter1(0),
233   fITSncls(0),
234   fITSClusterMap(0),
235   fITSSharedMap(0),
236   fTRDncls(0),
237   fTRDncls0(0),
238   fTRDntracklets(0),
239   fTRDNchamberdEdx(0),
240   fTRDNclusterdEdx(0),
241   fTRDnSlices(0),
242   fTRDslices(0x0),
243   fVertexID(-2),// -2 means an orphan track 
244   fESDEvent(0),
245   fCacheNCrossedRows(-10),
246   fCacheChi2TPCConstrainedVsGlobal(-10),
247   fCacheChi2TPCConstrainedVsGlobalVertex(0),
248   fDetectorPID(0x0),
249   fTrackPhiOnEMCal(-999),
250   fTrackEtaOnEMCal(-999),
251   fTrackPtOnEMCal(-999),
252   fNtofClusters(0),
253   fTOFcluster(NULL)
254 {
255   //
256   // The default ESD constructor 
257   //
258   if (!OnlineMode()) fFriendTrack=new AliESDfriendTrack();
259
260   Int_t i;
261   for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
262   for (i=0; i<AliPID::kSPECIES; i++) {
263     fR[i]=0.;
264     fITSr[i]=0.;
265     fTPCr[i]=0.;
266     fTRDr[i]=0.;
267     fTOFr[i]=0.;
268     fHMPIDr[i]=0.;
269   }
270   
271   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
272   for (i=0; i<3; i++)   { fV0Indexes[i]=0;}
273   for (i=0;i<kTRDnPlanes;i++) {
274     fTRDTimBin[i]=0;
275   }
276   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
277   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
278   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
279   for (i=0;i<12;i++) {fITSModule[i]=-1;}
280 }
281
282 bool AliESDtrack::fgkOnlineMode=false;
283
284 //_______________________________________________________________________
285 AliESDtrack::AliESDtrack(const AliESDtrack& track):
286   AliExternalTrackParam(track),
287   fCp(0),
288   fIp(0),
289   fTPCInner(0),
290   fOp(0),
291   fHMPIDp(0),  
292   fFriendTrack(0),
293   fTPCFitMap(track.fTPCFitMap),
294   fTPCClusterMap(track.fTPCClusterMap),
295   fTPCSharedMap(track.fTPCSharedMap),
296   fFlags(track.fFlags),
297   fID(track.fID),
298   fLabel(track.fLabel),
299   fITSLabel(track.fITSLabel),
300   fTPCLabel(track.fTPCLabel),
301   fTRDLabel(track.fTRDLabel),
302   fTOFLabel(NULL),
303   fTOFCalChannel(track.fTOFCalChannel),
304   fTOFindex(track.fTOFindex),
305   fHMPIDqn(track.fHMPIDqn),
306   fHMPIDcluIdx(track.fHMPIDcluIdx),
307   fCaloIndex(track.fCaloIndex),
308   fHMPIDtrkTheta(track.fHMPIDtrkTheta),
309   fHMPIDtrkPhi(track.fHMPIDtrkPhi),
310   fHMPIDsignal(track.fHMPIDsignal),
311   fTrackTime(NULL),
312   fTrackLength(track.fTrackLength),
313   fdTPC(track.fdTPC),fzTPC(track.fzTPC),
314   fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
315   fCchi2TPC(track.fCchi2TPC),
316   fD(track.fD),fZ(track.fZ),
317   fCdd(track.fCdd),fCdz(track.fCdz),fCzz(track.fCzz),
318   fCchi2(track.fCchi2),
319   fITSchi2(track.fITSchi2),
320   fTPCchi2(track.fTPCchi2),
321   fTPCchi2Iter1(track.fTPCchi2Iter1),
322   fTRDchi2(track.fTRDchi2),
323   fTOFchi2(track.fTOFchi2),
324   fHMPIDchi2(track.fHMPIDchi2),
325   fGlobalChi2(track.fGlobalChi2),
326   fITSsignal(track.fITSsignal),
327   fTPCsignal(track.fTPCsignal),
328   fTPCsignalTuned(track.fTPCsignalTuned),
329   fTPCsignalS(track.fTPCsignalS),
330   fTPCdEdxInfo(0),
331   fTRDsignal(track.fTRDsignal),
332   fTRDQuality(track.fTRDQuality),
333   fTRDBudget(track.fTRDBudget),
334   fTOFsignal(track.fTOFsignal),
335   fTOFsignalTuned(track.fTOFsignalTuned),
336   fTOFsignalToT(track.fTOFsignalToT),
337   fTOFsignalRaw(track.fTOFsignalRaw),
338   fTOFsignalDz(track.fTOFsignalDz),
339   fTOFsignalDx(track.fTOFsignalDx),
340   fTOFdeltaBC(track.fTOFdeltaBC),
341   fTOFl0l1(track.fTOFl0l1),
342   fCaloDx(track.fCaloDx),
343   fCaloDz(track.fCaloDz),
344   fHMPIDtrkX(track.fHMPIDtrkX),
345   fHMPIDtrkY(track.fHMPIDtrkY),
346   fHMPIDmipX(track.fHMPIDmipX),
347   fHMPIDmipY(track.fHMPIDmipY),
348   fTPCncls(track.fTPCncls),
349   fTPCnclsF(track.fTPCnclsF),
350   fTPCsignalN(track.fTPCsignalN),
351   fTPCnclsIter1(track.fTPCnclsIter1),
352   fTPCnclsFIter1(track.fTPCnclsIter1),
353   fITSncls(track.fITSncls),
354   fITSClusterMap(track.fITSClusterMap),
355   fITSSharedMap(track.fITSSharedMap),
356   fTRDncls(track.fTRDncls),
357   fTRDncls0(track.fTRDncls0),
358   fTRDntracklets(track.fTRDntracklets),
359   fTRDNchamberdEdx(track.fTRDNchamberdEdx),
360   fTRDNclusterdEdx(track.fTRDNclusterdEdx),
361   fTRDnSlices(track.fTRDnSlices),
362   fTRDslices(0x0),
363   fVertexID(track.fVertexID),
364   fESDEvent(track.fESDEvent),
365   fCacheNCrossedRows(track.fCacheNCrossedRows),
366   fCacheChi2TPCConstrainedVsGlobal(track.fCacheChi2TPCConstrainedVsGlobal),
367   fCacheChi2TPCConstrainedVsGlobalVertex(track.fCacheChi2TPCConstrainedVsGlobalVertex),
368   fDetectorPID(0x0),
369   fTrackPhiOnEMCal(track.fTrackPhiOnEMCal),
370   fTrackEtaOnEMCal(track.fTrackEtaOnEMCal),
371   fTrackPtOnEMCal(track.fTrackPtOnEMCal),
372   fNtofClusters(track.fNtofClusters),
373   fTOFcluster(NULL)
374 {
375   //
376   //copy constructor
377   //
378   for (Int_t i=kNITSchi2Std;i--;) fITSchi2Std[i] = track.fITSchi2Std[i];
379
380   if(track.fTrackTime){
381     fTrackTime = new Double32_t[AliPID::kSPECIESC];
382     for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i]=track.fTrackTime[i];
383   }
384
385   for (Int_t i=0;i<AliPID::kSPECIES;i++)  fR[i]=track.fR[i];
386   //
387   for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=track.fITSr[i]; 
388   //
389   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=track.fTPCr[i]; 
390   for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=track.fITSdEdxSamples[i];}
391   for (Int_t i=0;i<4;i++) {fTPCPoints[i]=track.fTPCPoints[i];}
392   for (Int_t i=0; i<3;i++)   { fKinkIndexes[i]=track.fKinkIndexes[i];}
393   for (Int_t i=0; i<3;i++)   { fV0Indexes[i]=track.fV0Indexes[i];}
394   //
395   for (Int_t i=0;i<kTRDnPlanes;i++) {
396     fTRDTimBin[i]=track.fTRDTimBin[i];
397   }
398
399   if (fTRDnSlices) {
400     fTRDslices=new Double32_t[fTRDnSlices];
401     for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=track.fTRDslices[i];
402   }
403
404   if (track.fDetectorPID) fDetectorPID = new AliDetectorPID(*track.fDetectorPID);
405
406   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i]=track.fTRDr[i]; 
407   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i]=track.fTOFr[i];
408   if(track.fTOFLabel){
409     if(!fTOFLabel) fTOFLabel = new Int_t[3];
410     for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
411   }
412
413   for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
414   for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
415   for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i]=track.fHMPIDr[i];
416
417   if (track.fCp) fCp=new AliExternalTrackParam(*track.fCp);
418   if (track.fIp) fIp=new AliExternalTrackParam(*track.fIp);
419   if (track.fTPCInner) fTPCInner=new AliExternalTrackParam(*track.fTPCInner);
420   if (track.fOp) fOp=new AliExternalTrackParam(*track.fOp);
421   if (track.fHMPIDp) fHMPIDp=new AliExternalTrackParam(*track.fHMPIDp);
422   if (track.fTPCdEdxInfo) fTPCdEdxInfo = new AliTPCdEdxInfo(*track.fTPCdEdxInfo);
423
424   
425   if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
426
427   if(fNtofClusters > 0){
428     fTOFcluster = new Int_t[fNtofClusters];
429         for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = track.fTOFcluster[i];
430   }
431 }
432
433 //_______________________________________________________________________
434 AliESDtrack::AliESDtrack(const AliVTrack *track) : 
435   AliExternalTrackParam(track),
436   fCp(0),
437   fIp(0),
438   fTPCInner(0),
439   fOp(0),
440   fHMPIDp(0),  
441   fFriendTrack(0),
442   fTPCFitMap(159),//number of padrows
443   fTPCClusterMap(159),//number of padrows
444   fTPCSharedMap(159),//number of padrows
445   fFlags(0),
446   fID(),
447   fLabel(0),
448   fITSLabel(0),
449   fTPCLabel(0),
450   fTRDLabel(0),
451   fTOFLabel(NULL),
452   fTOFCalChannel(-1),
453   fTOFindex(-1),
454   fHMPIDqn(0),
455   fHMPIDcluIdx(-1),
456   fCaloIndex(kEMCALNoMatch),
457   fHMPIDtrkTheta(0),
458   fHMPIDtrkPhi(0),
459   fHMPIDsignal(0),
460   fTrackTime(NULL),
461   fTrackLength(0),
462   fdTPC(0),fzTPC(0),
463   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
464   fCchi2TPC(0),
465   fD(0),fZ(0),
466   fCdd(0),fCdz(0),fCzz(0),
467   fCchi2(0),
468   fITSchi2(0),
469   fTPCchi2(0),
470   fTPCchi2Iter1(0),
471   fTRDchi2(0),
472   fTOFchi2(0),
473   fHMPIDchi2(0),
474   fGlobalChi2(0),
475   fITSsignal(0),
476   fTPCsignal(0),
477   fTPCsignalTuned(0),
478   fTPCsignalS(0),
479   fTPCdEdxInfo(0),
480   fTRDsignal(0),
481   fTRDQuality(0),
482   fTRDBudget(0),
483   fTOFsignal(99999),
484   fTOFsignalTuned(99999),
485   fTOFsignalToT(99999),
486   fTOFsignalRaw(99999),
487   fTOFsignalDz(999),
488   fTOFsignalDx(999),
489   fTOFdeltaBC(999),
490   fTOFl0l1(999),
491   fCaloDx(0),
492   fCaloDz(0),
493   fHMPIDtrkX(0),
494   fHMPIDtrkY(0),
495   fHMPIDmipX(0),
496   fHMPIDmipY(0),
497   fTPCncls(0),
498   fTPCnclsF(0),
499   fTPCsignalN(0),
500   fTPCnclsIter1(0),
501   fTPCnclsFIter1(0),
502   fITSncls(0),
503   fITSClusterMap(0),
504   fITSSharedMap(0),
505   fTRDncls(0),
506   fTRDncls0(0),
507   fTRDntracklets(0),
508   fTRDNchamberdEdx(0),
509   fTRDNclusterdEdx(0),
510   fTRDnSlices(0),
511   fTRDslices(0x0),
512   fVertexID(-2),  // -2 means an orphan track
513   fESDEvent(0),
514   fCacheNCrossedRows(-10),
515   fCacheChi2TPCConstrainedVsGlobal(-10),
516   fCacheChi2TPCConstrainedVsGlobalVertex(0),
517   fDetectorPID(0x0),
518   fTrackPhiOnEMCal(-999),
519   fTrackEtaOnEMCal(-999),
520   fTrackPtOnEMCal(-999),
521   fNtofClusters(0),
522   fTOFcluster(NULL)
523 {
524   //
525   // ESD track from AliVTrack.
526   // This is not a copy constructor !
527   //
528
529   if (track->InheritsFrom("AliExternalTrackParam")) {
530      AliError("This is not a copy constructor. Use AliESDtrack(const AliESDtrack &) !");
531      AliWarning("Calling the default constructor...");
532      AliESDtrack();
533      return;
534   }
535
536   // Reset all the arrays
537   Int_t i;
538   for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
539   for (i=0; i<AliPID::kSPECIES; i++) {
540     fR[i]=0.;
541     fITSr[i]=0.;
542     fTPCr[i]=0.;
543     fTRDr[i]=0.;
544     fTOFr[i]=0.;
545     fHMPIDr[i]=0.;
546   }
547   
548   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
549   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
550   for (i=0;i<kTRDnPlanes;i++) {
551     fTRDTimBin[i]=0;
552   }
553   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
554   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
555   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
556   for (i=0;i<12;i++) {fITSModule[i]=-1;}
557
558   // Set the ID
559   SetID(track->GetID());
560
561   // Set ITS cluster map
562   fITSClusterMap=track->GetITSClusterMap();
563   fITSSharedMap=0;
564
565   fITSncls=0;
566   for(i=0; i<6; i++) {
567     if(HasPointOnITSLayer(i)) fITSncls++;
568   }
569
570   // Set TPC ncls 
571   fTPCncls=track->GetTPCNcls();
572   fTPCnclsF=track->GetTPCNclsF();
573   // TPC cluster maps
574   const TBits* bmap = track->GetTPCClusterMapPtr();
575   if (bmap) SetTPCClusterMap(*bmap);
576   bmap = GetTPCFitMapPtr();
577   if (bmap) SetTPCFitMap(*bmap);
578   bmap = GetTPCSharedMapPtr();
579   if (bmap) SetTPCSharedMap(*bmap);
580   //
581   // Set the combined PID
582   const Double_t *pid = track->PID();
583   if(pid) for (i=0; i<AliPID::kSPECIES; i++) fR[i]=pid[i];
584   //
585   // calo matched cluster id
586   SetEMCALcluster(track->GetEMCALcluster());
587   // AliESD track label
588   //
589   // PID info
590   fITSsignal = track->GetITSsignal();
591   double itsdEdx[4];
592   track->GetITSdEdxSamples(itsdEdx);
593   SetITSdEdxSamples(itsdEdx);
594   //
595   SetTPCsignal(track->GetTPCsignal(),fTPCsignalS,track->GetTPCsignalN()); // No signalS in AODPi
596   AliTPCdEdxInfo * dEdxInfo = track->GetTPCdEdxInfo();
597   if (dEdxInfo) SetTPCdEdxInfo(new AliTPCdEdxInfo(*dEdxInfo));
598   //
599   SetTRDsignal(track->GetTRDsignal());
600   int ntrdsl = track->GetNumberOfTRDslices();
601   if (ntrdsl>0) {
602     SetNumberOfTRDslices((ntrdsl+2)*kTRDnPlanes);
603     for (int ipl=kTRDnPlanes;ipl--;){
604       for (int isl=ntrdsl;isl--;) SetTRDslice(track->GetTRDslice(ipl,isl),ipl,isl);
605       Double_t sp, p = track->GetTRDmomentum(ipl, &sp);
606       SetTRDmomentum(p, ipl, &sp);
607     }
608   }
609   //
610   fTRDncls = track->GetTRDncls();
611   fTRDntracklets &= 0xff & track->GetTRDntrackletsPID();
612   fTRDchi2 = track->GetTRDchi2();
613   //
614   SetTOFsignal(track->GetTOFsignal());
615   Double_t expt[AliPID::kSPECIESC];
616   track->GetIntegratedTimes(expt);
617   SetIntegratedTimes(expt);
618   //
619   SetTrackPhiEtaPtOnEMCal(track->GetTrackPhiOnEMCal(),track->GetTrackEtaOnEMCal(),track->GetTrackPtOnEMCal());
620   //
621   SetLabel(track->GetLabel());
622   // Set the status
623   SetStatus(track->GetStatus());
624 }
625
626 //_______________________________________________________________________
627 AliESDtrack::AliESDtrack(TParticle * part) : 
628   AliExternalTrackParam(),
629   fCp(0),
630   fIp(0),
631   fTPCInner(0),
632   fOp(0),
633   fHMPIDp(0),  
634   fFriendTrack(0),
635   fTPCFitMap(159),//number of padrows
636   fTPCClusterMap(159),//number of padrows
637   fTPCSharedMap(159),//number of padrows
638   fFlags(0),
639   fID(0),
640   fLabel(0),
641   fITSLabel(0),
642   fTPCLabel(0),
643   fTRDLabel(0),
644   fTOFLabel(NULL),
645   fTOFCalChannel(-1),
646   fTOFindex(-1),
647   fHMPIDqn(0),
648   fHMPIDcluIdx(-1),
649   fCaloIndex(kEMCALNoMatch),
650   fHMPIDtrkTheta(0),
651   fHMPIDtrkPhi(0),
652   fHMPIDsignal(0),
653   fTrackTime(NULL),
654   fTrackLength(0),
655   fdTPC(0),fzTPC(0),
656   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
657   fCchi2TPC(0),
658   fD(0),fZ(0),
659   fCdd(0),fCdz(0),fCzz(0),
660   fCchi2(0),
661   fITSchi2(0),
662   fTPCchi2(0),
663   fTPCchi2Iter1(0),  
664   fTRDchi2(0),
665   fTOFchi2(0),
666   fHMPIDchi2(0),
667   fGlobalChi2(0),
668   fITSsignal(0),
669   fTPCsignal(0),
670   fTPCsignalTuned(0),
671   fTPCsignalS(0),
672   fTPCdEdxInfo(0),
673   fTRDsignal(0),
674   fTRDQuality(0),
675   fTRDBudget(0),
676   fTOFsignal(99999),
677   fTOFsignalTuned(99999),
678   fTOFsignalToT(99999),
679   fTOFsignalRaw(99999),
680   fTOFsignalDz(999),
681   fTOFsignalDx(999),
682   fTOFdeltaBC(999),
683   fTOFl0l1(999),
684   fCaloDx(0),
685   fCaloDz(0),
686   fHMPIDtrkX(0),
687   fHMPIDtrkY(0),
688   fHMPIDmipX(0),
689   fHMPIDmipY(0),
690   fTPCncls(0),
691   fTPCnclsF(0),
692   fTPCsignalN(0),
693   fTPCnclsIter1(0),
694   fTPCnclsFIter1(0),
695   fITSncls(0),
696   fITSClusterMap(0),
697   fITSSharedMap(0),
698   fTRDncls(0),
699   fTRDncls0(0),
700   fTRDntracklets(0),
701   fTRDNchamberdEdx(0),
702   fTRDNclusterdEdx(0),
703   fTRDnSlices(0),
704   fTRDslices(0x0),
705   fVertexID(-2),  // -2 means an orphan track
706   fESDEvent(0),
707   fCacheNCrossedRows(-10),
708   fCacheChi2TPCConstrainedVsGlobal(-10),
709   fCacheChi2TPCConstrainedVsGlobalVertex(0),
710   fDetectorPID(0x0),
711   fTrackPhiOnEMCal(-999),
712   fTrackEtaOnEMCal(-999),
713   fTrackPtOnEMCal(-999),
714   fNtofClusters(0),
715   fTOFcluster(NULL)
716 {
717   //
718   // ESD track from TParticle
719   //
720
721   // Reset all the arrays
722   Int_t i;
723   for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
724   for (i=0; i<AliPID::kSPECIES; i++) {
725     fR[i]=0.;
726     fITSr[i]=0.;
727     fTPCr[i]=0.;
728     fTRDr[i]=0.;
729     fTOFr[i]=0.;
730     fHMPIDr[i]=0.;
731   }
732   
733   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
734   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
735   for (i=0;i<kTRDnPlanes;i++) {
736     fTRDTimBin[i]=0;
737   }
738   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
739   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
740   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
741   for (i=0;i<12;i++) {fITSModule[i]=-1;}
742
743   // Calculate the AliExternalTrackParam content
744
745   Double_t xref;
746   Double_t alpha;
747   Double_t param[5];
748   Double_t covar[15];
749
750   // Calculate alpha: the rotation angle of the corresponding local system (TPC sector)
751   alpha = part->Phi()*180./TMath::Pi();
752   if (alpha<0) alpha+= 360.;
753   if (alpha>360) alpha -= 360.;
754
755   Int_t sector = (Int_t)(alpha/20.);
756   alpha = 10. + 20.*sector;
757   alpha /= 180;
758   alpha *= TMath::Pi();
759
760   // Covariance matrix: no errors, the parameters are exact
761   for (i=0; i<15; i++) covar[i]=0.;
762
763   // Get the vertex of origin and the momentum
764   TVector3 ver(part->Vx(),part->Vy(),part->Vz());
765   TVector3 mom(part->Px(),part->Py(),part->Pz());
766
767   // Rotate to the local coordinate system (TPC sector)
768   ver.RotateZ(-alpha);
769   mom.RotateZ(-alpha);
770
771   // X of the referense plane
772   xref = ver.X();
773
774   Int_t pdgCode = part->GetPdgCode();
775
776   Double_t charge = 
777     TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge();
778
779   param[0] = ver.Y();
780   param[1] = ver.Z();
781   param[2] = TMath::Sin(mom.Phi());
782   param[3] = mom.Pz()/mom.Pt();
783   param[4] = TMath::Sign(1/mom.Pt(),charge);
784
785   // Set AliExternalTrackParam
786   Set(xref, alpha, param, covar);
787
788   // Set the PID
789   Int_t indexPID = 99;
790
791   switch (TMath::Abs(pdgCode)) {
792
793   case  11: // electron
794     indexPID = 0;
795     break;
796
797   case 13: // muon
798     indexPID = 1;
799     break;
800
801   case 211: // pion
802     indexPID = 2;
803     break;
804
805   case 321: // kaon
806     indexPID = 3;
807     break;
808
809   case 2212: // proton
810     indexPID = 4;
811     break;
812
813   default:
814     break;
815   }
816
817   // If the particle is not e,mu,pi,K or p the PID probabilities are set to 0
818   if (indexPID < AliPID::kSPECIES) {
819     fR[indexPID]=1.;
820     fITSr[indexPID]=1.;
821     fTPCr[indexPID]=1.;
822     fTRDr[indexPID]=1.;
823     fTOFr[indexPID]=1.;
824     fHMPIDr[indexPID]=1.;
825
826   }
827   // AliESD track label
828   SetLabel(part->GetUniqueID());
829
830 }
831
832 //_______________________________________________________________________
833 AliESDtrack::~AliESDtrack(){ 
834   //
835   // This is destructor according Coding Conventrions 
836   //
837   //printf("Delete track\n");
838   delete fIp; 
839   delete fTPCInner; 
840   delete fOp;
841   delete fHMPIDp;
842   delete fCp; 
843   delete fFriendTrack;
844   delete fTPCdEdxInfo;
845   if(fTRDnSlices)
846     delete[] fTRDslices;
847
848   //Reset cached values - needed for TClonesArray in AliESDInputHandler
849   fCacheNCrossedRows = -10.;
850   fCacheChi2TPCConstrainedVsGlobal = -10.;
851   if(fCacheChi2TPCConstrainedVsGlobalVertex) fCacheChi2TPCConstrainedVsGlobalVertex = 0;
852
853   if(fTOFcluster)
854     delete[] fTOFcluster;
855   fTOFcluster = NULL;
856   fNtofClusters=0;
857
858   delete fDetectorPID;
859
860   if(fTrackTime) delete[] fTrackTime; 
861   if(fTOFLabel) delete[] fTOFLabel;
862 }
863
864 AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
865   
866
867   if(&source == this) return *this;
868   AliExternalTrackParam::operator=(source);
869
870   
871   if(source.fCp){
872     // we have the trackparam: assign or copy construct
873     if(fCp)*fCp = *source.fCp;
874     else fCp = new AliExternalTrackParam(*source.fCp);
875   }
876   else{
877     // no track param delete the old one
878     delete fCp;
879     fCp = 0;
880   }
881
882   if(source.fIp){
883     // we have the trackparam: assign or copy construct
884     if(fIp)*fIp = *source.fIp;
885     else fIp = new AliExternalTrackParam(*source.fIp);
886   }
887   else{
888     // no track param delete the old one
889     delete fIp;
890     fIp = 0;
891   }
892
893
894   if(source.fTPCInner){
895     // we have the trackparam: assign or copy construct
896     if(fTPCInner) *fTPCInner = *source.fTPCInner;
897     else fTPCInner = new AliExternalTrackParam(*source.fTPCInner);
898   }
899   else{
900     // no track param delete the old one
901     delete fTPCInner;
902     fTPCInner = 0;
903   }
904
905   if(source.fTPCdEdxInfo) {
906     if(fTPCdEdxInfo) *fTPCdEdxInfo = *source.fTPCdEdxInfo;
907     fTPCdEdxInfo = new AliTPCdEdxInfo(*source.fTPCdEdxInfo);
908   }
909
910   if(source.fOp){
911     // we have the trackparam: assign or copy construct
912     if(fOp) *fOp = *source.fOp;
913     else fOp = new AliExternalTrackParam(*source.fOp);
914   }
915   else{
916     // no track param delete the old one
917     delete fOp;
918     fOp = 0;
919   }
920
921   
922   if(source.fHMPIDp){
923     // we have the trackparam: assign or copy construct
924     if(fHMPIDp) *fHMPIDp = *source.fHMPIDp;
925     else fHMPIDp = new AliExternalTrackParam(*source.fHMPIDp);
926   }
927   else{
928     // no track param delete the old one
929     delete fHMPIDp;
930     fHMPIDp = 0;
931   }
932
933   // copy also the friend track 
934   // use copy constructor
935   if(source.fFriendTrack){
936     // we have the trackparam: assign or copy construct
937     delete fFriendTrack; fFriendTrack=new AliESDfriendTrack(*source.fFriendTrack);
938   }
939   else{
940     // no track param delete the old one
941     delete fFriendTrack; fFriendTrack= 0;
942   }
943
944   fTPCFitMap = source.fTPCFitMap; 
945   fTPCClusterMap = source.fTPCClusterMap; 
946   fTPCSharedMap  = source.fTPCSharedMap;  
947   // the simple stuff
948   fFlags    = source.fFlags; 
949   fID       = source.fID;             
950   fLabel    = source.fLabel;
951   fITSLabel = source.fITSLabel;
952   for(int i = 0; i< 12;++i){
953     fITSModule[i] = source.fITSModule[i];
954   }
955   fTPCLabel = source.fTPCLabel; 
956   fTRDLabel = source.fTRDLabel;
957   if(source.fTOFLabel){
958     if(!fTOFLabel) fTOFLabel = new Int_t[3];
959     for(int i = 0; i< 3;++i){
960       fTOFLabel[i] = source.fTOFLabel[i];    
961     }
962   }
963   fTOFCalChannel = source.fTOFCalChannel;
964   fTOFindex      = source.fTOFindex;
965   fHMPIDqn       = source.fHMPIDqn;
966   fHMPIDcluIdx   = source.fHMPIDcluIdx; 
967   fCaloIndex    = source.fCaloIndex;
968   for (int i=kNITSchi2Std;i--;) fITSchi2Std[i] = source.fITSchi2Std[i];
969   for(int i = 0; i< 3;++i){
970     fKinkIndexes[i] = source.fKinkIndexes[i]; 
971     fV0Indexes[i]   = source.fV0Indexes[i]; 
972   }
973
974   for(int i = 0; i< AliPID::kSPECIES;++i){
975     fR[i]     = source.fR[i];
976     fITSr[i]  = source.fITSr[i];
977     fTPCr[i]  = source.fTPCr[i];
978     fTRDr[i]  = source.fTRDr[i];
979     fTOFr[i]  = source.fTOFr[i];
980     fHMPIDr[i] = source.fHMPIDr[i];
981   }
982
983   fHMPIDtrkTheta = source.fHMPIDtrkTheta;
984   fHMPIDtrkPhi   = source.fHMPIDtrkPhi;
985   fHMPIDsignal   = source.fHMPIDsignal; 
986
987   
988   if(fTrackTime){
989     delete[] fTrackTime;
990   }
991   if(source.fTrackTime){
992     fTrackTime = new Double32_t[AliPID::kSPECIESC];
993     for(Int_t i=0;i < AliPID::kSPECIESC;i++)
994       fTrackTime[i] = source.fTrackTime[i];  
995   }
996
997   fTrackLength   = source. fTrackLength;
998   fdTPC  = source.fdTPC; 
999   fzTPC  = source.fzTPC; 
1000   fCddTPC = source.fCddTPC;
1001   fCdzTPC = source.fCdzTPC;
1002   fCzzTPC = source.fCzzTPC;
1003   fCchi2TPC = source.fCchi2TPC;
1004
1005   fD  = source.fD; 
1006   fZ  = source.fZ; 
1007   fCdd = source.fCdd;
1008   fCdz = source.fCdz;
1009   fCzz = source.fCzz;
1010   fCchi2     = source.fCchi2;
1011
1012   fITSchi2   = source.fITSchi2;             
1013   fTPCchi2   = source.fTPCchi2;            
1014   fTPCchi2Iter1   = source.fTPCchi2Iter1;            
1015   fTRDchi2   = source.fTRDchi2;      
1016   fTOFchi2   = source.fTOFchi2;      
1017   fHMPIDchi2 = source.fHMPIDchi2;      
1018
1019   fGlobalChi2 = source.fGlobalChi2;      
1020
1021   fITSsignal  = source.fITSsignal;     
1022   for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=source.fITSdEdxSamples[i];}
1023   fTPCsignal  = source.fTPCsignal;     
1024   fTPCsignalTuned  = source.fTPCsignalTuned;
1025   fTPCsignalS = source.fTPCsignalS;    
1026   for(int i = 0; i< 4;++i){
1027     fTPCPoints[i] = source.fTPCPoints[i];  
1028   }
1029   fTRDsignal = source.fTRDsignal;
1030   fTRDNchamberdEdx = source.fTRDNchamberdEdx;
1031   fTRDNclusterdEdx = source.fTRDNclusterdEdx;
1032
1033   for(int i = 0;i < kTRDnPlanes;++i){
1034     fTRDTimBin[i] = source.fTRDTimBin[i];   
1035   }
1036
1037   if(fTRDnSlices)
1038     delete[] fTRDslices;
1039   fTRDslices=0;
1040   fTRDnSlices=source.fTRDnSlices;
1041   if (fTRDnSlices) {
1042     fTRDslices=new Double32_t[fTRDnSlices];
1043     for(int j = 0;j < fTRDnSlices;++j) fTRDslices[j] = source.fTRDslices[j];
1044   }
1045
1046   fTRDQuality =   source.fTRDQuality;     
1047   fTRDBudget  =   source.fTRDBudget;      
1048   fTOFsignal  =   source.fTOFsignal;     
1049   fTOFsignalTuned  = source.fTOFsignalTuned;
1050   fTOFsignalToT = source.fTOFsignalToT;   
1051   fTOFsignalRaw = source.fTOFsignalRaw;  
1052   fTOFsignalDz  = source.fTOFsignalDz;      
1053   fTOFsignalDx  = source.fTOFsignalDx;      
1054   fTOFdeltaBC   = source.fTOFdeltaBC;
1055   fTOFl0l1      = source.fTOFl0l1;
1056  
1057   for(int i = 0;i<10;++i){
1058     fTOFInfo[i] = source.fTOFInfo[i];    
1059   }
1060
1061   fHMPIDtrkX = source.fHMPIDtrkX; 
1062   fHMPIDtrkY = source.fHMPIDtrkY; 
1063   fHMPIDmipX = source.fHMPIDmipX;
1064   fHMPIDmipY = source.fHMPIDmipY; 
1065
1066   fTPCncls    = source.fTPCncls;      
1067   fTPCnclsF   = source.fTPCnclsF;     
1068   fTPCsignalN = source.fTPCsignalN;   
1069   fTPCnclsIter1    = source.fTPCnclsIter1;      
1070   fTPCnclsFIter1   = source.fTPCnclsFIter1;     
1071
1072   fITSncls = source.fITSncls;       
1073   fITSClusterMap = source.fITSClusterMap; 
1074   fITSSharedMap = source.fITSSharedMap; 
1075   fTRDncls   = source.fTRDncls;       
1076   fTRDncls0  = source.fTRDncls0;      
1077   fTRDntracklets  = source.fTRDntracklets; 
1078   fVertexID = source.fVertexID;
1079
1080   fCacheNCrossedRows = source.fCacheNCrossedRows;
1081   fCacheChi2TPCConstrainedVsGlobal = source.fCacheChi2TPCConstrainedVsGlobal;
1082   fCacheChi2TPCConstrainedVsGlobalVertex = source.fCacheChi2TPCConstrainedVsGlobalVertex;
1083
1084   delete fDetectorPID;
1085   fDetectorPID=0x0;
1086   if (source.fDetectorPID) fDetectorPID = new AliDetectorPID(*source.fDetectorPID);
1087   
1088   fTrackPhiOnEMCal= source.fTrackPhiOnEMCal;
1089   fTrackEtaOnEMCal= source.fTrackEtaOnEMCal;
1090   fTrackPtOnEMCal= source.fTrackPtOnEMCal;
1091
1092   if(fTOFcluster){
1093     delete[] fTOFcluster;
1094   }
1095   fNtofClusters = source.fNtofClusters;
1096   if(fNtofClusters > 0){
1097     fTOFcluster = new Int_t[fNtofClusters];
1098         for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = source.fTOFcluster[i];
1099   }
1100
1101   return *this;
1102 }
1103
1104
1105
1106 void AliESDtrack::Copy(TObject &obj) const {
1107   
1108   // this overwrites the virtual TOBject::Copy()
1109   // to allow run time copying without casting
1110   // in AliESDEvent
1111
1112   if(this==&obj)return;
1113   AliESDtrack *robj = dynamic_cast<AliESDtrack*>(&obj);
1114   if(!robj)return; // not an AliESDtrack
1115   *robj = *this;
1116
1117 }
1118
1119
1120
1121 void AliESDtrack::AddCalibObject(TObject * object){
1122   //
1123   // add calib object to the list
1124   //
1125   if (!fFriendTrack) fFriendTrack  = new AliESDfriendTrack;
1126   if (!fFriendTrack) return;
1127   fFriendTrack->AddCalibObject(object);
1128 }
1129
1130 TObject *  AliESDtrack::GetCalibObject(Int_t index){
1131   //
1132   // return calib objct at given position
1133   //
1134   if (!fFriendTrack) return 0;
1135   return fFriendTrack->GetCalibObject(index);
1136 }
1137
1138
1139 Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
1140   
1141   // Fills the information of the TPC-only first reconstruction pass
1142   // into the passed ESDtrack object. For consistency fTPCInner is also filled
1143   // again
1144
1145
1146
1147   // For data produced before r26675
1148   // RelateToVertexTPC was not properly called during reco
1149   // so you'll have to call it again, before FillTPCOnlyTrack
1150   //  Float_t p[2],cov[3];
1151   // track->GetImpactParametersTPC(p,cov); 
1152   // if(p[0]==0&&p[1]==0) // <- Default values
1153   //  track->RelateToVertexTPC(esd->GetPrimaryVertexTPC(),esd->GetMagneticField(),kVeryBig);
1154   
1155
1156   if(!fTPCInner)return kFALSE;
1157
1158   // fill the TPC track params to the global track parameters
1159   track.Set(fTPCInner->GetX(),fTPCInner->GetAlpha(),fTPCInner->GetParameter(),fTPCInner->GetCovariance());
1160   track.fD = fdTPC;
1161   track.fZ = fzTPC;
1162   track.fCdd = fCddTPC;
1163   track.fCdz = fCdzTPC;
1164   track.fCzz = fCzzTPC;
1165
1166   // copy the inner params
1167   if(track.fIp) *track.fIp = *fIp;
1168   else track.fIp = new AliExternalTrackParam(*fIp);
1169
1170   // copy the TPCinner parameters
1171   if(track.fTPCInner) *track.fTPCInner = *fTPCInner;
1172   else track.fTPCInner = new AliExternalTrackParam(*fTPCInner);
1173   track.fdTPC   = fdTPC;
1174   track.fzTPC   = fzTPC;
1175   track.fCddTPC = fCddTPC;
1176   track.fCdzTPC = fCdzTPC;
1177   track.fCzzTPC = fCzzTPC;
1178   track.fCchi2TPC = fCchi2TPC;
1179
1180   // copy all other TPC specific parameters
1181
1182   // replace label by TPC label
1183   track.fLabel    = fTPCLabel;
1184   track.fTPCLabel = fTPCLabel;
1185
1186   track.fTPCchi2 = fTPCchi2; 
1187   track.fTPCchi2Iter1 = fTPCchi2Iter1; 
1188   track.fTPCsignal = fTPCsignal;
1189   track.fTPCsignalTuned = fTPCsignalTuned;
1190   track.fTPCsignalS = fTPCsignalS;
1191   for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
1192
1193   track.fTPCncls    = fTPCncls;     
1194   track.fTPCnclsF   = fTPCnclsF;     
1195   track.fTPCsignalN =  fTPCsignalN;
1196   track.fTPCnclsIter1    = fTPCnclsIter1;     
1197   track.fTPCnclsFIter1   = fTPCnclsFIter1;     
1198
1199   // PID 
1200   for(int i=0;i<AliPID::kSPECIES;++i){
1201     track.fTPCr[i] = fTPCr[i];
1202     // combined PID is TPC only!
1203     track.fR[i] = fTPCr[i];
1204   }
1205   track.fTPCFitMap = fTPCFitMap;
1206   track.fTPCClusterMap = fTPCClusterMap;
1207   track.fTPCSharedMap = fTPCSharedMap;
1208
1209
1210   // reset the flags
1211   track.fFlags = kTPCin;
1212   track.fID    = fID;
1213
1214   track.fFlags |= fFlags & kTPCpid; //copy the TPCpid status flag
1215  
1216   for (Int_t i=0;i<3;i++) track.fKinkIndexes[i] = fKinkIndexes[i];
1217   
1218   return kTRUE;
1219     
1220 }
1221
1222 //_______________________________________________________________________
1223 void AliESDtrack::MakeMiniESDtrack(){
1224   // Resets everything except
1225   // fFlags: Reconstruction status flags 
1226   // fLabel: Track label
1227   // fID:  Unique ID of the track
1228   // Impact parameter information
1229   // fR[AliPID::kSPECIES]: combined "detector response probability"
1230   // Running track parameters in the base class (AliExternalTrackParam)
1231   
1232   fTrackLength = 0;
1233
1234   if(fTrackTime)
1235     for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i] = 0;
1236
1237   // Reset track parameters constrained to the primary vertex
1238   delete fCp;fCp = 0;
1239
1240   // Reset track parameters at the inner wall of TPC
1241   delete fIp;fIp = 0;
1242   delete fTPCInner;fTPCInner=0;
1243   // Reset track parameters at the inner wall of the TRD
1244   delete fOp;fOp = 0;
1245   // Reset track parameters at the HMPID
1246   delete fHMPIDp;fHMPIDp = 0;
1247
1248
1249   // Reset ITS track related information
1250   fITSchi2 = 0;
1251   fITSncls = 0;       
1252   fITSClusterMap=0;
1253   fITSSharedMap=0;
1254   fITSsignal = 0;     
1255   for (Int_t i=0;i<4;i++) fITSdEdxSamples[i] = 0.;
1256   for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0; 
1257   fITSLabel = 0;       
1258
1259   // Reset TPC related track information
1260   fTPCchi2 = 0;       
1261   fTPCchi2Iter1 = 0;       
1262   fTPCncls = 0;       
1263   fTPCnclsF = 0;       
1264   fTPCnclsIter1 = 0;       
1265   fTPCnclsFIter1 = 0;  
1266   fTPCFitMap = 0;       
1267   fTPCClusterMap = 0;  
1268   fTPCSharedMap = 0;  
1269   fTPCsignal= 0;      
1270   fTPCsignalTuned= 0;
1271   fTPCsignalS= 0;      
1272   fTPCsignalN= 0;      
1273   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=0; 
1274   fTPCLabel=0;       
1275   for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
1276   for (Int_t i=0; i<3;i++)   fKinkIndexes[i] = 0;
1277   for (Int_t i=0; i<3;i++)   fV0Indexes[i] = 0;
1278
1279   // Reset TRD related track information
1280   fTRDchi2 = 0;        
1281   fTRDncls = 0;       
1282   fTRDncls0 = 0;       
1283   fTRDsignal = 0;      
1284   fTRDNchamberdEdx = 0;
1285   fTRDNclusterdEdx = 0;
1286
1287   for (Int_t i=0;i<kTRDnPlanes;i++) {
1288     fTRDTimBin[i]  = 0;
1289   }
1290   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0; 
1291   fTRDLabel = 0;       
1292   fTRDQuality  = 0;
1293   fTRDntracklets = 0;
1294   if(fTRDnSlices)
1295     delete[] fTRDslices;
1296   fTRDslices=0x0;
1297   fTRDnSlices=0;
1298   fTRDBudget  = 0;
1299
1300   // Reset TOF related track information
1301   fTOFchi2 = 0;        
1302   fTOFindex = -1;       
1303   fTOFsignal = 99999;      
1304   fTOFCalChannel = -1;
1305   fTOFsignalToT = 99999;
1306   fTOFsignalRaw = 99999;
1307   fTOFsignalDz = 999;
1308   fTOFsignalDx = 999;
1309   fTOFdeltaBC = 999;
1310   fTOFl0l1 = 999;
1311   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
1312   for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
1313
1314   // Reset HMPID related track information
1315   fHMPIDchi2 = 0;     
1316   fHMPIDqn = 0;     
1317   fHMPIDcluIdx = -1;     
1318   fHMPIDsignal = 0;     
1319   for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
1320   fHMPIDtrkTheta = 0;     
1321   fHMPIDtrkPhi = 0;      
1322   fHMPIDtrkX = 0;     
1323   fHMPIDtrkY = 0;      
1324   fHMPIDmipX = 0;
1325   fHMPIDmipY = 0;
1326   fCaloIndex = kEMCALNoMatch;
1327
1328   // reset global track chi2
1329   fGlobalChi2 = 0;
1330
1331   fVertexID = -2; // an orphan track
1332
1333   delete fFriendTrack; fFriendTrack = 0;
1334
1335
1336 //_______________________________________________________________________
1337 Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const 
1338 {
1339   // Returns the particle most probable id
1340   Int_t i;
1341   const Double32_t *prob = 0;
1342   if (tpcOnly) { // check if TPCpid is valid
1343     prob = fTPCr;
1344     for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1345     if (i == AliPID::kSPECIES-1) prob = 0; // not valid, try with combined pid
1346   }
1347   if (!prob) { // either requested TPCpid is not valid or comb.pid is requested 
1348     prob = fR;
1349     for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1350     if (i == AliPID::kSPECIES-1) return AliPID::kPion;  // If all the probabilities are equal, return the pion mass
1351   }
1352   //
1353   Float_t max=0.;
1354   Int_t k=-1;
1355   for (i=0; i<AliPID::kSPECIES; i++) if (prob[i]>max) {k=i; max=prob[i];}
1356   //
1357   if (k==0) { // dE/dx "crossing points" in the TPC
1358     Double_t p=GetP();
1359     if ((p>0.38)&&(p<0.48))
1360       if (prob[0]<prob[3]*10.) return AliPID::kKaon;
1361     if ((p>0.75)&&(p<0.85))
1362       if (prob[0]<prob[4]*10.) return AliPID::kProton;
1363     return AliPID::kElectron;
1364   }
1365   if (k==1) return AliPID::kMuon; 
1366   if (k==2||k==-1) return AliPID::kPion;
1367   if (k==3) return AliPID::kKaon;
1368   if (k==4) return AliPID::kProton;
1369   AliWarning("Undefined PID !");
1370   return AliPID::kPion;
1371 }
1372
1373 //_______________________________________________________________________
1374 Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b, Bool_t pidTPConly) const 
1375 {
1376   // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
1377   const double kSpacing = 25e3; // min interbanch spacing
1378   const double kShift = 0;
1379   Int_t bcid = kTOFBCNA; // defualt one
1380   if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
1381   //
1382   double tdif = fTOFsignal;
1383   Double_t times[AliPID::kSPECIESC];
1384   GetIntegratedTimes(times);
1385   if (IsOn(kTIME)) { // integrated time info is there
1386     int pid = GetPID(pidTPConly);
1387
1388     tdif -= times[pid];
1389   }
1390   else { // assume integrated time info from TOF radius and momentum
1391     const double kRTOF = 385.;
1392     const double kCSpeed = 3.e-2; // cm/ps
1393     double p = GetP();
1394     if (p<0.01) return bcid;
1395     double m = GetMass(pidTPConly);
1396     double curv = GetC(b);
1397     double path = TMath::Abs(curv)>kAlmost0 ? // account for curvature
1398       2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+GetTgl()*GetTgl()) : kRTOF;
1399     tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
1400   }
1401   bcid = TMath::Nint((tdif - kShift)/kSpacing);
1402   return bcid;
1403 }
1404
1405 //______________________________________________________________________________
1406 Double_t AliESDtrack::M() const
1407 {
1408   // Returns the assumed mass
1409   // (the pion mass, if the particle can't be identified properly).
1410   static Bool_t printerr=kTRUE;
1411   if (printerr) {
1412      AliWarning("WARNING !!! ... THIS WILL BE PRINTED JUST ONCE !!!");
1413      printerr = kFALSE;
1414      AliWarning("This is the ESD mass. Use it with care !"); 
1415   }
1416   return GetMass(); 
1417 }
1418   
1419 //______________________________________________________________________________
1420 Double_t AliESDtrack::E() const
1421 {
1422   // Returns the energy of the particle given its assumed mass.
1423   // Assumes the pion mass if the particle can't be identified properly.
1424   
1425   Double_t m = M();
1426   Double_t p = P();
1427   return TMath::Sqrt(p*p + m*m);
1428 }
1429
1430 //______________________________________________________________________________
1431 Double_t AliESDtrack::Y() const
1432 {
1433   // Returns the rapidity of a particle given its assumed mass.
1434   // Assumes the pion mass if the particle can't be identified properly.
1435   
1436   Double_t e = E();
1437   Double_t pz = Pz();
1438   if (e != TMath::Abs(pz)) { // energy was not equal to pz
1439     return 0.5*TMath::Log((e+pz)/(e-pz));
1440   } else { // energy was equal to pz
1441     return -999.;
1442   }
1443 }
1444
1445 //_______________________________________________________________________
1446 Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
1447   //
1448   // This function updates track's running parameters 
1449   //
1450   Bool_t rc=kTRUE;
1451
1452   SetStatus(flags);
1453   fLabel=t->GetLabel();
1454
1455   if (t->IsStartedTimeIntegral()) {
1456     SetStatus(kTIME);
1457     Double_t times[AliPID::kSPECIESC];t->GetIntegratedTimes(times); SetIntegratedTimes(times);
1458     SetIntegratedLength(t->GetIntegratedLength());
1459   }
1460
1461   Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1462   if (fFriendTrack) {
1463   if (flags==kITSout) fFriendTrack->SetITSOut(*t);
1464   if (flags==kTPCout) fFriendTrack->SetTPCOut(*t);
1465   if (flags==kTRDrefit) fFriendTrack->SetTRDIn(*t);
1466   }
1467   
1468   switch (flags) {
1469     
1470   case kITSin: 
1471     fITSchi2Std[0] = t->GetChi2();
1472     //
1473   case kITSout: 
1474     fITSchi2Std[1] = t->GetChi2();
1475   case kITSrefit:
1476     {
1477     fITSchi2Std[2] = t->GetChi2();
1478     fITSClusterMap=0;
1479     fITSncls=t->GetNumberOfClusters();
1480     if (fFriendTrack) {
1481     Int_t* indexITS = new Int_t[AliESDfriendTrack::kMaxITScluster];
1482     for (Int_t i=0;i<AliESDfriendTrack::kMaxITScluster;i++) {
1483         indexITS[i]=t->GetClusterIndex(i);
1484
1485         if (i<fITSncls) {
1486           Int_t l=(indexITS[i] & 0xf0000000) >> 28;
1487            SETBIT(fITSClusterMap,l);                 
1488         }
1489     }
1490     fFriendTrack->SetITSIndices(indexITS,AliESDfriendTrack::kMaxITScluster);
1491     delete [] indexITS;
1492     }
1493
1494     fITSchi2=t->GetChi2();
1495     fITSsignal=t->GetPIDsignal();
1496     fITSLabel = t->GetLabel();
1497     // keep in fOp the parameters outside ITS for ITS stand-alone tracks 
1498     if (flags==kITSout) { 
1499       if (!fOp) fOp=new AliExternalTrackParam(*t);
1500       else 
1501         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1502     }   
1503     }
1504     break;
1505     
1506   case kTPCin: case kTPCrefit:
1507     {
1508     fTPCLabel = t->GetLabel();
1509     if (flags==kTPCin)  {
1510       fTPCInner=new AliExternalTrackParam(*t); 
1511       fTPCnclsIter1=t->GetNumberOfClusters();    
1512       fTPCchi2Iter1=t->GetChi2();
1513     }
1514     if (!fIp) fIp=new AliExternalTrackParam(*t);
1515     else 
1516       fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1517     }
1518     // Intentionally no break statement; need to set general TPC variables as well
1519   case kTPCout:
1520     {
1521     if (flags & kTPCout){
1522       if (!fOp) fOp=new AliExternalTrackParam(*t);
1523       else 
1524         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1525     }
1526     fTPCncls=t->GetNumberOfClusters();    
1527     fTPCchi2=t->GetChi2();
1528     
1529     if (fFriendTrack) {  // Copy cluster indices
1530       Int_t* indexTPC = new Int_t[AliESDfriendTrack::kMaxTPCcluster];
1531       for (Int_t i=0;i<AliESDfriendTrack::kMaxTPCcluster;i++)         
1532         indexTPC[i]=t->GetClusterIndex(i);
1533       fFriendTrack->SetTPCIndices(indexTPC,AliESDfriendTrack::kMaxTPCcluster);
1534       delete [] indexTPC;
1535     }
1536     fTPCsignal=t->GetPIDsignal();
1537     }
1538     break;
1539
1540   case kTRDin: case kTRDrefit:
1541     break;
1542   case kTRDout:
1543     {
1544     fTRDLabel = t->GetLabel(); 
1545     fTRDchi2  = t->GetChi2();
1546     fTRDncls  = t->GetNumberOfClusters();
1547     if (fFriendTrack) {
1548       Int_t* indexTRD = new Int_t[AliESDfriendTrack::kMaxTRDcluster];
1549       for (Int_t i=0;i<AliESDfriendTrack::kMaxTRDcluster;i++) indexTRD[i]=-2;
1550       for (Int_t i=0;i<6;i++) indexTRD[i]=t->GetTrackletIndex(i);
1551       fFriendTrack->SetTRDIndices(indexTRD,AliESDfriendTrack::kMaxTRDcluster);
1552       delete [] indexTRD;
1553     }    
1554     
1555     //commented out by Xianguo
1556     //fTRDsignal=t->GetPIDsignal();
1557     }
1558     break;
1559   case kTRDbackup:
1560     if (!fOp) fOp=new AliExternalTrackParam(*t);
1561     else 
1562       fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1563     fTRDncls0 = t->GetNumberOfClusters(); 
1564     break;
1565   case kTOFin: 
1566     break;
1567   case kTOFout: 
1568     break;
1569   case kTRDStop:
1570     break;
1571   case kHMPIDout:
1572   if (!fHMPIDp) fHMPIDp=new AliExternalTrackParam(*t);
1573     else 
1574       fHMPIDp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1575     break;
1576   default: 
1577     AliError("Wrong flag !");
1578     return kFALSE;
1579   }
1580
1581   return rc;
1582 }
1583
1584 //_______________________________________________________________________
1585 void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const {
1586   //---------------------------------------------------------------------
1587   // This function returns external representation of the track parameters
1588   //---------------------------------------------------------------------
1589   x=GetX();
1590   for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i];
1591 }
1592
1593 //_______________________________________________________________________
1594 void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const {
1595   //---------------------------------------------------------------------
1596   // This function returns external representation of the cov. matrix
1597   //---------------------------------------------------------------------
1598   for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i];
1599 }
1600
1601 //_______________________________________________________________________
1602 Bool_t AliESDtrack::GetConstrainedExternalParameters
1603                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1604   //---------------------------------------------------------------------
1605   // This function returns the constrained external track parameters
1606   //---------------------------------------------------------------------
1607   if (!fCp) return kFALSE;
1608   alpha=fCp->GetAlpha();
1609   x=fCp->GetX();
1610   for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i];
1611   return kTRUE;
1612 }
1613
1614 //_______________________________________________________________________
1615 Bool_t 
1616 AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const {
1617   //---------------------------------------------------------------------
1618   // This function returns the constrained external cov. matrix
1619   //---------------------------------------------------------------------
1620   if (!fCp) return kFALSE;
1621   for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i];
1622   return kTRUE;
1623 }
1624
1625 Bool_t
1626 AliESDtrack::GetInnerExternalParameters
1627                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1628   //---------------------------------------------------------------------
1629   // This function returns external representation of the track parameters 
1630   // at the inner layer of TPC
1631   //---------------------------------------------------------------------
1632   if (!fIp) return kFALSE;
1633   alpha=fIp->GetAlpha();
1634   x=fIp->GetX();
1635   for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i];
1636   return kTRUE;
1637 }
1638
1639 Bool_t 
1640 AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const {
1641  //---------------------------------------------------------------------
1642  // This function returns external representation of the cov. matrix 
1643  // at the inner layer of TPC
1644  //---------------------------------------------------------------------
1645   if (!fIp) return kFALSE;
1646   for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i];
1647   return kTRUE;
1648 }
1649
1650 void 
1651 AliESDtrack::SetOuterParam(const AliExternalTrackParam *p, ULong_t flags) {
1652   //
1653   // This is a direct setter for the outer track parameters
1654   //
1655   SetStatus(flags);
1656   if (fOp) delete fOp;
1657   fOp=new AliExternalTrackParam(*p);
1658 }
1659
1660 void 
1661 AliESDtrack::SetOuterHmpParam(const AliExternalTrackParam *p, ULong_t flags) {
1662   //
1663   // This is a direct setter for the outer track parameters
1664   //
1665   SetStatus(flags);
1666   if (fHMPIDp) delete fHMPIDp;
1667   fHMPIDp=new AliExternalTrackParam(*p);
1668 }
1669
1670 Bool_t 
1671 AliESDtrack::GetOuterExternalParameters
1672                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1673   //---------------------------------------------------------------------
1674   // This function returns external representation of the track parameters 
1675   // at the inner layer of TRD
1676   //---------------------------------------------------------------------
1677   if (!fOp) return kFALSE;
1678   alpha=fOp->GetAlpha();
1679   x=fOp->GetX();
1680   for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i];
1681   return kTRUE;
1682 }
1683
1684 Bool_t 
1685 AliESDtrack::GetOuterHmpExternalParameters
1686                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1687   //---------------------------------------------------------------------
1688   // This function returns external representation of the track parameters 
1689   // at the inner layer of TRD
1690   //---------------------------------------------------------------------
1691   if (!fHMPIDp) return kFALSE;
1692   alpha=fHMPIDp->GetAlpha();
1693   x=fHMPIDp->GetX();
1694   for (Int_t i=0; i<5; i++) p[i]=fHMPIDp->GetParameter()[i];
1695   return kTRUE;
1696 }
1697
1698 Bool_t 
1699 AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const {
1700  //---------------------------------------------------------------------
1701  // This function returns external representation of the cov. matrix 
1702  // at the inner layer of TRD
1703  //---------------------------------------------------------------------
1704   if (!fOp) return kFALSE;
1705   for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i];
1706   return kTRUE;
1707 }
1708
1709 Bool_t 
1710 AliESDtrack::GetOuterHmpExternalCovariance(Double_t cov[15]) const {
1711  //---------------------------------------------------------------------
1712  // This function returns external representation of the cov. matrix 
1713  // at the inner layer of TRD
1714  //---------------------------------------------------------------------
1715   if (!fHMPIDp) return kFALSE;
1716   for (Int_t i=0; i<15; i++) cov[i]=fHMPIDp->GetCovariance()[i];
1717   return kTRUE;
1718 }
1719
1720 Int_t AliESDtrack::GetNcls(Int_t idet) const
1721 {
1722   // Get number of clusters by subdetector index
1723   //
1724   Int_t ncls = 0;
1725   switch(idet){
1726   case 0:
1727     ncls = fITSncls;
1728     break;
1729   case 1:
1730     ncls = fTPCncls;
1731     break;
1732   case 2:
1733     ncls = fTRDncls;
1734     break;
1735   case 3:
1736     if (fTOFindex != -1)
1737       ncls = 1;
1738     break;
1739   case 4: //PHOS
1740     break;
1741   case 5: //HMPID
1742     if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1743       if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1744         ncls = 1;
1745       }
1746     }    
1747     break;
1748   default:
1749     break;
1750   }
1751   return ncls;
1752 }
1753
1754 Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
1755 {
1756   // Get cluster index array by subdetector index
1757   //
1758   Int_t ncls = 0;
1759   switch(idet){
1760   case 0:
1761     ncls = GetITSclusters(idx);
1762     break;
1763   case 1:
1764     ncls = GetTPCclusters(idx);
1765     break;
1766   case 2:
1767     ncls = GetTRDclusters(idx);
1768     break;
1769   case 3:
1770     if (fTOFindex != -1) {
1771       idx[0] = fTOFindex;
1772       ncls = 1;
1773     }
1774     break;
1775   case 4: //PHOS
1776     break;
1777   case 5:
1778     if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1779       if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1780         idx[0] = GetHMPIDcluIdx();
1781         ncls = 1;
1782       }
1783     }    
1784     break;
1785   case 6: //EMCAL
1786     break;
1787   default:
1788     break;
1789   }
1790   return ncls;
1791 }
1792
1793 //_______________________________________________________________________
1794 void AliESDtrack::GetIntegratedTimes(Double_t *times) const {
1795   Int_t index = -1;
1796
1797   if(fNtofClusters>0 && GetESDEvent()){
1798     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
1799     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
1800
1801     for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
1802       if(tofcl->GetTrackIndex(i) == GetID()) index = i;
1803     }
1804     if(fNtofClusters>0 && index > -1){
1805       for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=tofcl->GetIntegratedTime(i,index);
1806       return;
1807     }
1808   }
1809   else if(fNtofClusters>0) 
1810     AliInfo("No AliESDEvent available here!\n");
1811
1812   // Returns the array with integrated times for each particle hypothesis
1813   if(fTrackTime)
1814     for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=fTrackTime[i];
1815   else
1816     for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=0.0;
1817 }
1818 //_______________________________________________________________________
1819 Double_t AliESDtrack::GetIntegratedLength() const{
1820   Int_t index = -1;
1821   if(fNtofClusters>0 && GetESDEvent()){
1822     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
1823     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
1824
1825     for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
1826       if(tofcl->GetTrackIndex(i) == GetID()) index = i;
1827     }
1828     
1829     if(fNtofClusters>0 && index > -1)
1830       return tofcl->GetLength(index);
1831   }
1832   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
1833
1834   return fTrackLength;
1835 }
1836
1837 //_______________________________________________________________________
1838 void AliESDtrack::SetIntegratedTimes(const Double_t *times) {
1839   // Sets the array with integrated times for each particle hypotesis
1840   if(!fTrackTime)
1841     fTrackTime = new Double32_t[AliPID::kSPECIESC];
1842   for (Int_t i=0; i<AliPID::kSPECIESC; i++) fTrackTime[i]=times[i];
1843 }
1844
1845 //_______________________________________________________________________
1846 void AliESDtrack::SetITSpid(const Double_t *p) {
1847   // Sets values for the probability of each particle type (in ITS)
1848   SetPIDValues(fITSr,p,AliPID::kSPECIES);
1849   SetStatus(AliESDtrack::kITSpid);
1850 }
1851
1852 //_______________________________________________________________________
1853 void AliESDtrack::GetITSpid(Double_t *p) const {
1854   // Gets the probability of each particle type (in ITS)
1855   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fITSr[i];
1856 }
1857
1858 //_______________________________________________________________________
1859 Char_t AliESDtrack::GetITSclusters(Int_t *idx) const {
1860   //---------------------------------------------------------------------
1861   // This function returns indices of the assgined ITS clusters 
1862   //---------------------------------------------------------------------
1863   if (idx && fFriendTrack) {
1864     Int_t *index=fFriendTrack->GetITSindices();
1865     for (Int_t i=0; i<AliESDfriendTrack::kMaxITScluster; i++) {
1866       if ( (i>=fITSncls) && (i<6) ) idx[i]=-1;
1867       else {
1868         if (index) {
1869           idx[i]=index[i];
1870         }
1871         else idx[i]= -2;
1872       }
1873     }
1874   }
1875   return fITSncls;
1876 }
1877
1878 //_______________________________________________________________________
1879 Bool_t AliESDtrack::GetITSModuleIndexInfo(Int_t ilayer,Int_t &idet,Int_t &status,
1880                                          Float_t &xloc,Float_t &zloc) const {
1881   //----------------------------------------------------------------------
1882   // This function encodes in the module number also the status of cluster association
1883   // "status" can have the following values: 
1884   // 1 "found" (cluster is associated), 
1885   // 2 "dead" (module is dead from OCDB), 
1886   // 3 "skipped" (module or layer forced to be skipped),
1887   // 4 "outinz" (track out of z acceptance), 
1888   // 5 "nocls" (no clusters in the road), 
1889   // 6 "norefit" (cluster rejected during refit), 
1890   // 7 "deadzspd" (holes in z in SPD)
1891   // Also given are the coordinates of the crossing point of track and module
1892   // (in the local module ref. system)
1893   // WARNING: THIS METHOD HAS TO BE SYNCHRONIZED WITH AliITStrackV2::GetModuleIndexInfo()!
1894   //----------------------------------------------------------------------
1895
1896   if(fITSModule[ilayer]==-1) {
1897     idet = -1;
1898     status=0;
1899     xloc=-99.; zloc=-99.;
1900     return kFALSE;
1901   }
1902
1903   Int_t module = fITSModule[ilayer];
1904
1905   idet = Int_t(module/1000000);
1906
1907   module -= idet*1000000;
1908
1909   status = Int_t(module/100000);
1910
1911   module -= status*100000;
1912
1913   Int_t signs = Int_t(module/10000);
1914
1915   module-=signs*10000;
1916
1917   Int_t xInt = Int_t(module/100);
1918   module -= xInt*100;
1919
1920   Int_t zInt = module;
1921
1922   if(signs==1) { xInt*=1; zInt*=1; }
1923   if(signs==2) { xInt*=1; zInt*=-1; }
1924   if(signs==3) { xInt*=-1; zInt*=1; }
1925   if(signs==4) { xInt*=-1; zInt*=-1; }
1926
1927   xloc = 0.1*(Float_t)xInt;
1928   zloc = 0.1*(Float_t)zInt;
1929
1930   if(status==4) idet = -1;
1931
1932   return kTRUE;
1933 }
1934
1935 //_______________________________________________________________________
1936 UShort_t AliESDtrack::GetTPCclusters(Int_t *idx) const {
1937   //---------------------------------------------------------------------
1938   // This function returns indices of the assgined ITS clusters 
1939   //---------------------------------------------------------------------
1940   if (idx && fFriendTrack) {
1941     Int_t *index=fFriendTrack->GetTPCindices();
1942
1943     if (index){
1944       for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=index[i];
1945     }
1946     else {
1947       for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=-2;
1948     }
1949   }
1950   return fTPCncls;
1951 }
1952
1953 //_______________________________________________________________________
1954 Float_t AliESDtrack::GetTPCCrossedRows() const
1955 {
1956   // This function calls GetTPCClusterInfo with some default parameters which are used in the track selection and caches the outcome
1957   // because GetTPCClusterInfo is quite time-consuming
1958   
1959   if (fCacheNCrossedRows > -1)
1960     return fCacheNCrossedRows;
1961   
1962   fCacheNCrossedRows = GetTPCClusterInfo(2, 1);
1963   return fCacheNCrossedRows;
1964 }
1965
1966 //_______________________________________________________________________
1967 Float_t AliESDtrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
1968 {
1969   //
1970   // TPC cluster information
1971   // type 0: get fraction of found/findable clusters with neighbourhood definition
1972   //      1: findable clusters with neighbourhood definition
1973   //      2: found clusters
1974   // bitType:
1975   //      0 - all cluster used
1976   //      1 - clusters  used for the kalman update
1977   // definition of findable clusters:
1978   //            a cluster is defined as findable if there is another cluster
1979   //           within +- nNeighbours pad rows. The idea is to overcome threshold
1980   //           effects with a very simple algorithm.
1981   //
1982
1983   
1984   Int_t found=0;
1985   Int_t findable=0;
1986   Int_t last=-nNeighbours;
1987   const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
1988   
1989   Int_t upperBound=clusterMap.GetNbits();
1990   if (upperBound>row1) upperBound=row1;
1991   for (Int_t i=row0; i<upperBound; ++i){
1992     //look to current row
1993     if (clusterMap[i]) {
1994       last=i;
1995       ++found;
1996       ++findable;
1997       continue;
1998     }
1999     //look to nNeighbours before
2000     if ((i-last)<=nNeighbours) {
2001       ++findable;
2002       continue;
2003     }
2004     //look to nNeighbours after
2005     for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
2006       if (clusterMap[j]){
2007         ++findable;
2008         break;
2009       }
2010     }
2011   }
2012   if (type==2) return found;
2013   if (type==1) return findable;
2014   
2015   if (type==0){
2016     Float_t fraction=0;
2017     if (findable>0) 
2018       fraction=(Float_t)found/(Float_t)findable;
2019     else 
2020       fraction=0;
2021     return fraction;
2022   }  
2023   return 0;  // undefined type - default value
2024 }
2025
2026 //_______________________________________________________________________
2027 Float_t AliESDtrack::GetTPCClusterDensity(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
2028 {
2029   //
2030   // TPC cluster density -  only rows where signal before and after given row are used
2031   //                     -  slower function
2032   // type 0: get fraction of found/findable clusters with neighbourhood definition
2033   //      1: findable clusters with neighbourhood definition
2034   //      2: found clusters
2035   // bitType:
2036   //      0 - all cluster used
2037   //      1 - clusters  used for the kalman update
2038   // definition of findable clusters:
2039   //            a cluster is defined as findable if there is another cluster
2040   //           within +- nNeighbours pad rows. The idea is to overcome threshold
2041   //           effects with a very simple algorithm.
2042   //  
2043   Int_t found=0;
2044   Int_t findable=0;
2045   //  Int_t last=-nNeighbours;
2046   const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
2047   Int_t upperBound=clusterMap.GetNbits();
2048   if (upperBound>row1) upperBound=row1;
2049   for (Int_t i=row0; i<upperBound; ++i){
2050     Bool_t isUp=kFALSE;
2051     Bool_t isDown=kFALSE;
2052     for (Int_t idelta=1; idelta<=nNeighbours; idelta++){
2053       if (i-idelta>=0 && clusterMap[i-idelta]) isDown=kTRUE;
2054       if (i+idelta<upperBound && clusterMap[i+idelta]) isUp=kTRUE;
2055     }
2056     if (isUp&&isDown){
2057       ++findable;
2058       if (clusterMap[i]) ++found;
2059     }
2060   }
2061   if (type==2) return found;
2062   if (type==1) return findable;
2063   
2064   if (type==0){
2065     Float_t fraction=0;
2066     if (findable>0) 
2067       fraction=(Float_t)found/(Float_t)findable;
2068     else 
2069       fraction=0;
2070     return fraction;
2071   }  
2072   return 0;  // undefined type - default value
2073 }
2074
2075
2076
2077
2078 //_______________________________________________________________________
2079 Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
2080   //
2081   // GetDensity of the clusters on given region between row0 and row1
2082   // Dead zone effect takin into acoount
2083   //
2084   if (!fFriendTrack) return 0.0;
2085   Int_t good  = 0;
2086   Int_t found = 0;
2087   //  
2088   Int_t *index=fFriendTrack->GetTPCindices();
2089   for (Int_t i=row0;i<=row1;i++){     
2090     Int_t idx = index[i];
2091     if (idx!=-1)  good++;             // track outside of dead zone
2092     if (idx>0)    found++;
2093   }
2094   Float_t density=0.5;
2095   if (good>TMath::Max((row1-row0)*0.5,0.0)) density = Float_t(found)/Float_t(good);
2096   return density;
2097 }
2098
2099 //_______________________________________________________________________
2100 void AliESDtrack::SetTPCpid(const Double_t *p) {  
2101   // Sets values for the probability of each particle type (in TPC)
2102   SetPIDValues(fTPCr,p,AliPID::kSPECIES);
2103   SetStatus(AliESDtrack::kTPCpid);
2104 }
2105
2106 //_______________________________________________________________________
2107 void AliESDtrack::GetTPCpid(Double_t *p) const {
2108   // Gets the probability of each particle type (in TPC)
2109   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTPCr[i];
2110 }
2111
2112 //_______________________________________________________________________
2113 UChar_t AliESDtrack::GetTRDclusters(Int_t *idx) const {
2114   //---------------------------------------------------------------------
2115   // This function returns indices of the assgined TRD clusters 
2116   //---------------------------------------------------------------------
2117   if (idx && fFriendTrack) {
2118     Int_t *index=fFriendTrack->GetTRDindices();
2119
2120     if (index) {
2121       for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=index[i];
2122     }
2123     else {
2124       for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=-2;
2125     }
2126   }
2127   return fTRDncls;
2128 }
2129
2130 //_______________________________________________________________________
2131 UChar_t AliESDtrack::GetTRDtracklets(Int_t *idx) const {
2132 //
2133 // This function returns the number of TRD tracklets used in tracking
2134 // and it fills the indices of these tracklets in the array "idx" as they 
2135 // are registered in the TRD track list. 
2136 // 
2137 // Caution :
2138 //   1. The idx array has to be allocated with a size >= AliESDtrack::kTRDnPlanes
2139 //   2. The idx array store not only the index but also the layer of the tracklet. 
2140 //      Therefore tracks with TRD gaps contain default values for indices [-1] 
2141
2142   if (!fFriendTrack) return 0;
2143   if (!idx) return GetTRDntracklets();
2144   Int_t *index=fFriendTrack->GetTRDindices();
2145   Int_t n = 0;
2146   for (Int_t i=0; i<kTRDnPlanes; i++){ 
2147     if (index){
2148       if(index[i]>=0) n++;
2149       idx[i]=index[i];
2150     }
2151     else idx[i] = -2;
2152   }
2153   return n;
2154 }
2155
2156 //_______________________________________________________________________
2157 void AliESDtrack::SetTRDpid(const Double_t *p) {  
2158   // Sets values for the probability of each particle type (in TRD)
2159   SetPIDValues(fTRDr,p,AliPID::kSPECIES);
2160   SetStatus(AliESDtrack::kTRDpid);
2161 }
2162
2163 //_______________________________________________________________________
2164 void AliESDtrack::GetTRDpid(Double_t *p) const {
2165   // Gets the probability of each particle type (in TRD)
2166   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTRDr[i];
2167 }
2168
2169 //_______________________________________________________________________
2170 void    AliESDtrack::SetTRDpid(Int_t iSpecies, Float_t p)
2171 {
2172   // Sets the probability of particle type iSpecies to p (in TRD)
2173   fTRDr[iSpecies] = p;
2174 }
2175
2176 Double_t AliESDtrack::GetTRDpid(Int_t iSpecies) const
2177 {
2178   // Returns the probability of particle type iSpecies (in TRD)
2179   return fTRDr[iSpecies];
2180 }
2181
2182 //____________________________________________________
2183 Int_t AliESDtrack::GetNumberOfTRDslices() const 
2184 {
2185   // built in backward compatibility
2186   Int_t idx = fTRDnSlices - (kTRDnPlanes<<1);
2187   return idx<18 ? fTRDnSlices/kTRDnPlanes : idx/kTRDnPlanes;
2188 }
2189
2190 //____________________________________________________
2191 Double_t AliESDtrack::GetTRDmomentum(Int_t plane, Double_t *sp) const
2192 {
2193 //Returns momentum estimation and optional its error (sp)
2194 // in TRD layer "plane".
2195
2196   if (!fTRDnSlices) {
2197     AliDebug(2, "No TRD info allocated for this track.");
2198     return -1.;
2199   }
2200   if ((plane<0) || (plane>=kTRDnPlanes)) {
2201     AliWarning(Form("Request for TRD plane[%d] outside range.", plane)); 
2202     return -1.;
2203   }
2204
2205   Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2206   // Protection for backward compatibility
2207   if(idx<(GetNumberOfTRDslices()*kTRDnPlanes)) return -1.;
2208
2209   if(sp) (*sp) = fTRDslices[idx+kTRDnPlanes];
2210   return fTRDslices[idx];
2211 }
2212
2213 //____________________________________________________
2214 Double_t  AliESDtrack::GetTRDslice(Int_t plane, Int_t slice) const {
2215   //Gets the charge from the slice of the plane
2216
2217   if(!fTRDslices) {
2218     //AliError("No TRD slices allocated for this track !");
2219     return -1.;
2220   }
2221   if ((plane<0) || (plane>=kTRDnPlanes)) {
2222     AliError("Info for TRD plane not available !");
2223     return -1.;
2224   }
2225   Int_t ns=GetNumberOfTRDslices();
2226   if ((slice<-1) || (slice>=ns)) {
2227     //AliError("Wrong TRD slice !");  
2228     return -1.;
2229   }
2230
2231   if(slice>=0) return fTRDslices[plane*ns + slice];
2232
2233   // return average of the dEdx measurements
2234   Double_t q=0.; Double32_t *s = &fTRDslices[plane*ns];
2235   for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
2236   return q/ns;
2237 }
2238
2239 //____________________________________________________
2240 void  AliESDtrack::SetNumberOfTRDslices(Int_t n) {
2241   //Sets the number of slices used for PID 
2242   if (fTRDnSlices) return;
2243
2244   fTRDnSlices=n;
2245   fTRDslices=new Double32_t[fTRDnSlices];
2246   
2247   // set-up correctly the allocated memory
2248   memset(fTRDslices, 0, n*sizeof(Double32_t));
2249   for (Int_t i=GetNumberOfTRDslices(); i--;) fTRDslices[i]=-1.;
2250 }
2251
2252 //____________________________________________________
2253 void  AliESDtrack::SetTRDslice(Double_t q, Int_t plane, Int_t slice) {
2254   //Sets the charge q in the slice of the plane
2255   if(!fTRDslices) {
2256     AliError("No TRD slices allocated for this track !");
2257     return;
2258   }
2259   if ((plane<0) || (plane>=kTRDnPlanes)) {
2260     AliError("Info for TRD plane not allocated !");
2261     return;
2262   }
2263   Int_t ns=GetNumberOfTRDslices();
2264   if ((slice<0) || (slice>=ns)) {
2265     AliError(Form("Wrong TRD slice %d/%d, NSlices=%d",plane,slice,ns));
2266     return;
2267   }
2268   Int_t n=plane*ns + slice;
2269   fTRDslices[n]=q;
2270 }
2271
2272
2273 //____________________________________________________
2274 void AliESDtrack::SetTRDmomentum(Double_t p, Int_t plane, Double_t *sp)
2275 {
2276   if(!fTRDslices) {
2277     AliError("No TRD slices allocated for this track !");
2278     return;
2279   }
2280   if ((plane<0) || (plane>=kTRDnPlanes)) {
2281     AliError("Info for TRD plane not allocated !");
2282     return;
2283   }
2284
2285   Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2286   // Protection for backward compatibility
2287   if(idx<GetNumberOfTRDslices()*kTRDnPlanes) return;
2288
2289   if(sp) fTRDslices[idx+kTRDnPlanes] = (*sp);
2290   fTRDslices[idx] = p;
2291 }
2292
2293
2294 //_______________________________________________________________________
2295 void AliESDtrack::SetTOFpid(const Double_t *p) {  
2296   // Sets the probability of each particle type (in TOF)
2297   SetPIDValues(fTOFr,p,AliPID::kSPECIES);
2298   SetStatus(AliESDtrack::kTOFpid);
2299 }
2300
2301 //_______________________________________________________________________
2302 void AliESDtrack::SetTOFLabel(const Int_t *p) {  
2303   // Sets  (in TOF)
2304   if(!fTOFLabel) fTOFLabel = new Int_t[3]; 
2305   for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
2306 }
2307
2308 //_______________________________________________________________________
2309 void AliESDtrack::GetTOFpid(Double_t *p) const {
2310   // Gets probabilities of each particle type (in TOF)
2311   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTOFr[i];
2312 }
2313
2314 //_______________________________________________________________________
2315 void AliESDtrack::GetTOFLabel(Int_t *p) const {
2316   // Gets (in TOF)
2317   if(fNtofClusters>0){
2318     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2319     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2320
2321     for (Int_t i=0; i<3; i++) p[i]=tofcl->GetLabel(i);
2322   }
2323   else{
2324     if(fTOFLabel)
2325       for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
2326   }
2327 }
2328
2329 //_______________________________________________________________________
2330 void AliESDtrack::GetTOFInfo(Float_t *info) const {
2331   // Gets (in TOF)
2332   for (Int_t i=0; i<10; i++) info[i]=fTOFInfo[i];
2333 }
2334
2335 //_______________________________________________________________________
2336 void AliESDtrack::SetTOFInfo(Float_t*info) {
2337   // Gets (in TOF)
2338   for (Int_t i=0; i<10; i++) fTOFInfo[i]=info[i];
2339 }
2340
2341
2342
2343 //_______________________________________________________________________
2344 void AliESDtrack::SetHMPIDpid(const Double_t *p) {  
2345   // Sets the probability of each particle type (in HMPID)
2346   SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
2347   SetStatus(AliESDtrack::kHMPIDpid);
2348 }
2349
2350 //_______________________________________________________________________
2351 void  AliESDtrack::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo){ 
2352   if(fTPCdEdxInfo) delete fTPCdEdxInfo;
2353   fTPCdEdxInfo = dEdxInfo; 
2354 }
2355
2356 //_______________________________________________________________________
2357 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
2358   // Gets probabilities of each particle type (in HMPID)
2359   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fHMPIDr[i];
2360 }
2361
2362
2363
2364 //_______________________________________________________________________
2365 void AliESDtrack::SetESDpid(const Double_t *p) {  
2366   // Sets the probability of each particle type for the ESD track
2367   SetPIDValues(fR,p,AliPID::kSPECIES);
2368   SetStatus(AliESDtrack::kESDpid);
2369 }
2370
2371 //_______________________________________________________________________
2372 void AliESDtrack::GetESDpid(Double_t *p) const {
2373   // Gets probability of each particle type for the ESD track
2374   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fR[i];
2375 }
2376
2377 //_______________________________________________________________________
2378 Bool_t AliESDtrack::RelateToVertexTPC(const AliESDVertex *vtx, 
2379 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2380   //
2381   // Try to relate the TPC-only track parameters to the vertex "vtx", 
2382   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2383   //            Magnetic field is "b" (kG).
2384   //
2385   // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2386   // b) The impact parameters and their covariance matrix are calculated.
2387   // c) An attempt to constrain the TPC-only params to the vertex is done.
2388   //    The constrained params are returned via "cParam".
2389   //
2390   // In the case of success, the returned value is kTRUE
2391   // otherwise, it's kFALSE)
2392   // 
2393
2394   if (!fTPCInner) return kFALSE;
2395   if (!vtx) return kFALSE;
2396
2397   Double_t dz[2],cov[3];
2398   if (!fTPCInner->PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2399
2400   fdTPC = dz[0];
2401   fzTPC = dz[1];  
2402   fCddTPC = cov[0];
2403   fCdzTPC = cov[1];
2404   fCzzTPC = cov[2];
2405   
2406   Double_t covar[6]; vtx->GetCovMatrix(covar);
2407   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2408   Double_t c[3]={covar[2],0.,covar[5]};
2409
2410   Double_t chi2=GetPredictedChi2(p,c);
2411   if (chi2>kVeryBig) return kFALSE;
2412
2413   fCchi2TPC=chi2;
2414
2415   if (!cParam) return kTRUE;
2416
2417   *cParam = *fTPCInner;
2418   if (!cParam->Update(p,c)) return kFALSE;
2419
2420   return kTRUE;
2421 }
2422
2423 //_______________________________________________________________________
2424 Bool_t AliESDtrack::RelateToVertexTPCBxByBz(const AliESDVertex *vtx, 
2425 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2426   //
2427   // Try to relate the TPC-only track parameters to the vertex "vtx", 
2428   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2429   //
2430   // All three components of the magnetic field ,"b[3]" (kG), 
2431   // are taken into account.
2432   //
2433   // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2434   // b) The impact parameters and their covariance matrix are calculated.
2435   // c) An attempt to constrain the TPC-only params to the vertex is done.
2436   //    The constrained params are returned via "cParam".
2437   //
2438   // In the case of success, the returned value is kTRUE
2439   // otherwise, it's kFALSE)
2440   // 
2441
2442   if (!fTPCInner) return kFALSE;
2443   if (!vtx) return kFALSE;
2444
2445   Double_t dz[2],cov[3];
2446   if (!fTPCInner->PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2447
2448   fdTPC = dz[0];
2449   fzTPC = dz[1];  
2450   fCddTPC = cov[0];
2451   fCdzTPC = cov[1];
2452   fCzzTPC = cov[2];
2453   
2454   Double_t covar[6]; vtx->GetCovMatrix(covar);
2455   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2456   Double_t c[3]={covar[2],0.,covar[5]};
2457
2458   Double_t chi2=GetPredictedChi2(p,c);
2459   if (chi2>kVeryBig) return kFALSE;
2460
2461   fCchi2TPC=chi2;
2462
2463   if (!cParam) return kTRUE;
2464
2465   *cParam = *fTPCInner;
2466   if (!cParam->Update(p,c)) return kFALSE;
2467
2468   return kTRUE;
2469 }
2470
2471 //_______________________________________________________________________
2472 Bool_t AliESDtrack::RelateToVertex(const AliESDVertex *vtx, 
2473 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2474   //
2475   // Try to relate this track to the vertex "vtx", 
2476   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2477   //            Magnetic field is "b" (kG).
2478   //
2479   // a) The track gets extapolated to the DCA to the vertex.
2480   // b) The impact parameters and their covariance matrix are calculated.
2481   // c) An attempt to constrain this track to the vertex is done.
2482   //    The constrained params are returned via "cParam".
2483   //
2484   // In the case of success, the returned value is kTRUE
2485   // (otherwise, it's kFALSE)
2486   //  
2487
2488   if (!vtx) return kFALSE;
2489
2490   Double_t dz[2],cov[3];
2491   if (!PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2492
2493   fD = dz[0];
2494   fZ = dz[1];  
2495   fCdd = cov[0];
2496   fCdz = cov[1];
2497   fCzz = cov[2];
2498   
2499   Double_t covar[6]; vtx->GetCovMatrix(covar);
2500   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2501   Double_t c[3]={covar[2],0.,covar[5]};
2502
2503   Double_t chi2=GetPredictedChi2(p,c);
2504   if (chi2>kVeryBig) return kFALSE;
2505
2506   fCchi2=chi2;
2507
2508
2509   //--- Could now these lines be removed ? ---
2510   delete fCp;
2511   fCp=new AliExternalTrackParam(*this);  
2512
2513   if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2514   //----------------------------------------
2515
2516   fVertexID = vtx->GetID();
2517
2518   if (!cParam) return kTRUE;
2519
2520   *cParam = *this;
2521   if (!cParam->Update(p,c)) return kFALSE; 
2522
2523   return kTRUE;
2524 }
2525
2526 //_______________________________________________________________________
2527 Bool_t AliESDtrack::RelateToVertexBxByBz(const AliESDVertex *vtx, 
2528 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2529   //
2530   // Try to relate this track to the vertex "vtx", 
2531   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2532   //            Magnetic field is "b" (kG).
2533   //
2534   // a) The track gets extapolated to the DCA to the vertex.
2535   // b) The impact parameters and their covariance matrix are calculated.
2536   // c) An attempt to constrain this track to the vertex is done.
2537   //    The constrained params are returned via "cParam".
2538   //
2539   // In the case of success, the returned value is kTRUE
2540   // (otherwise, it's kFALSE)
2541   //  
2542
2543   if (!vtx) return kFALSE;
2544
2545   Double_t dz[2],cov[3];
2546   if (!PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2547
2548   fD = dz[0];
2549   fZ = dz[1];  
2550   fCdd = cov[0];
2551   fCdz = cov[1];
2552   fCzz = cov[2];
2553   
2554   Double_t covar[6]; vtx->GetCovMatrix(covar);
2555   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2556   Double_t c[3]={covar[2],0.,covar[5]};
2557
2558   Double_t chi2=GetPredictedChi2(p,c);
2559   if (chi2>kVeryBig) return kFALSE;
2560
2561   fCchi2=chi2;
2562
2563
2564   //--- Could now these lines be removed ? ---
2565   delete fCp;
2566   fCp=new AliExternalTrackParam(*this);  
2567
2568   if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2569   //----------------------------------------
2570
2571   fVertexID = vtx->GetID();
2572
2573   if (!cParam) return kTRUE;
2574
2575   *cParam = *this;
2576   if (!cParam->Update(p,c)) return kFALSE; 
2577
2578   return kTRUE;
2579 }
2580
2581 //_______________________________________________________________________
2582 void AliESDtrack::Print(Option_t *) const {
2583   // Prints info on the track
2584   AliExternalTrackParam::Print();
2585   printf("ESD track info\n") ; 
2586   Double_t p[AliPID::kSPECIES] ;
2587   Int_t index = 0 ; 
2588   if( IsOn(kITSpid) ){
2589     printf("From ITS: ") ; 
2590     GetITSpid(p) ; 
2591     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2592       printf("%f, ", p[index]) ;
2593     printf("\n           signal = %f\n", GetITSsignal()) ;
2594   } 
2595   if( IsOn(kTPCpid) ){
2596     printf("From TPC: ") ; 
2597     GetTPCpid(p) ; 
2598     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2599       printf("%f, ", p[index]) ;
2600     printf("\n           signal = %f\n", GetTPCsignal()) ;
2601   }
2602   if( IsOn(kTRDpid) ){
2603     printf("From TRD: ") ; 
2604     GetTRDpid(p) ; 
2605     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2606       printf("%f, ", p[index]) ;
2607       printf("\n           signal = %f\n", GetTRDsignal()) ;
2608       printf("\n           NchamberdEdx = %d\n", GetTRDNchamberdEdx()) ;
2609       printf("\n           NclusterdEdx = %d\n", GetTRDNclusterdEdx()) ;
2610   }
2611   if( IsOn(kTOFpid) ){
2612     printf("From TOF: ") ; 
2613     GetTOFpid(p) ; 
2614     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2615       printf("%f, ", p[index]) ;
2616     printf("\n           signal = %f\n", GetTOFsignal()) ;
2617   }
2618   if( IsOn(kHMPIDpid) ){
2619     printf("From HMPID: ") ; 
2620     GetHMPIDpid(p) ; 
2621     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2622       printf("%f, ", p[index]) ;
2623     printf("\n           signal = %f\n", GetHMPIDsignal()) ;
2624   }
2625
2626
2627
2628 //
2629 // Draw functionality
2630 // Origin: Marian Ivanov, Marian.Ivanov@cern.ch
2631 //
2632 void AliESDtrack::FillPolymarker(TPolyMarker3D *pol, Float_t magF, Float_t minR, Float_t maxR, Float_t stepR){
2633   //
2634   // Fill points in the polymarker
2635   //
2636   TObjArray arrayRef;
2637   arrayRef.AddLast(new AliExternalTrackParam(*this));
2638   if (fIp) arrayRef.AddLast(new AliExternalTrackParam(*fIp));
2639   if (fOp) arrayRef.AddLast(new AliExternalTrackParam(*fOp));
2640   if (fHMPIDp) arrayRef.AddLast(new AliExternalTrackParam(*fHMPIDp));
2641   //
2642   Double_t mpos[3]={0,0,0};
2643   Int_t entries=arrayRef.GetEntries();
2644   for (Int_t i=0;i<entries;i++){
2645     Double_t pos[3];
2646     ((AliExternalTrackParam*)arrayRef.At(i))->GetXYZ(pos);
2647     mpos[0]+=pos[0]/entries;
2648     mpos[1]+=pos[1]/entries;
2649     mpos[2]+=pos[2]/entries;    
2650   }
2651   // Rotate to the mean position
2652   //
2653   Float_t fi= TMath::ATan2(mpos[1],mpos[0]);
2654   for (Int_t i=0;i<entries;i++){
2655     Bool_t res = ((AliExternalTrackParam*)arrayRef.At(i))->Rotate(fi);
2656     if (!res) delete arrayRef.RemoveAt(i);
2657   }
2658   Int_t counter=0;
2659   for (Double_t r=minR; r<maxR; r+=stepR){
2660     Double_t sweight=0;
2661     Double_t mlpos[3]={0,0,0};
2662     for (Int_t i=0;i<entries;i++){
2663       Double_t point[3]={0,0,0};
2664       AliExternalTrackParam *param = ((AliExternalTrackParam*)arrayRef.At(i));
2665       if (!param) continue;
2666       if (param->GetXYZAt(r,magF,point)){
2667         Double_t weight = 1./(10.+(r-param->GetX())*(r-param->GetX()));
2668         sweight+=weight;
2669         mlpos[0]+=point[0]*weight;
2670         mlpos[1]+=point[1]*weight;
2671         mlpos[2]+=point[2]*weight;
2672       }
2673     }
2674     if (sweight>0){
2675       mlpos[0]/=sweight;
2676       mlpos[1]/=sweight;
2677       mlpos[2]/=sweight;      
2678       pol->SetPoint(counter,mlpos[0],mlpos[1], mlpos[2]);
2679       //      printf("xyz\t%f\t%f\t%f\n",mlpos[0], mlpos[1],mlpos[2]);
2680       counter++;
2681     }
2682   }
2683 }
2684
2685 //_______________________________________________________________________
2686 void AliESDtrack::SetITSdEdxSamples(const Double_t s[4]) {
2687   //
2688   // Store the dE/dx samples measured by the two SSD and two SDD layers.
2689   // These samples are corrected for the track segment length. 
2690   //
2691   for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
2692 }
2693
2694 //_______________________________________________________________________
2695 void AliESDtrack::GetITSdEdxSamples(Double_t s[4]) const {
2696   //
2697   // Get the dE/dx samples measured by the two SSD and two SDD layers.  
2698   // These samples are corrected for the track segment length.
2699   //
2700   for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
2701 }
2702
2703
2704 UShort_t   AliESDtrack::GetTPCnclsS(Int_t i0,Int_t i1) const{
2705   //
2706   // get number of shared TPC clusters
2707   //
2708   return  fTPCSharedMap.CountBits(i0)-fTPCSharedMap.CountBits(i1);
2709 }
2710
2711 UShort_t   AliESDtrack::GetTPCncls(Int_t i0,Int_t i1) const{
2712   //
2713   // get number of TPC clusters
2714   //
2715   return  fTPCClusterMap.CountBits(i0)-fTPCClusterMap.CountBits(i1);
2716 }
2717
2718 //____________________________________________________________________
2719 Double_t AliESDtrack::GetChi2TPCConstrainedVsGlobal(const AliESDVertex* vtx) const
2720 {
2721   // Calculates the chi2 between the TPC track (TPCinner) constrained to the primary vertex and the global track
2722   //
2723   // Returns -1 in case the calculation failed
2724   //
2725   // Value is cached as a non-persistent member.
2726   //
2727   // Code adapted from original code by GSI group (Jacek, Marian, Michael)
2728   
2729   // cache, ignoring that a different vertex might be passed
2730   if (fCacheChi2TPCConstrainedVsGlobalVertex == vtx)
2731     return fCacheChi2TPCConstrainedVsGlobal;
2732   
2733   fCacheChi2TPCConstrainedVsGlobal = -1;
2734   fCacheChi2TPCConstrainedVsGlobalVertex = vtx;
2735   
2736   Double_t x[3];
2737   GetXYZ(x);
2738   Double_t b[3];
2739   AliTrackerBase::GetBxByBz(x,b);
2740
2741   if (!fTPCInner)  { 
2742     AliWarning("Could not get TPC Inner Param.");
2743     return fCacheChi2TPCConstrainedVsGlobal;
2744   }
2745   
2746   // clone for constraining
2747   AliExternalTrackParam* tpcInnerC = new AliExternalTrackParam(*fTPCInner);
2748   if (!tpcInnerC) { 
2749     AliWarning("Clone of TPCInnerParam failed.");
2750     return fCacheChi2TPCConstrainedVsGlobal;  
2751   }
2752   
2753   // transform to the track reference frame 
2754   Bool_t isOK = tpcInnerC->Rotate(GetAlpha());
2755   isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2756   if (!isOK) { 
2757     delete tpcInnerC;
2758     tpcInnerC = 0; 
2759     AliWarning("Rotation/Propagation of track failed.") ; 
2760     return fCacheChi2TPCConstrainedVsGlobal;    
2761   }  
2762
2763   // constrain TPCinner 
2764   isOK = tpcInnerC->ConstrainToVertex(vtx, b);
2765   
2766   // transform to the track reference frame 
2767   isOK &= tpcInnerC->Rotate(GetAlpha());
2768   isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2769
2770   if (!isOK) {
2771     AliWarning("ConstrainTPCInner failed.") ;
2772     delete tpcInnerC;
2773     tpcInnerC = 0; 
2774     return fCacheChi2TPCConstrainedVsGlobal;  
2775   }
2776   
2777   // calculate chi2 between vi and vj vectors
2778   // with covi and covj covariance matrices
2779   // chi2ij = (vi-vj)^(T)*(covi+covj)^(-1)*(vi-vj)
2780   TMatrixD deltaT(5,1);
2781   TMatrixD delta(1,5);
2782   TMatrixD covarM(5,5);
2783
2784   for (Int_t ipar=0; ipar<5; ipar++) {
2785     deltaT(ipar,0) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2786     delta(0,ipar) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2787
2788     for (Int_t jpar=0; jpar<5; jpar++) {
2789       Int_t index = GetIndex(ipar,jpar);
2790       covarM(ipar,jpar) = GetCovariance()[index]+tpcInnerC->GetCovariance()[index];
2791     }
2792   }
2793   // chi2 distance TPC constrained and TPC+ITS
2794   TMatrixD covarMInv = covarM.Invert();
2795   TMatrixD mat2 = covarMInv*deltaT;
2796   TMatrixD chi2 = delta*mat2; 
2797   
2798   delete tpcInnerC; 
2799   tpcInnerC = 0;
2800   
2801   fCacheChi2TPCConstrainedVsGlobal = chi2(0,0);
2802   return fCacheChi2TPCConstrainedVsGlobal;
2803 }
2804
2805 void AliESDtrack::SetDetectorPID(const AliDetectorPID *pid)
2806 {
2807   //
2808   // Set the detector PID
2809   //
2810   if (fDetectorPID) delete fDetectorPID;
2811   fDetectorPID=pid;
2812   
2813 }
2814
2815 Double_t AliESDtrack::GetLengthInActiveZone( Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
2816   //
2817   // Input parameters:
2818   //   mode  - type of external track parameters 
2819   //   deltaY - user defined "dead region" in cm
2820   //   deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2821   //   bz     - magnetic field 
2822   //   exbPhi - optional rotation due to the ExB effect
2823   // return value:
2824   //   the length of the track in cm in "active volume" of the TPC
2825   //
2826   if (mode==0) return GetLengthInActiveZone(this, deltaY,deltaZ,bz, exbPhi,pcstream);
2827   if (mode==1) return GetLengthInActiveZone(fIp, deltaY,deltaZ,bz, exbPhi,pcstream);
2828   if (mode==2) return GetLengthInActiveZone(fOp, deltaY,deltaZ,bz, exbPhi,pcstream);
2829   return 0;
2830 }
2831
2832 Double_t AliESDtrack::GetLengthInActiveZone(const AliExternalTrackParam  *paramT, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
2833   //
2834   // Numerical code to calculate the length of the track in active region of the TPC
2835   // ( can be speed up if somebody wants to invest time - analysical version shoult be possible) 
2836   //
2837   // Input parameters:
2838   //   paramT - external track parameters 
2839   //   deltaY - user defined "dead region" in cm
2840   //   deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2841   //   bz     - magnetic field 
2842   //   exbPhi - optional rotation due to the ExB effect
2843   // return value:
2844   //   the length of the track in cm in "active volume" of the TPC
2845   //
2846   const Double_t rIn=85;
2847   const Double_t rOut=245;
2848   Double_t xyz[3], pxyz[3];
2849   if (paramT->GetXYZAt(rIn,bz,xyz)){
2850     paramT->GetPxPyPzAt(rIn,bz,pxyz);
2851   }else{
2852     paramT->GetXYZ(xyz);
2853     paramT->GetPxPyPz(pxyz);
2854   }
2855   //
2856   Double_t dca   = -paramT->GetD(0,0,bz);  // get impact parameter distance to point (0,0)
2857   Double_t radius= TMath::Abs(1/paramT->GetC(bz));  //
2858   Double_t sign  = paramT->GetSign();
2859   Double_t R0    = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);   // radius at current point
2860   Double_t phiR0 = TMath::ATan2(xyz[1],xyz[0]);                // angle of given point
2861   Double_t dPhiR0= -TMath::ASin((dca*dca-2*dca*radius*sign+R0*R0)/(2*R0*(dca-radius*sign)));
2862   Double_t phi0  = phiR0-(dPhiR0);  // global phi offset to be added
2863   //
2864   //
2865   AliExternalTrackParam paramR=(*paramT);
2866   Double_t length=0;
2867   for (Double_t R=rIn; R<=rOut; R++){
2868     Double_t sinPhi=(dca*dca-2*dca*radius*sign+R*R)/(2*R*(dca-radius*sign));
2869     if (TMath::Abs(sinPhi)>=1) continue;
2870     Double_t dphi     = -TMath::ASin(sinPhi);
2871     Double_t phi      = phi0+dphi;                           // global phi
2872     Int_t    sector   = TMath::Nint(9*phi/(TMath::Pi()));
2873     Double_t dPhiEdge = phi-(sector*TMath::Pi()/9)+exbPhi;   // distance to sector boundary in rphi
2874     Double_t dX   = R*TMath::Cos(phi)-xyz[0];
2875     Double_t dY   = R*TMath::Sin(phi)-xyz[1];
2876     Double_t deltaPhi = 2*TMath::ASin(0.5*TMath::Sqrt(dX*dX+dY*dY)/radius);
2877     Double_t z = xyz[2]+deltaPhi*radius*paramT->GetTgl();
2878     if (TMath::Abs(dPhiEdge*R)>deltaY && TMath::Abs(z)<deltaZ){
2879       length++;
2880     }
2881     //    Double_t deltaZ= dphi*radius; 
2882     if (pcstream){
2883       //should we keep debug possibility ?
2884       AliExternalTrackParam paramTcopy=(*paramT);
2885       paramR.Rotate(phi);
2886       paramR.PropagateTo(R,bz);
2887       (*pcstream)<<"debugEdge"<<
2888         "R="<<R<<                   // radius
2889         "dphiEdge="<<dPhiEdge<<     // distance to edge 
2890         "phi0="<<phi0<<             // phi0 -phi at the track initial position
2891         "phi="<<phi<<               // 
2892         "z="<<z<<
2893         "pT.="<<&paramTcopy<<
2894         "pR.="<<&paramR<<
2895         "\n";
2896     }
2897   }
2898   return length;
2899 }
2900
2901 void    AliESDtrack::SetTOFclusterArray(Int_t ncluster,Int_t *TOFcluster){
2902   AliInfo("Method has to be implemented!");
2903 //   fNtofClusters=ncluster;
2904 //   if(TOFcluster == fTOFcluster) return;
2905 //   if(fTOFcluster){ // reset previous content    
2906 //     delete[] fTOFcluster;
2907 //     fTOFcluster = NULL;
2908 //     fNtofClusters=0;
2909 //   }
2910
2911 //   if(ncluster){ // set new content
2912 //     fTOFcluster = new Int_t[fNtofClusters];
2913 //     for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = TOFcluster[i];
2914 //   }
2915 //   else
2916 //     fTOFcluster = 0;
2917 }
2918
2919 void    AliESDtrack::AddTOFcluster(Int_t icl){
2920   fNtofClusters++;
2921   
2922   Int_t *old = fTOFcluster;
2923   fTOFcluster = new Int_t[fNtofClusters];
2924
2925   for(Int_t i=0;i < fNtofClusters-1;i++) fTOFcluster[i] = old[i];
2926   fTOFcluster[fNtofClusters-1] = icl;
2927
2928   if(fNtofClusters-1){ // delete previous content    
2929     delete old;
2930     old = NULL;
2931   }
2932  
2933 }
2934
2935 Double_t AliESDtrack::GetTOFsignal() const {
2936   if(fNtofClusters>0 && GetESDEvent()){
2937     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2938     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2939
2940     return tofcl->GetTime();
2941   }
2942   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2943
2944   return fTOFsignal;
2945 }
2946
2947 Double_t AliESDtrack::GetTOFsignalToT() const 
2948 {
2949   if(fNtofClusters>0 && GetESDEvent()){
2950     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2951     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2952
2953     return tofcl->GetTOT();
2954   }
2955   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2956
2957   return fTOFsignalToT;
2958 }
2959
2960 Double_t AliESDtrack::GetTOFsignalRaw() const 
2961 {
2962   if(fNtofClusters>0 && GetESDEvent()){
2963     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2964     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2965
2966     return tofcl->GetTimeRaw();
2967   }
2968   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2969
2970   return fTOFsignalRaw;
2971 }
2972
2973 Double_t AliESDtrack::GetTOFsignalDz() const 
2974 {
2975
2976   AliESDTOFcluster *tofcl;
2977
2978   Int_t index = -1;
2979   if(fNtofClusters>0 && GetESDEvent()){
2980     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
2981     tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
2982
2983     for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
2984       if(tofcl->GetTrackIndex(i) == GetID()) index = i;
2985     }
2986   }
2987   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
2988
2989   if(fNtofClusters>0 && index > -1){
2990     return tofcl->GetDz(index);
2991   }
2992   return fTOFsignalDz;
2993 }
2994
2995 Double_t AliESDtrack::GetTOFsignalDx() const 
2996 {
2997   AliESDTOFcluster *tofcl;
2998
2999   Int_t index = -1;
3000   if(fNtofClusters>0 && GetESDEvent()){
3001     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3002     tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3003     for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3004       if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3005     }
3006   }
3007   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3008   if(fNtofClusters>0 && index > -1){
3009     return tofcl->GetDx(index);
3010   }
3011   return fTOFsignalDx;
3012 }
3013
3014 Short_t  AliESDtrack::GetTOFDeltaBC() const 
3015 {
3016   if(fNtofClusters>0 && GetESDEvent()){
3017     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3018     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3019     return tofcl->GetDeltaBC();
3020   }
3021   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3022
3023   return fTOFdeltaBC;
3024 }
3025
3026 Short_t  AliESDtrack::GetTOFL0L1() const 
3027 {
3028   if(fNtofClusters>0 && GetESDEvent()){
3029     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3030     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3031
3032     return tofcl->GetL0L1Latency();
3033   }
3034   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3035
3036   return fTOFl0l1;
3037 }
3038
3039 Int_t   AliESDtrack::GetTOFCalChannel() const 
3040 {
3041   if(fNtofClusters>0 && GetESDEvent()){
3042     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3043     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3044
3045     tofcl->GetTOFchannel();
3046   }
3047   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3048
3049   return fTOFCalChannel;
3050 }
3051
3052 Int_t   AliESDtrack::GetTOFcluster() const 
3053 {
3054   if(fNtofClusters>0 && GetESDEvent()){
3055     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3056     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3057
3058     tofcl->GetClusterIndex();
3059   }
3060   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3061
3062   return fTOFindex;
3063 }
3064
3065 Int_t   AliESDtrack::GetTOFclusterN() const
3066 {
3067   return fNtofClusters;
3068 }
3069
3070 Bool_t  AliESDtrack::IsTOFHitAlreadyMatched() const{
3071   if(fNtofClusters>0 && GetESDEvent()){
3072     TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3073     AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
3074
3075     if (tofcl->GetNMatchableTracks() > 1)
3076       return kTRUE;
3077   }
3078   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3079
3080   return kFALSE;
3081 }
3082
3083 void AliESDtrack::ReMapTOFcluster(Int_t ncl,Int_t *mapping){
3084   for(Int_t i=0;i<fNtofClusters;i++){
3085     if(fTOFcluster[i]<ncl && fTOFcluster[i]>-1)
3086       fTOFcluster[i] = mapping[fTOFcluster[i]];
3087     else
3088       AliInfo(Form("TOF cluster re-mapping in AliESDtrack: out of range (%i > %i)\n",fTOFcluster[i],ncl));
3089   }
3090 }
3091
3092 void AliESDtrack::SortTOFcluster(){
3093   TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
3094
3095   for(Int_t i=0;i<fNtofClusters-1;i++){
3096     for(Int_t j=i+1;j<fNtofClusters;j++){
3097       AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[i]);
3098       Int_t index1 = -1;
3099       for(Int_t it=0;it < tofcl->GetNMatchableTracks();it++){
3100          if(tofcl->GetTrackIndex(it) == GetID()) index1 = it;
3101       }
3102       Double_t timedist1 = 10000;
3103       for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3104         Double_t timec = TMath::Abs(tofcl->GetTime() - tofcl->GetIntegratedTime(isp));
3105         if(timec < timedist1) timedist1 = timec;
3106       }
3107       timedist1 *= 0.03; // in cm
3108       Double_t radius1 = tofcl->GetDx(index1)*tofcl->GetDx(index1) + tofcl->GetDz(index1)*tofcl->GetDz(index1) + timedist1*timedist1;
3109
3110       AliESDTOFcluster *tofcl2 = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[j]);
3111       Int_t index2 = -1;
3112       for(Int_t it=0;it < tofcl2->GetNMatchableTracks();it++){
3113          if(tofcl2->GetTrackIndex(it) == GetID()) index2 = it;
3114       }
3115       if(index1 == -1 || index2 == -1){
3116       }
3117       Double_t timedist2 = 10000;
3118       for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3119         Double_t timec = TMath::Abs(tofcl2->GetTime() - tofcl2->GetIntegratedTime(isp));
3120         if(timec < timedist2) timedist2 = timec;
3121       }
3122       timedist2 *= 0.03; // in cm
3123       Double_t radius2 = tofcl2->GetDx(index2)*tofcl2->GetDx(index2) + tofcl2->GetDz(index2)*tofcl2->GetDz(index2) + timedist2*timedist2;
3124
3125       if(radius2 < radius1){
3126         Int_t change = fTOFcluster[i];
3127         fTOFcluster[i] = fTOFcluster[j];
3128         fTOFcluster[j] = change;
3129       }
3130     }
3131   }
3132 }