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