]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/ESD/AliESDtrack.cxx
Merge branch 'master' into TRDdev
[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   // Set ITS cluster map
585   fITSClusterMap=track->GetITSClusterMap();
586   fITSSharedMap=0;
587
588   fITSncls=0;
589   for(i=0; i<6; i++) {
590     if(HasPointOnITSLayer(i)) fITSncls++;
591   }
592
593   // Set TPC ncls 
594   fTPCncls=track->GetTPCNcls();
595   fTPCnclsF=track->GetTPCNclsF();
596   // TPC cluster maps
597   const TBits* bmap = track->GetTPCClusterMapPtr();
598   if (bmap) SetTPCClusterMap(*bmap);
599   bmap = GetTPCFitMapPtr();
600   if (bmap) SetTPCFitMap(*bmap);
601   bmap = GetTPCSharedMapPtr();
602   if (bmap) SetTPCSharedMap(*bmap);
603   //
604   // Set the combined PID
605   const Double_t *pid = track->PID();
606   if(pid) {
607     fR = new Double32_t[AliPID::kSPECIES];
608     for (i=AliPID::kSPECIES; i--;) fR[i]=pid[i];
609   }
610   //
611   // calo matched cluster id
612   SetEMCALcluster(track->GetEMCALcluster());
613   // AliESD track label
614   //
615   // PID info
616   fITSsignal = track->GetITSsignal();
617   double itsdEdx[4];
618   track->GetITSdEdxSamples(itsdEdx);
619   SetITSdEdxSamples(itsdEdx);
620   //
621   SetTPCsignal(track->GetTPCsignal(),fTPCsignalS,track->GetTPCsignalN()); // No signalS in AODPi
622   AliTPCdEdxInfo * dEdxInfo = track->GetTPCdEdxInfo();
623   if (dEdxInfo) SetTPCdEdxInfo(new AliTPCdEdxInfo(*dEdxInfo));
624   //
625   SetTRDsignal(track->GetTRDsignal());
626   int ntrdsl = track->GetNumberOfTRDslices();
627   if (ntrdsl>0) {
628     SetNumberOfTRDslices((ntrdsl+2)*kTRDnPlanes);
629     for (int ipl=kTRDnPlanes;ipl--;){
630       for (int isl=ntrdsl;isl--;) SetTRDslice(track->GetTRDslice(ipl,isl),ipl,isl);
631       Double_t sp, p = track->GetTRDmomentum(ipl, &sp);
632       SetTRDmomentum(p, ipl, &sp);
633     }
634   }
635   //
636   fTRDncls = track->GetTRDncls();
637   fTRDntracklets &= 0xff & track->GetTRDntrackletsPID();
638   fTRDchi2 = track->GetTRDchi2();
639   //
640   SetTOFsignal(track->GetTOFsignal());
641   Double_t expt[AliPID::kSPECIESC];
642   track->GetIntegratedTimes(expt,AliPID::kSPECIESC);
643   SetIntegratedTimes(expt);
644   //
645   SetTrackPhiEtaPtOnEMCal(track->GetTrackPhiOnEMCal(),track->GetTrackEtaOnEMCal(),track->GetTrackPtOnEMCal());
646   //
647   SetLabel(track->GetLabel());
648   // Set the status
649   SetStatus(track->GetStatus());
650   //
651   // Set the ID
652   SetID(track->GetID());
653   //
654 }
655
656 //_______________________________________________________________________
657 AliESDtrack::AliESDtrack(TParticle * part) : 
658   AliExternalTrackParam(),
659   fCp(0),
660   fIp(0),
661   fTPCInner(0),
662   fOp(0),
663   fHMPIDp(0),  
664   fFriendTrack(0),
665   fTPCFitMap(159),//number of padrows
666   fTPCClusterMap(159),//number of padrows
667   fTPCSharedMap(159),//number of padrows
668   fFlags(0),
669   fID(0),
670   fLabel(0),
671   fITSLabel(0),
672   fTPCLabel(0),
673   fTRDLabel(0),
674   fTOFLabel(NULL),
675   fTOFCalChannel(-1),
676   fTOFindex(-1),
677   fHMPIDqn(0),
678   fHMPIDcluIdx(-1),
679   fCaloIndex(kEMCALNoMatch),
680   fR(0),
681   fITSr(0),
682   fTPCr(0),
683   fTRDr(0),
684   fTOFr(0),
685   fHMPIDr(0),
686   fHMPIDtrkTheta(0),
687   fHMPIDtrkPhi(0),
688   fHMPIDsignal(0),
689   fTrackTime(NULL),
690   fTrackLength(0),
691   fdTPC(0),fzTPC(0),
692   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
693   fCchi2TPC(0),
694   fD(0),fZ(0),
695   fCdd(0),fCdz(0),fCzz(0),
696   fCchi2(0),
697   fITSchi2(0),
698   fTPCchi2(0),
699   fTPCchi2Iter1(0),  
700   fTRDchi2(0),
701   fTOFchi2(0),
702   fHMPIDchi2(0),
703   fGlobalChi2(0),
704   fITSsignal(0),
705   fTPCsignal(0),
706   fTPCsignalTuned(0),
707   fTPCsignalS(0),
708   fTPCdEdxInfo(0),
709   fTRDsignal(0),
710   fTRDQuality(0),
711   fTRDBudget(0),
712   fTOFsignal(99999),
713   fTOFsignalTuned(99999),
714   fTOFsignalToT(99999),
715   fTOFsignalRaw(99999),
716   fTOFsignalDz(999),
717   fTOFsignalDx(999),
718   fTOFdeltaBC(999),
719   fTOFl0l1(999),
720   fCaloDx(0),
721   fCaloDz(0),
722   fHMPIDtrkX(0),
723   fHMPIDtrkY(0),
724   fHMPIDmipX(0),
725   fHMPIDmipY(0),
726   fTPCncls(0),
727   fTPCnclsF(0),
728   fTPCsignalN(0),
729   fTPCnclsIter1(0),
730   fTPCnclsFIter1(0),
731   fITSncls(0),
732   fITSClusterMap(0),
733   fITSSharedMap(0),
734   fTRDncls(0),
735   fTRDncls0(0),
736   fTRDntracklets(0),
737   fTRDNchamberdEdx(0),
738   fTRDNclusterdEdx(0),
739   fTRDnSlices(0),
740   fTRDslices(0x0),
741   fVertexID(-2),  // -2 means an orphan track
742   fPIDForTracking(AliPID::kPion),
743   fESDEvent(0),
744   fCacheNCrossedRows(-10),
745   fCacheChi2TPCConstrainedVsGlobal(-10),
746   fCacheChi2TPCConstrainedVsGlobalVertex(0),
747   fDetectorPID(0x0),
748   fTrackPhiOnEMCal(-999),
749   fTrackEtaOnEMCal(-999),
750   fTrackPtOnEMCal(-999),
751   fNtofClusters(0),
752   fTOFcluster(NULL)
753 {
754   //
755   // ESD track from TParticle
756   //
757
758   // Reset all the arrays
759   Int_t i;
760   for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
761   
762   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
763   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
764   for (i=0;i<kTRDnPlanes;i++) {
765     fTRDTimBin[i]=0;
766   }
767   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
768   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
769   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
770   for (i=0;i<12;i++) {fITSModule[i]=-1;}
771
772   // Calculate the AliExternalTrackParam content
773
774   Double_t xref;
775   Double_t alpha;
776   Double_t param[5];
777   Double_t covar[15];
778
779   // Calculate alpha: the rotation angle of the corresponding local system (TPC sector)
780   alpha = part->Phi()*180./TMath::Pi();
781   if (alpha<0) alpha+= 360.;
782   if (alpha>360) alpha -= 360.;
783
784   Int_t sector = (Int_t)(alpha/20.);
785   alpha = 10. + 20.*sector;
786   alpha /= 180;
787   alpha *= TMath::Pi();
788
789   // Covariance matrix: no errors, the parameters are exact
790   for (i=0; i<15; i++) covar[i]=0.;
791
792   // Get the vertex of origin and the momentum
793   TVector3 ver(part->Vx(),part->Vy(),part->Vz());
794   TVector3 mom(part->Px(),part->Py(),part->Pz());
795
796   // Rotate to the local coordinate system (TPC sector)
797   ver.RotateZ(-alpha);
798   mom.RotateZ(-alpha);
799
800   // X of the referense plane
801   xref = ver.X();
802
803   Int_t pdgCode = part->GetPdgCode();
804
805   Double_t charge = 
806     TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge();
807
808   param[0] = ver.Y();
809   param[1] = ver.Z();
810   param[2] = TMath::Sin(mom.Phi());
811   param[3] = mom.Pz()/mom.Pt();
812   param[4] = TMath::Sign(1/mom.Pt(),charge);
813
814   // Set AliExternalTrackParam
815   Set(xref, alpha, param, covar);
816
817   // Set the PID
818   Int_t indexPID = 99;
819   if (pdgCode<0) pdgCode = -pdgCode;
820   for (i=0;i<AliPID::kSPECIESC;i++) if (pdgCode==AliPID::ParticleCode(i)) {indexPID = i; break;}
821
822   if (indexPID < AliPID::kSPECIESC) fPIDForTracking = indexPID;
823
824   // AliESD track label
825   SetLabel(part->GetUniqueID());
826
827 }
828
829 //_______________________________________________________________________
830 AliESDtrack::~AliESDtrack(){ 
831   //
832   // This is destructor according Coding Conventrions 
833   //
834   //printf("Delete track\n");
835   delete fIp; 
836   delete fTPCInner; 
837   delete fOp;
838   delete fHMPIDp;
839   delete fCp; 
840   delete fFriendTrack;
841   delete fTPCdEdxInfo;
842   if(fTRDnSlices)
843     delete[] fTRDslices;
844
845   //Reset cached values - needed for TClonesArray in AliESDInputHandler
846   fCacheNCrossedRows = -10.;
847   fCacheChi2TPCConstrainedVsGlobal = -10.;
848   if(fCacheChi2TPCConstrainedVsGlobalVertex) fCacheChi2TPCConstrainedVsGlobalVertex = 0;
849
850   if(fTOFcluster)
851     delete[] fTOFcluster;
852   fTOFcluster = NULL;
853   fNtofClusters=0;
854
855   delete fDetectorPID;
856
857   delete[] fR;
858   delete[] fITSr;
859   delete[] fTPCr;
860   delete[] fTRDr;
861   delete[] fTOFr;
862   delete[] fHMPIDr;
863   //
864   if(fTrackTime) delete[] fTrackTime; 
865   if(fTOFLabel) delete[] fTOFLabel;
866 }
867
868 //_______________________________________________________________________
869 AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source)
870 {
871   // == operator
872
873   if(&source == this) return *this;
874   AliExternalTrackParam::operator=(source);
875
876   
877   if(source.fCp){
878     // we have the trackparam: assign or copy construct
879     if(fCp)*fCp = *source.fCp;
880     else fCp = new AliExternalTrackParam(*source.fCp);
881   }
882   else{
883     // no track param delete the old one
884     delete fCp;
885     fCp = 0;
886   }
887
888   if(source.fIp){
889     // we have the trackparam: assign or copy construct
890     if(fIp)*fIp = *source.fIp;
891     else fIp = new AliExternalTrackParam(*source.fIp);
892   }
893   else{
894     // no track param delete the old one
895     delete fIp;
896     fIp = 0;
897   }
898
899
900   if(source.fTPCInner){
901     // we have the trackparam: assign or copy construct
902     if(fTPCInner) *fTPCInner = *source.fTPCInner;
903     else fTPCInner = new AliExternalTrackParam(*source.fTPCInner);
904   }
905   else{
906     // no track param delete the old one
907     delete fTPCInner;
908     fTPCInner = 0;
909   }
910
911   if(source.fTPCdEdxInfo) {
912     if(fTPCdEdxInfo) *fTPCdEdxInfo = *source.fTPCdEdxInfo;
913     fTPCdEdxInfo = new AliTPCdEdxInfo(*source.fTPCdEdxInfo);
914   }
915
916   if(source.fOp){
917     // we have the trackparam: assign or copy construct
918     if(fOp) *fOp = *source.fOp;
919     else fOp = new AliExternalTrackParam(*source.fOp);
920   }
921   else{
922     // no track param delete the old one
923     delete fOp;
924     fOp = 0;
925   }
926
927   
928   if(source.fHMPIDp){
929     // we have the trackparam: assign or copy construct
930     if(fHMPIDp) *fHMPIDp = *source.fHMPIDp;
931     else fHMPIDp = new AliExternalTrackParam(*source.fHMPIDp);
932   }
933   else{
934     // no track param delete the old one
935     delete fHMPIDp;
936     fHMPIDp = 0;
937   }
938
939   // copy also the friend track 
940   // use copy constructor
941   if(source.fFriendTrack){
942     // we have the trackparam: assign or copy construct
943     delete fFriendTrack; fFriendTrack=new AliESDfriendTrack(*source.fFriendTrack);
944   }
945   else{
946     // no track param delete the old one
947     delete fFriendTrack; fFriendTrack= 0;
948   }
949
950   fTPCFitMap = source.fTPCFitMap; 
951   fTPCClusterMap = source.fTPCClusterMap; 
952   fTPCSharedMap  = source.fTPCSharedMap;  
953   // the simple stuff
954   fFlags    = source.fFlags; 
955   fID       = source.fID;             
956   fLabel    = source.fLabel;
957   fITSLabel = source.fITSLabel;
958   for(int i = 0; i< 12;++i){
959     fITSModule[i] = source.fITSModule[i];
960   }
961   fTPCLabel = source.fTPCLabel; 
962   fTRDLabel = source.fTRDLabel;
963   if(source.fTOFLabel){
964     if(!fTOFLabel) fTOFLabel = new Int_t[3];
965     for(int i = 0; i< 3;++i){
966       fTOFLabel[i] = source.fTOFLabel[i];    
967     }
968   }
969   fTOFCalChannel = source.fTOFCalChannel;
970   fTOFindex      = source.fTOFindex;
971   fHMPIDqn       = source.fHMPIDqn;
972   fHMPIDcluIdx   = source.fHMPIDcluIdx; 
973   fCaloIndex    = source.fCaloIndex;
974   for (int i=kNITSchi2Std;i--;) fITSchi2Std[i] = source.fITSchi2Std[i];
975   for(int i = 0; i< 3;++i){
976     fKinkIndexes[i] = source.fKinkIndexes[i]; 
977     fV0Indexes[i]   = source.fV0Indexes[i]; 
978   }
979
980   if (source.fR) {
981     if (!fR) fR = new Double32_t[AliPID::kSPECIES]; 
982     for (Int_t i=AliPID::kSPECIES;i--;)  fR[i]=source.fR[i];
983   }
984   else {delete[] fR; fR = 0;}
985
986   if (source.fITSr) {
987     if (!fITSr) fITSr = new Double32_t[AliPID::kSPECIES]; 
988     for (Int_t i=AliPID::kSPECIES;i--;)  fITSr[i]=source.fITSr[i]; 
989   }
990   else {delete[] fITSr; fITSr = 0;}
991   //
992   if (source.fTPCr) {
993     if (!fTPCr) fTPCr = new Double32_t[AliPID::kSPECIES]; 
994     for (Int_t i=AliPID::kSPECIES;i--;) fTPCr[i]=source.fTPCr[i]; 
995   }
996   else {delete[] fTPCr; fTPCr = 0;}
997
998   if (source.fTRDr) {
999     if (!fTRDr) fTRDr  = new Double32_t[AliPID::kSPECIES];
1000     for (Int_t i=AliPID::kSPECIES;i--;) fTRDr[i]=source.fTRDr[i]; 
1001   }
1002   else {delete[] fTRDr; fTRDr = 0;}
1003
1004   if (source.fTOFr) {
1005     if (!fTOFr) fTOFr = new Double32_t[AliPID::kSPECIES];
1006     for (Int_t i=AliPID::kSPECIES;i--;) fTOFr[i]=source.fTOFr[i];
1007   }
1008   else {delete[] fTOFr; fTOFr = 0;}
1009
1010   if (source.fHMPIDr) {
1011     if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
1012     for (Int_t i=AliPID::kSPECIES;i--;) fHMPIDr[i]=source.fHMPIDr[i];
1013   }
1014   else {delete[] fHMPIDr; fHMPIDr = 0;}
1015   
1016   fPIDForTracking = source.fPIDForTracking;
1017
1018   fHMPIDtrkTheta = source.fHMPIDtrkTheta;
1019   fHMPIDtrkPhi   = source.fHMPIDtrkPhi;
1020   fHMPIDsignal   = source.fHMPIDsignal; 
1021
1022   
1023   if(fTrackTime){
1024     delete[] fTrackTime;
1025   }
1026   if(source.fTrackTime){
1027     fTrackTime = new Double32_t[AliPID::kSPECIESC];
1028     for(Int_t i=0;i < AliPID::kSPECIESC;i++)
1029       fTrackTime[i] = source.fTrackTime[i];  
1030   }
1031
1032   fTrackLength   = source. fTrackLength;
1033   fdTPC  = source.fdTPC; 
1034   fzTPC  = source.fzTPC; 
1035   fCddTPC = source.fCddTPC;
1036   fCdzTPC = source.fCdzTPC;
1037   fCzzTPC = source.fCzzTPC;
1038   fCchi2TPC = source.fCchi2TPC;
1039
1040   fD  = source.fD; 
1041   fZ  = source.fZ; 
1042   fCdd = source.fCdd;
1043   fCdz = source.fCdz;
1044   fCzz = source.fCzz;
1045   fCchi2     = source.fCchi2;
1046
1047   fITSchi2   = source.fITSchi2;             
1048   fTPCchi2   = source.fTPCchi2;            
1049   fTPCchi2Iter1   = source.fTPCchi2Iter1;            
1050   fTRDchi2   = source.fTRDchi2;      
1051   fTOFchi2   = source.fTOFchi2;      
1052   fHMPIDchi2 = source.fHMPIDchi2;      
1053
1054   fGlobalChi2 = source.fGlobalChi2;      
1055
1056   fITSsignal  = source.fITSsignal;     
1057   for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=source.fITSdEdxSamples[i];}
1058   fTPCsignal  = source.fTPCsignal;     
1059   fTPCsignalTuned  = source.fTPCsignalTuned;
1060   fTPCsignalS = source.fTPCsignalS;    
1061   for(int i = 0; i< 4;++i){
1062     fTPCPoints[i] = source.fTPCPoints[i];  
1063   }
1064   fTRDsignal = source.fTRDsignal;
1065   fTRDNchamberdEdx = source.fTRDNchamberdEdx;
1066   fTRDNclusterdEdx = source.fTRDNclusterdEdx;
1067
1068   for(int i = 0;i < kTRDnPlanes;++i){
1069     fTRDTimBin[i] = source.fTRDTimBin[i];   
1070   }
1071
1072   if(fTRDnSlices)
1073     delete[] fTRDslices;
1074   fTRDslices=0;
1075   fTRDnSlices=source.fTRDnSlices;
1076   if (fTRDnSlices) {
1077     fTRDslices=new Double32_t[fTRDnSlices];
1078     for(int j = 0;j < fTRDnSlices;++j) fTRDslices[j] = source.fTRDslices[j];
1079   }
1080
1081   fTRDQuality =   source.fTRDQuality;     
1082   fTRDBudget  =   source.fTRDBudget;      
1083   fTOFsignal  =   source.fTOFsignal;     
1084   fTOFsignalTuned  = source.fTOFsignalTuned;
1085   fTOFsignalToT = source.fTOFsignalToT;   
1086   fTOFsignalRaw = source.fTOFsignalRaw;  
1087   fTOFsignalDz  = source.fTOFsignalDz;      
1088   fTOFsignalDx  = source.fTOFsignalDx;      
1089   fTOFdeltaBC   = source.fTOFdeltaBC;
1090   fTOFl0l1      = source.fTOFl0l1;
1091  
1092   for(int i = 0;i<10;++i){
1093     fTOFInfo[i] = source.fTOFInfo[i];    
1094   }
1095
1096   fHMPIDtrkX = source.fHMPIDtrkX; 
1097   fHMPIDtrkY = source.fHMPIDtrkY; 
1098   fHMPIDmipX = source.fHMPIDmipX;
1099   fHMPIDmipY = source.fHMPIDmipY; 
1100
1101   fTPCncls    = source.fTPCncls;      
1102   fTPCnclsF   = source.fTPCnclsF;     
1103   fTPCsignalN = source.fTPCsignalN;   
1104   fTPCnclsIter1    = source.fTPCnclsIter1;      
1105   fTPCnclsFIter1   = source.fTPCnclsFIter1;     
1106
1107   fITSncls = source.fITSncls;       
1108   fITSClusterMap = source.fITSClusterMap; 
1109   fITSSharedMap = source.fITSSharedMap; 
1110   fTRDncls   = source.fTRDncls;       
1111   fTRDncls0  = source.fTRDncls0;      
1112   fTRDntracklets  = source.fTRDntracklets; 
1113   fVertexID = source.fVertexID;
1114   fPIDForTracking = source.fPIDForTracking;
1115
1116   fCacheNCrossedRows = source.fCacheNCrossedRows;
1117   fCacheChi2TPCConstrainedVsGlobal = source.fCacheChi2TPCConstrainedVsGlobal;
1118   fCacheChi2TPCConstrainedVsGlobalVertex = source.fCacheChi2TPCConstrainedVsGlobalVertex;
1119
1120   delete fDetectorPID;
1121   fDetectorPID=0x0;
1122   if (source.fDetectorPID) fDetectorPID = new AliDetectorPID(*source.fDetectorPID);
1123   
1124   fTrackPhiOnEMCal= source.fTrackPhiOnEMCal;
1125   fTrackEtaOnEMCal= source.fTrackEtaOnEMCal;
1126   fTrackPtOnEMCal= source.fTrackPtOnEMCal;
1127
1128   if(fTOFcluster){
1129     delete[] fTOFcluster;
1130   }
1131   fNtofClusters = source.fNtofClusters;
1132   if(fNtofClusters > 0){
1133     fTOFcluster = new Int_t[fNtofClusters];
1134         for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = source.fTOFcluster[i];
1135   }
1136
1137   return *this;
1138 }
1139
1140
1141
1142 void AliESDtrack::Copy(TObject &obj) const {
1143   
1144   // this overwrites the virtual TOBject::Copy()
1145   // to allow run time copying without casting
1146   // in AliESDEvent
1147
1148   if(this==&obj)return;
1149   AliESDtrack *robj = dynamic_cast<AliESDtrack*>(&obj);
1150   if(!robj)return; // not an AliESDtrack
1151   *robj = *this;
1152
1153 }
1154
1155
1156
1157 void AliESDtrack::AddCalibObject(TObject * object){
1158   //
1159   // add calib object to the list
1160   //
1161   if (!fFriendTrack) fFriendTrack  = new AliESDfriendTrack;
1162   if (!fFriendTrack) return;
1163   fFriendTrack->AddCalibObject(object);
1164 }
1165
1166 TObject *  AliESDtrack::GetCalibObject(Int_t index){
1167   //
1168   // return calib objct at given position
1169   //
1170   if (!fFriendTrack) return 0;
1171   return fFriendTrack->GetCalibObject(index);
1172 }
1173
1174
1175 Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
1176   
1177   // Fills the information of the TPC-only first reconstruction pass
1178   // into the passed ESDtrack object. For consistency fTPCInner is also filled
1179   // again
1180
1181
1182
1183   // For data produced before r26675
1184   // RelateToVertexTPC was not properly called during reco
1185   // so you'll have to call it again, before FillTPCOnlyTrack
1186   //  Float_t p[2],cov[3];
1187   // track->GetImpactParametersTPC(p,cov); 
1188   // if(p[0]==0&&p[1]==0) // <- Default values
1189   //  track->RelateToVertexTPC(esd->GetPrimaryVertexTPC(),esd->GetMagneticField(),kVeryBig);
1190   
1191
1192   if(!fTPCInner)return kFALSE;
1193
1194   // fill the TPC track params to the global track parameters
1195   track.Set(fTPCInner->GetX(),fTPCInner->GetAlpha(),fTPCInner->GetParameter(),fTPCInner->GetCovariance());
1196   track.fD = fdTPC;
1197   track.fZ = fzTPC;
1198   track.fCdd = fCddTPC;
1199   track.fCdz = fCdzTPC;
1200   track.fCzz = fCzzTPC;
1201
1202   // copy the inner params
1203   if(track.fIp) *track.fIp = *fIp;
1204   else track.fIp = new AliExternalTrackParam(*fIp);
1205
1206   // copy the TPCinner parameters
1207   if(track.fTPCInner) *track.fTPCInner = *fTPCInner;
1208   else track.fTPCInner = new AliExternalTrackParam(*fTPCInner);
1209   track.fdTPC   = fdTPC;
1210   track.fzTPC   = fzTPC;
1211   track.fCddTPC = fCddTPC;
1212   track.fCdzTPC = fCdzTPC;
1213   track.fCzzTPC = fCzzTPC;
1214   track.fCchi2TPC = fCchi2TPC;
1215
1216   // copy all other TPC specific parameters
1217
1218   // replace label by TPC label
1219   track.fLabel    = fTPCLabel;
1220   track.fTPCLabel = fTPCLabel;
1221
1222   track.fTPCchi2 = fTPCchi2; 
1223   track.fTPCchi2Iter1 = fTPCchi2Iter1; 
1224   track.fTPCsignal = fTPCsignal;
1225   track.fTPCsignalTuned = fTPCsignalTuned;
1226   track.fTPCsignalS = fTPCsignalS;
1227   for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
1228
1229   track.fTPCncls    = fTPCncls;     
1230   track.fTPCnclsF   = fTPCnclsF;     
1231   track.fTPCsignalN =  fTPCsignalN;
1232   track.fTPCnclsIter1    = fTPCnclsIter1;     
1233   track.fTPCnclsFIter1   = fTPCnclsFIter1;     
1234
1235   // PID 
1236   if (fTPCr) {
1237     if (!track.fTPCr) track.fTPCr = new Double32_t[AliPID::kSPECIES];
1238     for(int i=AliPID::kSPECIES;i--;) track.fTPCr[i] = fTPCr[i];
1239   }
1240   //
1241   if (fR) {
1242     if (!track.fR) track.fR = new Double32_t[AliPID::kSPECIES];
1243     for(int i=AliPID::kSPECIES;i--;) track.fR[i] = fR[i];
1244   }
1245     
1246   track.fTPCFitMap = fTPCFitMap;
1247   track.fTPCClusterMap = fTPCClusterMap;
1248   track.fTPCSharedMap = fTPCSharedMap;
1249
1250
1251   // reset the flags
1252   track.fFlags = kTPCin;
1253   track.fID    = fID;
1254
1255   track.fFlags |= fFlags & kTPCpid; //copy the TPCpid status flag
1256  
1257   for (Int_t i=0;i<3;i++) track.fKinkIndexes[i] = fKinkIndexes[i];
1258   
1259   return kTRUE;
1260     
1261 }
1262
1263 //_______________________________________________________________________
1264 void AliESDtrack::MakeMiniESDtrack(){
1265   // Resets everything except
1266   // fFlags: Reconstruction status flags 
1267   // fLabel: Track label
1268   // fID:  Unique ID of the track
1269   // Impact parameter information
1270   // fR[AliPID::kSPECIES]: combined "detector response probability"
1271   // Running track parameters in the base class (AliExternalTrackParam)
1272   
1273   fTrackLength = 0;
1274
1275   if(fTrackTime)
1276     for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i] = 0;
1277
1278   // Reset track parameters constrained to the primary vertex
1279   delete fCp;fCp = 0;
1280
1281   // Reset track parameters at the inner wall of TPC
1282   delete fIp;fIp = 0;
1283   delete fTPCInner;fTPCInner=0;
1284   // Reset track parameters at the inner wall of the TRD
1285   delete fOp;fOp = 0;
1286   // Reset track parameters at the HMPID
1287   delete fHMPIDp;fHMPIDp = 0;
1288
1289
1290   // Reset ITS track related information
1291   fITSchi2 = 0;
1292   fITSncls = 0;       
1293   fITSClusterMap=0;
1294   fITSSharedMap=0;
1295   fITSsignal = 0;     
1296   for (Int_t i=0;i<4;i++) fITSdEdxSamples[i] = 0.;
1297   if (fITSr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0; 
1298   fITSLabel = 0;       
1299
1300   // Reset TPC related track information
1301   fTPCchi2 = 0;       
1302   fTPCchi2Iter1 = 0;       
1303   fTPCncls = 0;       
1304   fTPCnclsF = 0;       
1305   fTPCnclsIter1 = 0;       
1306   fTPCnclsFIter1 = 0;  
1307   fTPCFitMap = 0;       
1308   fTPCClusterMap = 0;  
1309   fTPCSharedMap = 0;  
1310   fTPCsignal= 0;      
1311   fTPCsignalTuned= 0;
1312   fTPCsignalS= 0;      
1313   fTPCsignalN= 0;      
1314   if (fTPCr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i] = 0; 
1315   fTPCLabel=0;       
1316   for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
1317   for (Int_t i=0; i<3;i++)   fKinkIndexes[i] = 0;
1318   for (Int_t i=0; i<3;i++)   fV0Indexes[i] = 0;
1319
1320   // Reset TRD related track information
1321   fTRDchi2 = 0;        
1322   fTRDncls = 0;       
1323   fTRDncls0 = 0;       
1324   fTRDsignal = 0;      
1325   fTRDNchamberdEdx = 0;
1326   fTRDNclusterdEdx = 0;
1327
1328   for (Int_t i=0;i<kTRDnPlanes;i++) {
1329     fTRDTimBin[i]  = 0;
1330   }
1331   if (fTRDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0; 
1332   fTRDLabel = 0;       
1333   fTRDQuality  = 0;
1334   fTRDntracklets = 0;
1335   if(fTRDnSlices)
1336     delete[] fTRDslices;
1337   fTRDslices=0x0;
1338   fTRDnSlices=0;
1339   fTRDBudget  = 0;
1340
1341   // Reset TOF related track information
1342   fTOFchi2 = 0;        
1343   fTOFindex = -1;       
1344   fTOFsignal = 99999;      
1345   fTOFCalChannel = -1;
1346   fTOFsignalToT = 99999;
1347   fTOFsignalRaw = 99999;
1348   fTOFsignalDz = 999;
1349   fTOFsignalDx = 999;
1350   fTOFdeltaBC = 999;
1351   fTOFl0l1 = 999;
1352   if (fTOFr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
1353   for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
1354
1355   // Reset HMPID related track information
1356   fHMPIDchi2 = 0;     
1357   fHMPIDqn = 0;     
1358   fHMPIDcluIdx = -1;     
1359   fHMPIDsignal = 0;     
1360   if (fHMPIDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
1361   fHMPIDtrkTheta = 0;     
1362   fHMPIDtrkPhi = 0;      
1363   fHMPIDtrkX = 0;     
1364   fHMPIDtrkY = 0;      
1365   fHMPIDmipX = 0;
1366   fHMPIDmipY = 0;
1367   fCaloIndex = kEMCALNoMatch;
1368
1369   // reset global track chi2
1370   fGlobalChi2 = 0;
1371
1372   fVertexID = -2; // an orphan track
1373   fPIDForTracking = AliPID::kPion;
1374   //
1375   delete fFriendTrack; fFriendTrack = 0;
1376
1377
1378 //_______________________________________________________________________
1379 Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const 
1380 {
1381   // Returns the particle most probable id. For backward compatibility first the prob. arrays
1382   // will be checked, but normally the GetPIDForTracking will be returned
1383   Int_t i;
1384   const Double32_t *prob = 0;
1385   if (tpcOnly) { // check if TPCpid is valid
1386     if (!fTPCr) return GetPIDForTracking();
1387     prob = fTPCr;
1388     for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1389     if (i == AliPID::kSPECIES-1) prob = 0; // not valid, try with combined pid
1390   }
1391   if (!prob) { // either requested TPCpid is not valid or comb.pid is requested 
1392     if (!fR) return GetPIDForTracking();
1393     prob = fR;
1394     for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1395     if (i == AliPID::kSPECIES-1) return GetPIDForTracking();  // If all the probabilities are equal, return the pion mass
1396   }
1397   //
1398   Float_t max=0.;
1399   Int_t k=-1;
1400   for (i=0; i<AliPID::kSPECIES; i++) if (prob[i]>max) {k=i; max=prob[i];}
1401   //
1402   if (k==0) { // dE/dx "crossing points" in the TPC
1403     /*
1404     Double_t p=GetP();
1405     if ((p>0.38)&&(p<0.48))
1406       if (prob[0]<prob[3]*10.) return AliPID::kKaon;
1407     if ((p>0.75)&&(p<0.85))
1408       if (prob[0]<prob[4]*10.) return AliPID::kProton;
1409     */
1410     return AliPID::kElectron;
1411   }
1412   if (k==1) return AliPID::kMuon; 
1413   if (k==2||k==-1) return AliPID::kPion;
1414   if (k==3) return AliPID::kKaon;
1415   if (k==4) return AliPID::kProton;
1416   //  AliWarning("Undefined PID !");
1417   return GetPIDForTracking();
1418 }
1419
1420 //_______________________________________________________________________
1421 Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b, Bool_t pidTPConly) const 
1422 {
1423   // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
1424   const double kSpacing = 25e3; // min interbanch spacing
1425   const double kShift = 0;
1426   Int_t bcid = kTOFBCNA; // defualt one
1427   if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
1428   //
1429   double tdif = fTOFsignal;
1430   if (IsOn(kTIME)) { // integrated time info is there
1431     int pid = GetPID(pidTPConly);
1432     Double_t times[AliPID::kSPECIESC];
1433     // old esd has only AliPID::kSPECIES times
1434     GetIntegratedTimes(times,pid>=AliPID::kSPECIES ? AliPID::kSPECIESC : AliPID::kSPECIES); 
1435     tdif -= times[pid];
1436   }
1437   else { // assume integrated time info from TOF radius and momentum
1438     const double kRTOF = 385.;
1439     const double kCSpeed = 3.e-2; // cm/ps
1440     double p = GetP();
1441     if (p<0.01) return bcid;
1442     double m = GetMass(pidTPConly);
1443     double curv = GetC(b);
1444     double path = TMath::Abs(curv)>kAlmost0 ? // account for curvature
1445       2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+GetTgl()*GetTgl()) : kRTOF;
1446     tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
1447   }
1448   bcid = TMath::Nint((tdif - kShift)/kSpacing);
1449   return bcid;
1450 }
1451
1452 //______________________________________________________________________________
1453 Double_t AliESDtrack::M() const
1454 {
1455   // Returns the assumed mass
1456   // (the pion mass, if the particle can't be identified properly).
1457   static Bool_t printerr=kTRUE;
1458   if (printerr) {
1459      AliWarning("WARNING !!! ... THIS WILL BE PRINTED JUST ONCE !!!");
1460      printerr = kFALSE;
1461      AliWarning("This is the ESD mass. Use it with care !"); 
1462   }
1463   return GetMass(); 
1464 }
1465   
1466 //______________________________________________________________________________
1467 Double_t AliESDtrack::E() const
1468 {
1469   // Returns the energy of the particle given its assumed mass.
1470   // Assumes the pion mass if the particle can't be identified properly.
1471   
1472   Double_t m = M();
1473   Double_t p = P();
1474   return TMath::Sqrt(p*p + m*m);
1475 }
1476
1477 //______________________________________________________________________________
1478 Double_t AliESDtrack::Y() const
1479 {
1480   // Returns the rapidity of a particle given its assumed mass.
1481   // Assumes the pion mass if the particle can't be identified properly.
1482   
1483   Double_t e = E();
1484   Double_t pz = Pz();
1485   if (e != TMath::Abs(pz)) { // energy was not equal to pz
1486     return 0.5*TMath::Log((e+pz)/(e-pz));
1487   } else { // energy was equal to pz
1488     return -999.;
1489   }
1490 }
1491
1492 //_______________________________________________________________________
1493 Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
1494   //
1495   // This function updates track's running parameters 
1496   //
1497   Bool_t rc=kTRUE;
1498
1499   SetStatus(flags);
1500   fLabel=t->GetLabel();
1501
1502   if (t->IsStartedTimeIntegral()) {
1503     SetStatus(kTIME);
1504     Double_t times[AliPID::kSPECIESC];
1505     t->GetIntegratedTimes(times); 
1506     SetIntegratedTimes(times);
1507     SetIntegratedLength(t->GetIntegratedLength());
1508   }
1509
1510   Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1511   if (fFriendTrack) {
1512   if (flags==kITSout) fFriendTrack->SetITSOut(*t);
1513   if (flags==kTPCout) fFriendTrack->SetTPCOut(*t);
1514   if (flags==kTRDrefit) fFriendTrack->SetTRDIn(*t);
1515   }
1516   
1517   switch (flags) {
1518     
1519   case kITSin: 
1520     fITSchi2Std[0] = t->GetChi2();
1521     //
1522   case kITSout: 
1523     fITSchi2Std[1] = t->GetChi2();
1524   case kITSrefit:
1525     {
1526     fITSchi2Std[2] = t->GetChi2();
1527     fITSClusterMap=0;
1528     fITSncls=t->GetNumberOfClusters();
1529     if (fFriendTrack) {
1530     Int_t* indexITS = new Int_t[AliESDfriendTrack::kMaxITScluster];
1531     for (Int_t i=0;i<AliESDfriendTrack::kMaxITScluster;i++) {
1532         indexITS[i]=t->GetClusterIndex(i);
1533
1534         if (i<fITSncls) {
1535           Int_t l=(indexITS[i] & 0xf0000000) >> 28;
1536            SETBIT(fITSClusterMap,l);                 
1537         }
1538     }
1539     fFriendTrack->SetITSIndices(indexITS,AliESDfriendTrack::kMaxITScluster);
1540     delete [] indexITS;
1541     }
1542
1543     fITSchi2=t->GetChi2();
1544     fITSsignal=t->GetPIDsignal();
1545     fITSLabel = t->GetLabel();
1546     // keep in fOp the parameters outside ITS for ITS stand-alone tracks 
1547     if (flags==kITSout) { 
1548       if (!fOp) fOp=new AliExternalTrackParam(*t);
1549       else 
1550         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1551     }   
1552     }
1553     break;
1554     
1555   case kTPCin: case kTPCrefit:
1556     {
1557     fTPCLabel = t->GetLabel();
1558     if (flags==kTPCin)  {
1559       fTPCInner=new AliExternalTrackParam(*t); 
1560       fTPCnclsIter1=t->GetNumberOfClusters();    
1561       fTPCchi2Iter1=t->GetChi2();
1562     }
1563     if (!fIp) fIp=new AliExternalTrackParam(*t);
1564     else 
1565       fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1566     }
1567     // Intentionally no break statement; need to set general TPC variables as well
1568   case kTPCout:
1569     {
1570     if (flags & kTPCout){
1571       if (!fOp) fOp=new AliExternalTrackParam(*t);
1572       else 
1573         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1574     }
1575     fTPCncls=t->GetNumberOfClusters();    
1576     fTPCchi2=t->GetChi2();
1577     
1578     if (fFriendTrack) {  // Copy cluster indices
1579       Int_t* indexTPC = new Int_t[AliESDfriendTrack::kMaxTPCcluster];
1580       for (Int_t i=0;i<AliESDfriendTrack::kMaxTPCcluster;i++)         
1581         indexTPC[i]=t->GetClusterIndex(i);
1582       fFriendTrack->SetTPCIndices(indexTPC,AliESDfriendTrack::kMaxTPCcluster);
1583       delete [] indexTPC;
1584     }
1585     fTPCsignal=t->GetPIDsignal();
1586     }
1587     break;
1588
1589   case kTRDin: case kTRDrefit:
1590     break;
1591   case kTRDout:
1592     {
1593     fTRDLabel = t->GetLabel(); 
1594     fTRDchi2  = t->GetChi2();
1595     fTRDncls  = t->GetNumberOfClusters();
1596     if (fFriendTrack) {
1597       Int_t* indexTRD = new Int_t[AliESDfriendTrack::kMaxTRDcluster];
1598       for (Int_t i=0;i<AliESDfriendTrack::kMaxTRDcluster;i++) indexTRD[i]=-2;
1599       for (Int_t i=0;i<6;i++) indexTRD[i]=t->GetTrackletIndex(i);
1600       fFriendTrack->SetTRDIndices(indexTRD,AliESDfriendTrack::kMaxTRDcluster);
1601       delete [] indexTRD;
1602     }    
1603     
1604     //commented out by Xianguo
1605     //fTRDsignal=t->GetPIDsignal();
1606     }
1607     break;
1608   case kTRDbackup:
1609     if (!fOp) fOp=new AliExternalTrackParam(*t);
1610     else 
1611       fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1612     fTRDncls0 = t->GetNumberOfClusters(); 
1613     break;
1614   case kTOFin: 
1615     break;
1616   case kTOFout: 
1617     break;
1618   case kTRDStop:
1619     break;
1620   case kHMPIDout:
1621   if (!fHMPIDp) fHMPIDp=new AliExternalTrackParam(*t);
1622     else 
1623       fHMPIDp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1624     break;
1625   default: 
1626     AliError("Wrong flag !");
1627     return kFALSE;
1628   }
1629
1630   return rc;
1631 }
1632
1633 //_______________________________________________________________________
1634 void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const {
1635   //---------------------------------------------------------------------
1636   // This function returns external representation of the track parameters
1637   //---------------------------------------------------------------------
1638   x=GetX();
1639   for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i];
1640 }
1641
1642 //_______________________________________________________________________
1643 void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const {
1644   //---------------------------------------------------------------------
1645   // This function returns external representation of the cov. matrix
1646   //---------------------------------------------------------------------
1647   for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i];
1648 }
1649
1650 //_______________________________________________________________________
1651 Bool_t AliESDtrack::GetConstrainedExternalParameters
1652                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1653   //---------------------------------------------------------------------
1654   // This function returns the constrained external track parameters
1655   //---------------------------------------------------------------------
1656   if (!fCp) return kFALSE;
1657   alpha=fCp->GetAlpha();
1658   x=fCp->GetX();
1659   for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i];
1660   return kTRUE;
1661 }
1662
1663 //_______________________________________________________________________
1664 Bool_t 
1665 AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const {
1666   //---------------------------------------------------------------------
1667   // This function returns the constrained external cov. matrix
1668   //---------------------------------------------------------------------
1669   if (!fCp) return kFALSE;
1670   for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i];
1671   return kTRUE;
1672 }
1673
1674 Bool_t
1675 AliESDtrack::GetInnerExternalParameters
1676                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1677   //---------------------------------------------------------------------
1678   // This function returns external representation of the track parameters 
1679   // at the inner layer of TPC
1680   //---------------------------------------------------------------------
1681   if (!fIp) return kFALSE;
1682   alpha=fIp->GetAlpha();
1683   x=fIp->GetX();
1684   for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i];
1685   return kTRUE;
1686 }
1687
1688 Bool_t 
1689 AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const {
1690  //---------------------------------------------------------------------
1691  // This function returns external representation of the cov. matrix 
1692  // at the inner layer of TPC
1693  //---------------------------------------------------------------------
1694   if (!fIp) return kFALSE;
1695   for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i];
1696   return kTRUE;
1697 }
1698
1699 void 
1700 AliESDtrack::SetOuterParam(const AliExternalTrackParam *p, ULong_t flags) {
1701   //
1702   // This is a direct setter for the outer track parameters
1703   //
1704   SetStatus(flags);
1705   if (fOp) delete fOp;
1706   fOp=new AliExternalTrackParam(*p);
1707 }
1708
1709 void 
1710 AliESDtrack::SetOuterHmpParam(const AliExternalTrackParam *p, ULong_t flags) {
1711   //
1712   // This is a direct setter for the outer track parameters
1713   //
1714   SetStatus(flags);
1715   if (fHMPIDp) delete fHMPIDp;
1716   fHMPIDp=new AliExternalTrackParam(*p);
1717 }
1718
1719 Bool_t 
1720 AliESDtrack::GetOuterExternalParameters
1721                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1722   //---------------------------------------------------------------------
1723   // This function returns external representation of the track parameters 
1724   // at the inner layer of TRD
1725   //---------------------------------------------------------------------
1726   if (!fOp) return kFALSE;
1727   alpha=fOp->GetAlpha();
1728   x=fOp->GetX();
1729   for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i];
1730   return kTRUE;
1731 }
1732
1733 Bool_t 
1734 AliESDtrack::GetOuterHmpExternalParameters
1735                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1736   //---------------------------------------------------------------------
1737   // This function returns external representation of the track parameters 
1738   // at the inner layer of TRD
1739   //---------------------------------------------------------------------
1740   if (!fHMPIDp) return kFALSE;
1741   alpha=fHMPIDp->GetAlpha();
1742   x=fHMPIDp->GetX();
1743   for (Int_t i=0; i<5; i++) p[i]=fHMPIDp->GetParameter()[i];
1744   return kTRUE;
1745 }
1746
1747 Bool_t 
1748 AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const {
1749  //---------------------------------------------------------------------
1750  // This function returns external representation of the cov. matrix 
1751  // at the inner layer of TRD
1752  //---------------------------------------------------------------------
1753   if (!fOp) return kFALSE;
1754   for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i];
1755   return kTRUE;
1756 }
1757
1758 Bool_t 
1759 AliESDtrack::GetOuterHmpExternalCovariance(Double_t cov[15]) const {
1760  //---------------------------------------------------------------------
1761  // This function returns external representation of the cov. matrix 
1762  // at the inner layer of TRD
1763  //---------------------------------------------------------------------
1764   if (!fHMPIDp) return kFALSE;
1765   for (Int_t i=0; i<15; i++) cov[i]=fHMPIDp->GetCovariance()[i];
1766   return kTRUE;
1767 }
1768
1769 Int_t AliESDtrack::GetNcls(Int_t idet) const
1770 {
1771   // Get number of clusters by subdetector index
1772   //
1773   Int_t ncls = 0;
1774   switch(idet){
1775   case 0:
1776     ncls = fITSncls;
1777     break;
1778   case 1:
1779     ncls = fTPCncls;
1780     break;
1781   case 2:
1782     ncls = fTRDncls;
1783     break;
1784   case 3:
1785     if (fTOFindex != -1)
1786       ncls = 1;
1787     break;
1788   case 4: //PHOS
1789     break;
1790   case 5: //HMPID
1791     if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1792       if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1793         ncls = 1;
1794       }
1795     }    
1796     break;
1797   default:
1798     break;
1799   }
1800   return ncls;
1801 }
1802
1803 Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
1804 {
1805   // Get cluster index array by subdetector index
1806   //
1807   Int_t ncls = 0;
1808   switch(idet){
1809   case 0:
1810     ncls = GetITSclusters(idx);
1811     break;
1812   case 1:
1813     ncls = GetTPCclusters(idx);
1814     break;
1815   case 2:
1816     ncls = GetTRDclusters(idx);
1817     break;
1818   case 3:
1819     if (fTOFindex != -1) {
1820       idx[0] = fTOFindex;
1821       ncls = 1;
1822     }
1823     break;
1824   case 4: //PHOS
1825     break;
1826   case 5:
1827     if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1828       if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1829         idx[0] = GetHMPIDcluIdx();
1830         ncls = 1;
1831       }
1832     }    
1833     break;
1834   case 6: //EMCAL
1835     break;
1836   default:
1837     break;
1838   }
1839   return ncls;
1840 }
1841
1842 //_______________________________________________________________________
1843 void AliESDtrack::GetIntegratedTimes(Double_t *times, Int_t nspec) const 
1844 {
1845   // get integrated time for requested N species
1846   if (nspec<1) return;
1847   if(fNtofClusters>0 && GetESDEvent()){
1848     TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
1849     AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
1850     //
1851     for(int i=tofcl->GetNMatchableTracks();i--;){
1852       if(tofcl->GetTrackIndex(i) == GetID()) {
1853         for (int j=nspec; j--;) times[j]=tofcl->GetIntegratedTime(j,i);
1854         return;
1855       }
1856     }
1857   }
1858   else if(fNtofClusters>0) 
1859     AliInfo("No AliESDEvent available here!\n");
1860
1861   // Returns the array with integrated times for each particle hypothesis
1862   if(fTrackTime)
1863     for (int i=nspec; i--;) times[i]=fTrackTime[i];
1864   else
1865     for (int i=AliPID::kSPECIESC; i--;) times[i]=0.0;
1866   //
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) const {
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 //___________________________________________
3288 void AliESDtrack::SetID(Short_t id) 
3289 {
3290   // set track ID taking care about dependencies
3291   if (fNtofClusters) ReplaceTOFTrackID(fID,id); 
3292   fID=id;
3293 }