]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDtrack.cxx
3862c80c8c18ef95f70c5b233be373ddfb806fd6
[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 = fTOFsignal;
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   // Sets  (in TOF)
2364   if(!fTOFLabel) fTOFLabel = new Int_t[3]; 
2365   for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
2366 }
2367
2368 //_______________________________________________________________________
2369 void AliESDtrack::GetTOFpid(Double_t *p) const {
2370   // Gets probabilities of each particle type (in TOF)
2371   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTOFr ? fTOFr[i]:0;
2372 }
2373
2374 //_______________________________________________________________________
2375 void AliESDtrack::GetTOFLabel(Int_t *p) const {
2376   // Gets (in TOF)
2377   if(fNtofClusters>0){
2378     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
2379     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
2380
2381     for (Int_t i=0; i<3; i++) p[i]=tofcl->GetLabel(i);
2382   }
2383   else{
2384     if(fTOFLabel)
2385       for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
2386   }
2387 }
2388
2389 //_______________________________________________________________________
2390 void AliESDtrack::GetTOFInfo(Float_t *info) const {
2391   // Gets (in TOF)
2392   for (Int_t i=0; i<10; i++) info[i]=fTOFInfo[i];
2393 }
2394
2395 //_______________________________________________________________________
2396 void AliESDtrack::SetTOFInfo(Float_t*info) {
2397   // Gets (in TOF)
2398   for (Int_t i=0; i<10; i++) fTOFInfo[i]=info[i];
2399 }
2400
2401
2402
2403 //_______________________________________________________________________
2404 void AliESDtrack::SetHMPIDpid(const Double_t *p) {  
2405   // Sets the probability of each particle type (in HMPID)
2406   if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
2407   SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
2408   SetStatus(AliESDtrack::kHMPIDpid);
2409 }
2410
2411 //_______________________________________________________________________
2412 void  AliESDtrack::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo){ 
2413   if(fTPCdEdxInfo) delete fTPCdEdxInfo;
2414   fTPCdEdxInfo = dEdxInfo; 
2415 }
2416
2417 //_______________________________________________________________________
2418 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
2419   // Gets probabilities of each particle type (in HMPID)
2420   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fHMPIDr ? fHMPIDr[i]:0;
2421 }
2422
2423
2424
2425 //_______________________________________________________________________
2426 void AliESDtrack::SetESDpid(const Double_t *p) {  
2427   // Sets the probability of each particle type for the ESD track
2428   if (!fR) fR = new Double32_t[AliPID::kSPECIES];
2429   SetPIDValues(fR,p,AliPID::kSPECIES);
2430   SetStatus(AliESDtrack::kESDpid);
2431 }
2432
2433 //_______________________________________________________________________
2434 void AliESDtrack::GetESDpid(Double_t *p) const {
2435   // Gets probability of each particle type for the ESD track
2436   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fR ? fR[i]:0;
2437 }
2438
2439 //_______________________________________________________________________
2440 Bool_t AliESDtrack::RelateToVertexTPC(const AliESDVertex *vtx, 
2441 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2442   //
2443   // Try to relate the TPC-only track parameters to the vertex "vtx", 
2444   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2445   //            Magnetic field is "b" (kG).
2446   //
2447   // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2448   // b) The impact parameters and their covariance matrix are calculated.
2449   // c) An attempt to constrain the TPC-only params to the vertex is done.
2450   //    The constrained params are returned via "cParam".
2451   //
2452   // In the case of success, the returned value is kTRUE
2453   // otherwise, it's kFALSE)
2454   // 
2455
2456   if (!fTPCInner) return kFALSE;
2457   if (!vtx) return kFALSE;
2458
2459   Double_t dz[2],cov[3];
2460   if (!fTPCInner->PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2461
2462   fdTPC = dz[0];
2463   fzTPC = dz[1];  
2464   fCddTPC = cov[0];
2465   fCdzTPC = cov[1];
2466   fCzzTPC = cov[2];
2467   
2468   Double_t covar[6]; vtx->GetCovMatrix(covar);
2469   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2470   Double_t c[3]={covar[2],0.,covar[5]};
2471
2472   Double_t chi2=GetPredictedChi2(p,c);
2473   if (chi2>kVeryBig) return kFALSE;
2474
2475   fCchi2TPC=chi2;
2476
2477   if (!cParam) return kTRUE;
2478
2479   *cParam = *fTPCInner;
2480   if (!cParam->Update(p,c)) return kFALSE;
2481
2482   return kTRUE;
2483 }
2484
2485 //_______________________________________________________________________
2486 Bool_t AliESDtrack::RelateToVertexTPCBxByBz(const AliESDVertex *vtx, 
2487 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2488   //
2489   // Try to relate the TPC-only track parameters to the vertex "vtx", 
2490   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2491   //
2492   // All three components of the magnetic field ,"b[3]" (kG), 
2493   // are taken into account.
2494   //
2495   // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2496   // b) The impact parameters and their covariance matrix are calculated.
2497   // c) An attempt to constrain the TPC-only params to the vertex is done.
2498   //    The constrained params are returned via "cParam".
2499   //
2500   // In the case of success, the returned value is kTRUE
2501   // otherwise, it's kFALSE)
2502   // 
2503
2504   if (!fTPCInner) return kFALSE;
2505   if (!vtx) return kFALSE;
2506
2507   Double_t dz[2],cov[3];
2508   if (!fTPCInner->PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2509
2510   fdTPC = dz[0];
2511   fzTPC = dz[1];  
2512   fCddTPC = cov[0];
2513   fCdzTPC = cov[1];
2514   fCzzTPC = cov[2];
2515   
2516   Double_t covar[6]; vtx->GetCovMatrix(covar);
2517   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2518   Double_t c[3]={covar[2],0.,covar[5]};
2519
2520   Double_t chi2=GetPredictedChi2(p,c);
2521   if (chi2>kVeryBig) return kFALSE;
2522
2523   fCchi2TPC=chi2;
2524
2525   if (!cParam) return kTRUE;
2526
2527   *cParam = *fTPCInner;
2528   if (!cParam->Update(p,c)) return kFALSE;
2529
2530   return kTRUE;
2531 }
2532
2533 //_______________________________________________________________________
2534 Bool_t AliESDtrack::RelateToVertex(const AliESDVertex *vtx, 
2535 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2536   //
2537   // Try to relate this track to the vertex "vtx", 
2538   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2539   //            Magnetic field is "b" (kG).
2540   //
2541   // a) The track gets extapolated to the DCA to the vertex.
2542   // b) The impact parameters and their covariance matrix are calculated.
2543   // c) An attempt to constrain this track to the vertex is done.
2544   //    The constrained params are returned via "cParam".
2545   //
2546   // In the case of success, the returned value is kTRUE
2547   // (otherwise, it's kFALSE)
2548   //  
2549
2550   if (!vtx) return kFALSE;
2551
2552   Double_t dz[2],cov[3];
2553   if (!PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2554
2555   fD = dz[0];
2556   fZ = dz[1];  
2557   fCdd = cov[0];
2558   fCdz = cov[1];
2559   fCzz = cov[2];
2560   
2561   Double_t covar[6]; vtx->GetCovMatrix(covar);
2562   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2563   Double_t c[3]={covar[2],0.,covar[5]};
2564
2565   Double_t chi2=GetPredictedChi2(p,c);
2566   if (chi2>kVeryBig) return kFALSE;
2567
2568   fCchi2=chi2;
2569
2570
2571   //--- Could now these lines be removed ? ---
2572   delete fCp;
2573   fCp=new AliExternalTrackParam(*this);  
2574
2575   if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2576   //----------------------------------------
2577
2578   fVertexID = vtx->GetID();
2579
2580   if (!cParam) return kTRUE;
2581
2582   *cParam = *this;
2583   if (!cParam->Update(p,c)) return kFALSE; 
2584
2585   return kTRUE;
2586 }
2587
2588 //_______________________________________________________________________
2589 Bool_t AliESDtrack::RelateToVertexBxByBz(const AliESDVertex *vtx, 
2590 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2591   //
2592   // Try to relate this track to the vertex "vtx", 
2593   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2594   //            Magnetic field is "b" (kG).
2595   //
2596   // a) The track gets extapolated to the DCA to the vertex.
2597   // b) The impact parameters and their covariance matrix are calculated.
2598   // c) An attempt to constrain this track to the vertex is done.
2599   //    The constrained params are returned via "cParam".
2600   //
2601   // In the case of success, the returned value is kTRUE
2602   // (otherwise, it's kFALSE)
2603   //  
2604
2605   if (!vtx) return kFALSE;
2606
2607   Double_t dz[2],cov[3];
2608   if (!PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2609
2610   fD = dz[0];
2611   fZ = dz[1];  
2612   fCdd = cov[0];
2613   fCdz = cov[1];
2614   fCzz = cov[2];
2615   
2616   Double_t covar[6]; vtx->GetCovMatrix(covar);
2617   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2618   Double_t c[3]={covar[2],0.,covar[5]};
2619
2620   Double_t chi2=GetPredictedChi2(p,c);
2621   if (chi2>kVeryBig) return kFALSE;
2622
2623   fCchi2=chi2;
2624
2625
2626   //--- Could now these lines be removed ? ---
2627   delete fCp;
2628   fCp=new AliExternalTrackParam(*this);  
2629
2630   if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2631   //----------------------------------------
2632
2633   fVertexID = vtx->GetID();
2634
2635   if (!cParam) return kTRUE;
2636
2637   *cParam = *this;
2638   if (!cParam->Update(p,c)) return kFALSE; 
2639
2640   return kTRUE;
2641 }
2642
2643 //_______________________________________________________________________
2644 void AliESDtrack::Print(Option_t *) const {
2645   // Prints info on the track
2646   AliExternalTrackParam::Print();
2647   printf("ESD track info\n") ; 
2648   Double_t p[AliPID::kSPECIES] ;
2649   Int_t index = 0 ; 
2650   if( IsOn(kITSpid) ){
2651     printf("From ITS: ") ; 
2652     GetITSpid(p) ; 
2653     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2654       printf("%f, ", p[index]) ;
2655     printf("\n           signal = %f\n", GetITSsignal()) ;
2656   } 
2657   if( IsOn(kTPCpid) ){
2658     printf("From TPC: ") ; 
2659     GetTPCpid(p) ; 
2660     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2661       printf("%f, ", p[index]) ;
2662     printf("\n           signal = %f\n", GetTPCsignal()) ;
2663   }
2664   if( IsOn(kTRDpid) ){
2665     printf("From TRD: ") ; 
2666     GetTRDpid(p) ; 
2667     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2668       printf("%f, ", p[index]) ;
2669       printf("\n           signal = %f\n", GetTRDsignal()) ;
2670       printf("\n           NchamberdEdx = %d\n", GetTRDNchamberdEdx()) ;
2671       printf("\n           NclusterdEdx = %d\n", GetTRDNclusterdEdx()) ;
2672   }
2673   if( IsOn(kTOFpid) ){
2674     printf("From TOF: ") ; 
2675     GetTOFpid(p) ; 
2676     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2677       printf("%f, ", p[index]) ;
2678     printf("\n           signal = %f\n", GetTOFsignal()) ;
2679   }
2680   if( IsOn(kHMPIDpid) ){
2681     printf("From HMPID: ") ; 
2682     GetHMPIDpid(p) ; 
2683     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2684       printf("%f, ", p[index]) ;
2685     printf("\n           signal = %f\n", GetHMPIDsignal()) ;
2686   }
2687
2688
2689
2690 //
2691 // Draw functionality
2692 // Origin: Marian Ivanov, Marian.Ivanov@cern.ch
2693 //
2694 void AliESDtrack::FillPolymarker(TPolyMarker3D *pol, Float_t magF, Float_t minR, Float_t maxR, Float_t stepR){
2695   //
2696   // Fill points in the polymarker
2697   //
2698   TObjArray arrayRef;
2699   arrayRef.AddLast(new AliExternalTrackParam(*this));
2700   if (fIp) arrayRef.AddLast(new AliExternalTrackParam(*fIp));
2701   if (fOp) arrayRef.AddLast(new AliExternalTrackParam(*fOp));
2702   if (fHMPIDp) arrayRef.AddLast(new AliExternalTrackParam(*fHMPIDp));
2703   //
2704   Double_t mpos[3]={0,0,0};
2705   Int_t entries=arrayRef.GetEntries();
2706   for (Int_t i=0;i<entries;i++){
2707     Double_t pos[3];
2708     ((AliExternalTrackParam*)arrayRef.At(i))->GetXYZ(pos);
2709     mpos[0]+=pos[0]/entries;
2710     mpos[1]+=pos[1]/entries;
2711     mpos[2]+=pos[2]/entries;    
2712   }
2713   // Rotate to the mean position
2714   //
2715   Float_t fi= TMath::ATan2(mpos[1],mpos[0]);
2716   for (Int_t i=0;i<entries;i++){
2717     Bool_t res = ((AliExternalTrackParam*)arrayRef.At(i))->Rotate(fi);
2718     if (!res) delete arrayRef.RemoveAt(i);
2719   }
2720   Int_t counter=0;
2721   for (Double_t r=minR; r<maxR; r+=stepR){
2722     Double_t sweight=0;
2723     Double_t mlpos[3]={0,0,0};
2724     for (Int_t i=0;i<entries;i++){
2725       Double_t point[3]={0,0,0};
2726       AliExternalTrackParam *param = ((AliExternalTrackParam*)arrayRef.At(i));
2727       if (!param) continue;
2728       if (param->GetXYZAt(r,magF,point)){
2729         Double_t weight = 1./(10.+(r-param->GetX())*(r-param->GetX()));
2730         sweight+=weight;
2731         mlpos[0]+=point[0]*weight;
2732         mlpos[1]+=point[1]*weight;
2733         mlpos[2]+=point[2]*weight;
2734       }
2735     }
2736     if (sweight>0){
2737       mlpos[0]/=sweight;
2738       mlpos[1]/=sweight;
2739       mlpos[2]/=sweight;      
2740       pol->SetPoint(counter,mlpos[0],mlpos[1], mlpos[2]);
2741       //      printf("xyz\t%f\t%f\t%f\n",mlpos[0], mlpos[1],mlpos[2]);
2742       counter++;
2743     }
2744   }
2745 }
2746
2747 //_______________________________________________________________________
2748 void AliESDtrack::SetITSdEdxSamples(const Double_t s[4]) {
2749   //
2750   // Store the dE/dx samples measured by the two SSD and two SDD layers.
2751   // These samples are corrected for the track segment length. 
2752   //
2753   for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
2754 }
2755
2756 //_______________________________________________________________________
2757 void AliESDtrack::GetITSdEdxSamples(Double_t s[4]) const {
2758   //
2759   // Get the dE/dx samples measured by the two SSD and two SDD layers.  
2760   // These samples are corrected for the track segment length.
2761   //
2762   for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
2763 }
2764
2765
2766 UShort_t   AliESDtrack::GetTPCnclsS(Int_t i0,Int_t i1) const{
2767   //
2768   // get number of shared TPC clusters
2769   //
2770   return  fTPCSharedMap.CountBits(i0)-fTPCSharedMap.CountBits(i1);
2771 }
2772
2773 UShort_t   AliESDtrack::GetTPCncls(Int_t i0,Int_t i1) const{
2774   //
2775   // get number of TPC clusters
2776   //
2777   return  fTPCClusterMap.CountBits(i0)-fTPCClusterMap.CountBits(i1);
2778 }
2779
2780 //____________________________________________________________________
2781 Double_t AliESDtrack::GetChi2TPCConstrainedVsGlobal(const AliESDVertex* vtx) const
2782 {
2783   // Calculates the chi2 between the TPC track (TPCinner) constrained to the primary vertex and the global track
2784   //
2785   // Returns -1 in case the calculation failed
2786   //
2787   // Value is cached as a non-persistent member.
2788   //
2789   // Code adapted from original code by GSI group (Jacek, Marian, Michael)
2790   
2791   // cache, ignoring that a different vertex might be passed
2792   if (fCacheChi2TPCConstrainedVsGlobalVertex == vtx)
2793     return fCacheChi2TPCConstrainedVsGlobal;
2794   
2795   fCacheChi2TPCConstrainedVsGlobal = -1;
2796   fCacheChi2TPCConstrainedVsGlobalVertex = vtx;
2797   
2798   Double_t x[3];
2799   GetXYZ(x);
2800   Double_t b[3];
2801   AliTrackerBase::GetBxByBz(x,b);
2802
2803   if (!fTPCInner)  { 
2804     AliWarning("Could not get TPC Inner Param.");
2805     return fCacheChi2TPCConstrainedVsGlobal;
2806   }
2807   
2808   // clone for constraining
2809   AliExternalTrackParam* tpcInnerC = new AliExternalTrackParam(*fTPCInner);
2810   if (!tpcInnerC) { 
2811     AliWarning("Clone of TPCInnerParam failed.");
2812     return fCacheChi2TPCConstrainedVsGlobal;  
2813   }
2814   
2815   // transform to the track reference frame 
2816   Bool_t isOK = tpcInnerC->Rotate(GetAlpha());
2817   isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2818   if (!isOK) { 
2819     delete tpcInnerC;
2820     tpcInnerC = 0; 
2821     AliWarning("Rotation/Propagation of track failed.") ; 
2822     return fCacheChi2TPCConstrainedVsGlobal;    
2823   }  
2824
2825   // constrain TPCinner 
2826   isOK = tpcInnerC->ConstrainToVertex(vtx, b);
2827   
2828   // transform to the track reference frame 
2829   isOK &= tpcInnerC->Rotate(GetAlpha());
2830   isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2831
2832   if (!isOK) {
2833     AliWarning("ConstrainTPCInner failed.") ;
2834     delete tpcInnerC;
2835     tpcInnerC = 0; 
2836     return fCacheChi2TPCConstrainedVsGlobal;  
2837   }
2838   
2839   // calculate chi2 between vi and vj vectors
2840   // with covi and covj covariance matrices
2841   // chi2ij = (vi-vj)^(T)*(covi+covj)^(-1)*(vi-vj)
2842   TMatrixD deltaT(5,1);
2843   TMatrixD delta(1,5);
2844   TMatrixD covarM(5,5);
2845
2846   for (Int_t ipar=0; ipar<5; ipar++) {
2847     deltaT(ipar,0) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2848     delta(0,ipar) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2849
2850     for (Int_t jpar=0; jpar<5; jpar++) {
2851       Int_t index = GetIndex(ipar,jpar);
2852       covarM(ipar,jpar) = GetCovariance()[index]+tpcInnerC->GetCovariance()[index];
2853     }
2854   }
2855   // chi2 distance TPC constrained and TPC+ITS
2856   TMatrixD covarMInv = covarM.Invert();
2857   TMatrixD mat2 = covarMInv*deltaT;
2858   TMatrixD chi2 = delta*mat2; 
2859   
2860   delete tpcInnerC; 
2861   tpcInnerC = 0;
2862   
2863   fCacheChi2TPCConstrainedVsGlobal = chi2(0,0);
2864   return fCacheChi2TPCConstrainedVsGlobal;
2865 }
2866
2867 void AliESDtrack::SetDetectorPID(const AliDetectorPID *pid)
2868 {
2869   //
2870   // Set the detector PID
2871   //
2872   if (fDetectorPID) delete fDetectorPID;
2873   fDetectorPID=pid;
2874   
2875 }
2876
2877 Double_t AliESDtrack::GetLengthInActiveZone( Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
2878   //
2879   // Input parameters:
2880   //   mode  - type of external track parameters 
2881   //   deltaY - user defined "dead region" in cm
2882   //   deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2883   //   bz     - magnetic field 
2884   //   exbPhi - optional rotation due to the ExB effect
2885   // return value:
2886   //   the length of the track in cm in "active volume" of the TPC
2887   //
2888   if (mode==0) return GetLengthInActiveZone(this, deltaY,deltaZ,bz, exbPhi,pcstream);
2889   if (mode==1) return GetLengthInActiveZone(fIp, deltaY,deltaZ,bz, exbPhi,pcstream);
2890   if (mode==2) return GetLengthInActiveZone(fOp, deltaY,deltaZ,bz, exbPhi,pcstream);
2891   return 0;
2892 }
2893
2894 Double_t AliESDtrack::GetLengthInActiveZone(const AliExternalTrackParam  *paramT, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) {
2895   //
2896   // Numerical code to calculate the length of the track in active region of the TPC
2897   // ( can be speed up if somebody wants to invest time - analysical version shoult be possible) 
2898   //
2899   // Input parameters:
2900   //   paramT - external track parameters 
2901   //   deltaY - user defined "dead region" in cm
2902   //   deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2903   //   bz     - magnetic field 
2904   //   exbPhi - optional rotation due to the ExB effect
2905   // return value:
2906   //   the length of the track in cm in "active volume" of the TPC
2907   //
2908   const Double_t rIn=85;
2909   const Double_t rOut=245;
2910   Double_t xyz[3], pxyz[3];
2911   if (paramT->GetXYZAt(rIn,bz,xyz)){
2912     paramT->GetPxPyPzAt(rIn,bz,pxyz);
2913   }else{
2914     paramT->GetXYZ(xyz);
2915     paramT->GetPxPyPz(pxyz);
2916   }
2917   //
2918   Double_t dca   = -paramT->GetD(0,0,bz);  // get impact parameter distance to point (0,0)
2919   Double_t radius= TMath::Abs(1/paramT->GetC(bz));  //
2920   Double_t sign  = paramT->GetSign();
2921   Double_t R0    = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);   // radius at current point
2922   Double_t phiR0 = TMath::ATan2(xyz[1],xyz[0]);                // angle of given point
2923   Double_t dPhiR0= -TMath::ASin((dca*dca-2*dca*radius*sign+R0*R0)/(2*R0*(dca-radius*sign)));
2924   Double_t phi0  = phiR0-(dPhiR0);  // global phi offset to be added
2925   //
2926   //
2927   AliExternalTrackParam paramR=(*paramT);
2928   Double_t length=0;
2929   for (Double_t R=rIn; R<=rOut; R++){
2930     Double_t sinPhi=(dca*dca-2*dca*radius*sign+R*R)/(2*R*(dca-radius*sign));
2931     if (TMath::Abs(sinPhi)>=1) continue;
2932     Double_t dphi     = -TMath::ASin(sinPhi);
2933     Double_t phi      = phi0+dphi;                           // global phi
2934     Int_t    sector   = TMath::Nint(9*phi/(TMath::Pi()));
2935     Double_t dPhiEdge = phi-(sector*TMath::Pi()/9)+exbPhi;   // distance to sector boundary in rphi
2936     Double_t dX   = R*TMath::Cos(phi)-xyz[0];
2937     Double_t dY   = R*TMath::Sin(phi)-xyz[1];
2938     Double_t deltaPhi = 2*TMath::ASin(0.5*TMath::Sqrt(dX*dX+dY*dY)/radius);
2939     Double_t z = xyz[2]+deltaPhi*radius*paramT->GetTgl();
2940     if (TMath::Abs(dPhiEdge*R)>deltaY && TMath::Abs(z)<deltaZ){
2941       length++;
2942     }
2943     //    Double_t deltaZ= dphi*radius; 
2944     if (pcstream){
2945       //should we keep debug possibility ?
2946       AliExternalTrackParam paramTcopy=(*paramT);
2947       paramR.Rotate(phi);
2948       paramR.PropagateTo(R,bz);
2949       (*pcstream)<<"debugEdge"<<
2950         "R="<<R<<                   // radius
2951         "dphiEdge="<<dPhiEdge<<     // distance to edge 
2952         "phi0="<<phi0<<             // phi0 -phi at the track initial position
2953         "phi="<<phi<<               // 
2954         "z="<<z<<
2955         "pT.="<<&paramTcopy<<
2956         "pR.="<<&paramR<<
2957         "\n";
2958     }
2959   }
2960   return length;
2961 }
2962
2963 Double_t AliESDtrack::GetMassForTracking() const
2964 {
2965   int pid = fPIDForTracking;
2966   if (pid<AliPID::kPion) pid = AliPID::kPion;
2967   double m = AliPID::ParticleMass(pid);
2968   return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
2969 }
2970
2971
2972 void    AliESDtrack::SetTOFclusterArray(Int_t /*ncluster*/,Int_t */*TOFcluster*/){
2973   AliInfo("Method has to be implemented!");
2974 //   fNtofClusters=ncluster;
2975 //   if(TOFcluster == fTOFcluster) return;
2976 //   if(fTOFcluster){ // reset previous content    
2977 //     delete[] fTOFcluster;
2978 //     fTOFcluster = NULL;
2979 //     fNtofClusters=0;
2980 //   }
2981
2982 //   if(ncluster){ // set new content
2983 //     fTOFcluster = new Int_t[fNtofClusters];
2984 //     for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = TOFcluster[i];
2985 //   }
2986 //   else
2987 //     fTOFcluster = 0;
2988 }
2989
2990 //____________________________________________
2991 void  AliESDtrack::SuppressTOFMatches()
2992 {
2993   // remove reference to this track from TOF clusters
2994   if (!fNtofClusters || !GetESDEvent()) return;
2995   TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
2996   for (;fNtofClusters--;) {
2997     AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[fNtofClusters]);
2998     clTOF->SuppressMatchedTrack(GetID());
2999     if (!clTOF->GetNMatchableTracks()) { // remove this cluster
3000       int last = tofclArray->GetEntriesFast()-1;
3001       AliESDTOFCluster* clTOFL = (AliESDTOFCluster*)tofclArray->At(last);
3002       if (last != fTOFcluster[fNtofClusters]) {
3003         *clTOF = *clTOFL; // move last cluster to the place of eliminated one
3004         // fix the references on this cluster
3005         clTOF->FixSelfReferences(last,fTOFcluster[fNtofClusters]);
3006       }
3007       tofclArray->RemoveAt(last);
3008     }
3009   }
3010 }
3011
3012 //____________________________________________
3013 void  AliESDtrack::ReplaceTOFTrackID(int oldID, int newID)
3014 {
3015   // replace the ID in TOF clusters references to this track
3016   if (!fNtofClusters || !GetESDEvent()) return;
3017   TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3018   for (int it=fNtofClusters;it--;) {
3019     AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
3020     clTOF->ReplaceMatchedTrackID(oldID,newID);
3021   }
3022 }
3023
3024 //____________________________________________
3025 void  AliESDtrack::ReplaceTOFClusterID(int oldID, int newID)
3026 {
3027   // replace the referenc on TOF cluster oldID by newID
3028   if (!fNtofClusters || !GetESDEvent()) return;
3029   for (int it=fNtofClusters;it--;) {
3030     if (fTOFcluster[it] == oldID) {
3031       fTOFcluster[it] = newID;
3032       return;
3033     }
3034   }
3035 }
3036
3037 //____________________________________________
3038 void  AliESDtrack::ReplaceTOFMatchID(int oldID, int newID)
3039 {
3040   // replace in the ESDTOFCluster associated with this track the id of the corresponding
3041   // ESDTOFMatch from oldID to newID
3042   if (!fNtofClusters || !GetESDEvent()) return;
3043   TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3044   for (int it=fNtofClusters;it--;) {
3045     AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
3046     clTOF->ReplaceMatchID(oldID,newID);
3047   }
3048 }
3049
3050 //____________________________________________
3051 void AliESDtrack::AddTOFcluster(Int_t icl)
3052 {
3053   fNtofClusters++;
3054   
3055   Int_t *old = fTOFcluster;
3056   fTOFcluster = new Int_t[fNtofClusters];
3057
3058   for(Int_t i=0;i < fNtofClusters-1;i++) fTOFcluster[i] = old[i];
3059   fTOFcluster[fNtofClusters-1] = icl;
3060
3061   if(fNtofClusters-1){ // delete previous content    
3062     delete old;
3063     old = NULL;
3064   }
3065  
3066 }
3067
3068 //____________________________________________
3069 Double_t AliESDtrack::GetTOFsignal() const 
3070 {
3071   if(fNtofClusters>0 && GetESDEvent()){
3072     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3073     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3074
3075     return tofcl->GetTime();
3076   }
3077   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3078
3079   return fTOFsignal;
3080 }
3081
3082 //____________________________________________
3083 Double_t AliESDtrack::GetTOFsignalToT() const 
3084 {
3085   if(fNtofClusters>0 && GetESDEvent()){
3086     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3087     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3088
3089     return tofcl->GetTOT();
3090   }
3091   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3092
3093   return fTOFsignalToT;
3094 }
3095
3096 //____________________________________________
3097 Double_t AliESDtrack::GetTOFsignalRaw() const 
3098 {
3099   if(fNtofClusters>0 && GetESDEvent()){
3100     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3101     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3102
3103     return tofcl->GetTimeRaw();
3104   }
3105   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3106
3107   return fTOFsignalRaw;
3108 }
3109
3110 //____________________________________________
3111 Double_t AliESDtrack::GetTOFsignalDz() const 
3112 {
3113
3114   AliESDTOFCluster *tofcl;
3115
3116   Int_t index = -1;
3117   if(fNtofClusters>0 && GetESDEvent()){
3118     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3119     tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3120
3121     for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3122       if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3123     }
3124   }
3125   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3126
3127   if(fNtofClusters>0 && index > -1){
3128     return tofcl->GetDz(index);
3129   }
3130   return fTOFsignalDz;
3131 }
3132
3133 //____________________________________________
3134 Double_t AliESDtrack::GetTOFsignalDx() const 
3135 {
3136   AliESDTOFCluster *tofcl;
3137
3138   Int_t index = -1;
3139   if(fNtofClusters>0 && GetESDEvent()){
3140     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3141     tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3142     for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3143       if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3144     }
3145   }
3146   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3147   if(fNtofClusters>0 && index > -1){
3148     return tofcl->GetDx(index);
3149   }
3150   return fTOFsignalDx;
3151 }
3152
3153 //____________________________________________
3154 Short_t  AliESDtrack::GetTOFDeltaBC() const 
3155 {
3156   if(fNtofClusters>0 && GetESDEvent()){
3157     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3158     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3159     return tofcl->GetDeltaBC();
3160   }
3161   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3162
3163   return fTOFdeltaBC;
3164 }
3165
3166 //____________________________________________
3167 Short_t  AliESDtrack::GetTOFL0L1() const 
3168 {
3169   if(fNtofClusters>0 && GetESDEvent()){
3170     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3171     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3172
3173     return tofcl->GetL0L1Latency();
3174   }
3175   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3176
3177   return fTOFl0l1;
3178 }
3179
3180 //____________________________________________
3181 Int_t   AliESDtrack::GetTOFCalChannel() const 
3182 {
3183   if(fNtofClusters>0 && GetESDEvent()){
3184     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3185     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3186
3187     return tofcl->GetTOFchannel();
3188   }
3189   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3190
3191   return fTOFCalChannel;
3192 }
3193
3194 //____________________________________________
3195 Int_t   AliESDtrack::GetTOFcluster() const 
3196 {
3197   if(fNtofClusters>0 && GetESDEvent()){
3198     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3199     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3200
3201     return tofcl->GetClusterIndex();
3202   }
3203   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3204
3205   return fTOFindex;
3206 }
3207
3208 //____________________________________________
3209 Int_t   AliESDtrack::GetTOFclusterN() const
3210 {
3211   return fNtofClusters;
3212 }
3213
3214 //____________________________________________
3215 Bool_t  AliESDtrack::IsTOFHitAlreadyMatched() const{
3216   if(fNtofClusters>0 && GetESDEvent()){
3217     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3218     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3219
3220     if (tofcl->GetNMatchableTracks() > 1)
3221       return kTRUE;
3222   }
3223   else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3224
3225   return kFALSE;
3226 }
3227
3228 //____________________________________________
3229 void AliESDtrack::ReMapTOFcluster(Int_t ncl,Int_t *mapping){
3230   for(Int_t i=0;i<fNtofClusters;i++){
3231     if(fTOFcluster[i]<ncl && fTOFcluster[i]>-1)
3232       fTOFcluster[i] = mapping[fTOFcluster[i]];
3233     else
3234       AliInfo(Form("TOF cluster re-mapping in AliESDtrack: out of range (%i > %i)\n",fTOFcluster[i],ncl));
3235   }
3236 }
3237
3238 //____________________________________________
3239 void AliESDtrack::SortTOFcluster(){
3240   TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3241
3242   for(Int_t i=0;i<fNtofClusters-1;i++){
3243     for(Int_t j=i+1;j<fNtofClusters;j++){
3244       AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[i]);
3245       Int_t index1 = -1;
3246       for(Int_t it=0;it < tofcl->GetNMatchableTracks();it++){
3247          if(tofcl->GetTrackIndex(it) == GetID()) index1 = it;
3248       }
3249       Double_t timedist1 = 10000;
3250       for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3251         Double_t timec = TMath::Abs(tofcl->GetTime() - tofcl->GetIntegratedTime(isp));
3252         if(timec < timedist1) timedist1 = timec;
3253       }
3254       timedist1 *= 0.03; // in cm
3255       Double_t radius1 = tofcl->GetDx(index1)*tofcl->GetDx(index1) + tofcl->GetDz(index1)*tofcl->GetDz(index1) + timedist1*timedist1;
3256
3257       AliESDTOFCluster *tofcl2 = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[j]);
3258       Int_t index2 = -1;
3259       for(Int_t it=0;it < tofcl2->GetNMatchableTracks();it++){
3260          if(tofcl2->GetTrackIndex(it) == GetID()) index2 = it;
3261       }
3262       if(index1 == -1 || index2 == -1){
3263       }
3264       Double_t timedist2 = 10000;
3265       for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3266         Double_t timec = TMath::Abs(tofcl2->GetTime() - tofcl2->GetIntegratedTime(isp));
3267         if(timec < timedist2) timedist2 = timec;
3268       }
3269       timedist2 *= 0.03; // in cm
3270       Double_t radius2 = tofcl2->GetDx(index2)*tofcl2->GetDx(index2) + tofcl2->GetDz(index2)*tofcl2->GetDz(index2) + timedist2*timedist2;
3271
3272       if(radius2 < radius1){
3273         Int_t change = fTOFcluster[i];
3274         fTOFcluster[i] = fTOFcluster[j];
3275         fTOFcluster[j] = change;
3276       }
3277     }
3278   }
3279 }
3280
3281 //____________________________________________
3282 const AliTOFHeader* AliESDtrack::GetTOFHeader() const {
3283   return fESDEvent->GetTOFHeader();
3284 }
3285
3286 //___________________________________________
3287 void AliESDtrack::SetID(Short_t id) 
3288 {
3289   // set track ID taking care about dependencies
3290   if (fNtofClusters) ReplaceTOFTrackID(fID,id); 
3291   fID=id;
3292 }
3293
3294
3295 Double_t  AliESDtrack::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t qID, Int_t valueID){
3296   //
3297   // Interface to get the calibrated dEdx information 
3298   // For details of arguments and return values see 
3299   //     AliTPCdEdxInfo::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t valueID)
3300   //
3301   if (!fTPCdEdxInfo) return 0;
3302   if (!fIp) return 0;
3303   return fTPCdEdxInfo->GetdEdxInfo(fIp, regionID, calibID, qID, valueID);
3304 }
3305