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