125ab6f900161d49df575027d25207a04510e55c
[u/mrichter/AliRoot.git] / STEER / 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
120 #include "AliESDVertex.h"
121 #include "AliESDtrack.h"
122 #include "AliKalmanTrack.h"
123 #include "AliVTrack.h"
124 #include "AliLog.h"
125 #include "AliTrackPointArray.h"
126 #include "TPolyMarker3D.h"
127
128 ClassImp(AliESDtrack)
129
130 void SetPIDValues(Double_t * dest, const Double_t * src, Int_t n) {
131   // This function copies "n" PID weights from "scr" to "dest"
132   // and normalizes their sum to 1 thus producing conditional probabilities.
133   // The negative weights are set to 0.
134   // In case all the weights are non-positive they are replaced by
135   // uniform probabilities
136
137   if (n<=0) return;
138
139   Float_t uniform = 1./(Float_t)n;
140
141   Float_t sum = 0;
142   for (Int_t i=0; i<n; i++) 
143     if (src[i]>=0) {
144       sum+=src[i];
145       dest[i] = src[i];
146     }
147     else {
148       dest[i] = 0;
149     }
150
151   if(sum>0)
152     for (Int_t i=0; i<n; i++) dest[i] /= sum;
153   else
154     for (Int_t i=0; i<n; i++) dest[i] = uniform;
155 }
156
157 //_______________________________________________________________________
158 AliESDtrack::AliESDtrack() : 
159   AliExternalTrackParam(),
160   fCp(0),
161   fIp(0),
162   fTPCInner(0),
163   fOp(0),
164   fHMPIDp(0),  
165   fFriendTrack(new AliESDfriendTrack()),
166   fTPCClusterMap(159),//number of padrows
167   fTPCSharedMap(159),//number of padrows
168   fFlags(0),
169   fID(0),
170   fLabel(0),
171   fITSLabel(0),
172   fTPCLabel(0),
173   fTRDLabel(0),
174   fTOFCalChannel(0),
175   fTOFindex(-1),
176   fHMPIDqn(0),
177   fHMPIDcluIdx(-1),
178   fEMCALindex(kEMCALNoMatch),
179   fHMPIDtrkTheta(0),
180   fHMPIDtrkPhi(0),
181   fHMPIDsignal(0),
182   fTrackLength(0),
183   fdTPC(0),fzTPC(0),
184   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
185   fCchi2TPC(0),
186   fD(0),fZ(0),
187   fCdd(0),fCdz(0),fCzz(0),
188   fCchi2(0),
189   fITSchi2(0),
190   fTPCchi2(0),
191   fTRDchi2(0),
192   fTOFchi2(0),
193   fHMPIDchi2(0),
194   fGlobalChi2(0),
195   fITSsignal(0),
196   fTPCsignal(0),
197   fTPCsignalS(0),
198   fTRDsignal(0),
199   fTRDQuality(0),
200   fTRDBudget(0),
201   fTOFsignal(0),
202   fTOFsignalToT(0),
203   fTOFsignalRaw(0),
204   fTOFsignalDz(0),
205   fTOFsignalDx(0),
206   fHMPIDtrkX(0),
207   fHMPIDtrkY(0),
208   fHMPIDmipX(0),
209   fHMPIDmipY(0),
210   fTPCncls(0),
211   fTPCnclsF(0),
212   fTPCsignalN(0),
213   fITSncls(0),
214   fITSClusterMap(0),
215   fTRDncls(0),
216   fTRDncls0(0),
217   fTRDntracklets(0),
218   fTRDnSlices(0),
219   fTRDslices(0x0),
220   fVertexID(-2) // -2 means an orphan track 
221 {
222   //
223   // The default ESD constructor 
224   //
225   Int_t i;
226   for (i=0; i<AliPID::kSPECIES; i++) {
227     fTrackTime[i]=0.;
228     fR[i]=0.;
229     fITSr[i]=0.;
230     fTPCr[i]=0.;
231     fTRDr[i]=0.;
232     fTOFr[i]=0.;
233     fHMPIDr[i]=0.;
234   }
235   
236   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
237   for (i=0; i<3; i++)   { fV0Indexes[i]=0;}
238   for (i=0;i<kTRDnPlanes;i++) {
239     fTRDTimBin[i]=0;
240   }
241   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
242   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
243   for (i=0;i<3;i++) {fTOFLabel[i]=0;}
244   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
245   for (i=0;i<12;i++) {fITSModule[i]=-1;}
246 }
247
248 //_______________________________________________________________________
249 AliESDtrack::AliESDtrack(const AliESDtrack& track):
250   AliExternalTrackParam(track),
251   fCp(0),
252   fIp(0),
253   fTPCInner(0),
254   fOp(0),
255   fHMPIDp(0),  
256   fFriendTrack(0),
257   fTPCClusterMap(track.fTPCClusterMap),
258   fTPCSharedMap(track.fTPCSharedMap),
259   fFlags(track.fFlags),
260   fID(track.fID),
261   fLabel(track.fLabel),
262   fITSLabel(track.fITSLabel),
263   fTPCLabel(track.fTPCLabel),
264   fTRDLabel(track.fTRDLabel),
265   fTOFCalChannel(track.fTOFCalChannel),
266   fTOFindex(track.fTOFindex),
267   fHMPIDqn(track.fHMPIDqn),
268   fHMPIDcluIdx(track.fHMPIDcluIdx),
269   fEMCALindex(track.fEMCALindex),
270   fHMPIDtrkTheta(track.fHMPIDtrkTheta),
271   fHMPIDtrkPhi(track.fHMPIDtrkPhi),
272   fHMPIDsignal(track.fHMPIDsignal),
273   fTrackLength(track.fTrackLength),
274   fdTPC(track.fdTPC),fzTPC(track.fzTPC),
275   fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
276   fCchi2TPC(track.fCchi2TPC),
277   fD(track.fD),fZ(track.fZ),
278   fCdd(track.fCdd),fCdz(track.fCdz),fCzz(track.fCzz),
279   fCchi2(track.fCchi2),
280   fITSchi2(track.fITSchi2),
281   fTPCchi2(track.fTPCchi2),
282   fTRDchi2(track.fTRDchi2),
283   fTOFchi2(track.fTOFchi2),
284   fHMPIDchi2(track.fHMPIDchi2),
285   fGlobalChi2(track.fGlobalChi2),
286   fITSsignal(track.fITSsignal),
287   fTPCsignal(track.fTPCsignal),
288   fTPCsignalS(track.fTPCsignalS),
289   fTRDsignal(track.fTRDsignal),
290   fTRDQuality(track.fTRDQuality),
291   fTRDBudget(track.fTRDBudget),
292   fTOFsignal(track.fTOFsignal),
293   fTOFsignalToT(track.fTOFsignalToT),
294   fTOFsignalRaw(track.fTOFsignalRaw),
295   fTOFsignalDz(track.fTOFsignalDz),
296   fTOFsignalDx(track.fTOFsignalDx),
297   fHMPIDtrkX(track.fHMPIDtrkX),
298   fHMPIDtrkY(track.fHMPIDtrkY),
299   fHMPIDmipX(track.fHMPIDmipX),
300   fHMPIDmipY(track.fHMPIDmipY),
301   fTPCncls(track.fTPCncls),
302   fTPCnclsF(track.fTPCnclsF),
303   fTPCsignalN(track.fTPCsignalN),
304   fITSncls(track.fITSncls),
305   fITSClusterMap(track.fITSClusterMap),
306   fTRDncls(track.fTRDncls),
307   fTRDncls0(track.fTRDncls0),
308   fTRDntracklets(track.fTRDntracklets),
309   fTRDnSlices(track.fTRDnSlices),
310   fTRDslices(0x0),
311   fVertexID(track.fVertexID)
312 {
313   //
314   //copy constructor
315   //
316   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i]=track.fTrackTime[i];
317   for (Int_t i=0;i<AliPID::kSPECIES;i++)  fR[i]=track.fR[i];
318   //
319   for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=track.fITSr[i]; 
320   //
321   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=track.fTPCr[i]; 
322   for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=track.fITSdEdxSamples[i];}
323   for (Int_t i=0;i<4;i++) {fTPCPoints[i]=track.fTPCPoints[i];}
324   for (Int_t i=0; i<3;i++)   { fKinkIndexes[i]=track.fKinkIndexes[i];}
325   for (Int_t i=0; i<3;i++)   { fV0Indexes[i]=track.fV0Indexes[i];}
326   //
327   for (Int_t i=0;i<kTRDnPlanes;i++) {
328     fTRDTimBin[i]=track.fTRDTimBin[i];
329   }
330
331   if (fTRDnSlices) {
332     fTRDslices=new Double32_t[fTRDnSlices];
333     for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=track.fTRDslices[i];
334   }
335
336   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i]=track.fTRDr[i]; 
337   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i]=track.fTOFr[i];
338   for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
339   for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
340   for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
341   for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i]=track.fHMPIDr[i];
342
343   if (track.fCp) fCp=new AliExternalTrackParam(*track.fCp);
344   if (track.fIp) fIp=new AliExternalTrackParam(*track.fIp);
345   if (track.fTPCInner) fTPCInner=new AliExternalTrackParam(*track.fTPCInner);
346   if (track.fOp) fOp=new AliExternalTrackParam(*track.fOp);
347   if (track.fHMPIDp) fHMPIDp=new AliExternalTrackParam(*track.fHMPIDp);
348   
349   if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
350 }
351
352 //_______________________________________________________________________
353 AliESDtrack::AliESDtrack(const AliVTrack *track) : 
354   AliExternalTrackParam(track),
355   fCp(0),
356   fIp(0),
357   fTPCInner(0),
358   fOp(0),
359   fHMPIDp(0),  
360   fFriendTrack(0),
361   fTPCClusterMap(159),//number of padrows
362   fTPCSharedMap(159),//number of padrows
363   fFlags(0),
364   fID(),
365   fLabel(0),
366   fITSLabel(0),
367   fTPCLabel(0),
368   fTRDLabel(0),
369   fTOFCalChannel(0),
370   fTOFindex(-1),
371   fHMPIDqn(0),
372   fHMPIDcluIdx(-1),
373   fEMCALindex(kEMCALNoMatch),
374   fHMPIDtrkTheta(0),
375   fHMPIDtrkPhi(0),
376   fHMPIDsignal(0),
377   fTrackLength(0),
378   fdTPC(0),fzTPC(0),
379   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
380   fCchi2TPC(0),
381   fD(0),fZ(0),
382   fCdd(0),fCdz(0),fCzz(0),
383   fCchi2(0),
384   fITSchi2(0),
385   fTPCchi2(0),
386   fTRDchi2(0),
387   fTOFchi2(0),
388   fHMPIDchi2(0),
389   fGlobalChi2(0),
390   fITSsignal(0),
391   fTPCsignal(0),
392   fTPCsignalS(0),
393   fTRDsignal(0),
394   fTRDQuality(0),
395   fTRDBudget(0),
396   fTOFsignal(0),
397   fTOFsignalToT(0),
398   fTOFsignalRaw(0),
399   fTOFsignalDz(0),
400   fTOFsignalDx(0),
401   fHMPIDtrkX(0),
402   fHMPIDtrkY(0),
403   fHMPIDmipX(0),
404   fHMPIDmipY(0),
405   fTPCncls(0),
406   fTPCnclsF(0),
407   fTPCsignalN(0),
408   fITSncls(0),
409   fITSClusterMap(0),
410   fTRDncls(0),
411   fTRDncls0(0),
412   fTRDntracklets(0),
413   fTRDnSlices(0),
414   fTRDslices(0x0),
415   fVertexID(-2)  // -2 means an orphan track
416 {
417   //
418   // ESD track from AliVTrack.
419   // This is not a copy constructor !
420   //
421
422   if (track->InheritsFrom("AliExternalTrackParam")) {
423      AliError("This is not a copy constructor. Use AliESDtrack(const AliESDtrack &) !");
424      AliWarning("Calling the default constructor...");
425      AliESDtrack();
426      return;
427   }
428
429   // Reset all the arrays
430   Int_t i;
431   for (i=0; i<AliPID::kSPECIES; i++) {
432     fTrackTime[i]=0.;
433     fR[i]=0.;
434     fITSr[i]=0.;
435     fTPCr[i]=0.;
436     fTRDr[i]=0.;
437     fTOFr[i]=0.;
438     fHMPIDr[i]=0.;
439   }
440   
441   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
442   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
443   for (i=0;i<kTRDnPlanes;i++) {
444     fTRDTimBin[i]=0;
445   }
446   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
447   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
448   for (i=0;i<3;i++) {fTOFLabel[i]=0;}
449   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
450   for (i=0;i<12;i++) {fITSModule[i]=-1;}
451
452   // Set the ID
453   SetID(track->GetID());
454
455   // Set ITS cluster map
456   fITSClusterMap=track->GetITSClusterMap();
457
458   fITSncls=0;
459   for(i=0; i<6; i++) {
460     if(HasPointOnITSLayer(i)) fITSncls++;
461   }
462
463   // Set the combined PID
464   const Double_t *pid = track->PID();
465   if(pid){
466     for (i=0; i<AliPID::kSPECIES; i++) fR[i]=pid[i];
467   }
468   // AliESD track label
469   SetLabel(track->GetLabel());
470   // Set the status
471   SetStatus(track->GetStatus());
472 }
473
474 //_______________________________________________________________________
475 AliESDtrack::AliESDtrack(TParticle * part) : 
476   AliExternalTrackParam(),
477   fCp(0),
478   fIp(0),
479   fTPCInner(0),
480   fOp(0),
481   fHMPIDp(0),  
482   fFriendTrack(0),
483   fTPCClusterMap(159),//number of padrows
484   fTPCSharedMap(159),//number of padrows
485   fFlags(0),
486   fID(0),
487   fLabel(0),
488   fITSLabel(0),
489   fTPCLabel(0),
490   fTRDLabel(0),
491   fTOFCalChannel(0),
492   fTOFindex(-1),
493   fHMPIDqn(0),
494   fHMPIDcluIdx(-1),
495   fEMCALindex(kEMCALNoMatch),
496   fHMPIDtrkTheta(0),
497   fHMPIDtrkPhi(0),
498   fHMPIDsignal(0),
499   fTrackLength(0),
500   fdTPC(0),fzTPC(0),
501   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
502   fCchi2TPC(0),
503   fD(0),fZ(0),
504   fCdd(0),fCdz(0),fCzz(0),
505   fCchi2(0),
506   fITSchi2(0),
507   fTPCchi2(0),
508   fTRDchi2(0),
509   fTOFchi2(0),
510   fHMPIDchi2(0),
511   fGlobalChi2(0),
512   fITSsignal(0),
513   fTPCsignal(0),
514   fTPCsignalS(0),
515   fTRDsignal(0),
516   fTRDQuality(0),
517   fTRDBudget(0),
518   fTOFsignal(0),
519   fTOFsignalToT(0),
520   fTOFsignalRaw(0),
521   fTOFsignalDz(0),
522   fTOFsignalDx(0),
523   fHMPIDtrkX(0),
524   fHMPIDtrkY(0),
525   fHMPIDmipX(0),
526   fHMPIDmipY(0),
527   fTPCncls(0),
528   fTPCnclsF(0),
529   fTPCsignalN(0),
530   fITSncls(0),
531   fITSClusterMap(0),
532   fTRDncls(0),
533   fTRDncls0(0),
534   fTRDntracklets(0),
535   fTRDnSlices(0),
536   fTRDslices(0x0),
537   fVertexID(-2)  // -2 means an orphan track
538 {
539   //
540   // ESD track from TParticle
541   //
542
543   // Reset all the arrays
544   Int_t i;
545   for (i=0; i<AliPID::kSPECIES; i++) {
546     fTrackTime[i]=0.;
547     fR[i]=0.;
548     fITSr[i]=0.;
549     fTPCr[i]=0.;
550     fTRDr[i]=0.;
551     fTOFr[i]=0.;
552     fHMPIDr[i]=0.;
553   }
554   
555   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
556   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
557   for (i=0;i<kTRDnPlanes;i++) {
558     fTRDTimBin[i]=0;
559   }
560   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
561   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
562   for (i=0;i<3;i++) {fTOFLabel[i]=0;}
563   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
564   for (i=0;i<12;i++) {fITSModule[i]=-1;}
565
566   // Calculate the AliExternalTrackParam content
567
568   Double_t xref;
569   Double_t alpha;
570   Double_t param[5];
571   Double_t covar[15];
572
573   // Calculate alpha: the rotation angle of the corresponding local system (TPC sector)
574   alpha = part->Phi()*180./TMath::Pi();
575   if (alpha<0) alpha+= 360.;
576   if (alpha>360) alpha -= 360.;
577
578   Int_t sector = (Int_t)(alpha/20.);
579   alpha = 10. + 20.*sector;
580   alpha /= 180;
581   alpha *= TMath::Pi();
582
583   // Covariance matrix: no errors, the parameters are exact
584   for (i=0; i<15; i++) covar[i]=0.;
585
586   // Get the vertex of origin and the momentum
587   TVector3 ver(part->Vx(),part->Vy(),part->Vz());
588   TVector3 mom(part->Px(),part->Py(),part->Pz());
589
590   // Rotate to the local coordinate system (TPC sector)
591   ver.RotateZ(-alpha);
592   mom.RotateZ(-alpha);
593
594   // X of the referense plane
595   xref = ver.X();
596
597   Int_t pdgCode = part->GetPdgCode();
598
599   Double_t charge = 
600     TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge();
601
602   param[0] = ver.Y();
603   param[1] = ver.Z();
604   param[2] = TMath::Sin(mom.Phi());
605   param[3] = mom.Pz()/mom.Pt();
606   param[4] = TMath::Sign(1/mom.Pt(),charge);
607
608   // Set AliExternalTrackParam
609   Set(xref, alpha, param, covar);
610
611   // Set the PID
612   Int_t indexPID = 99;
613
614   switch (TMath::Abs(pdgCode)) {
615
616   case  11: // electron
617     indexPID = 0;
618     break;
619
620   case 13: // muon
621     indexPID = 1;
622     break;
623
624   case 211: // pion
625     indexPID = 2;
626     break;
627
628   case 321: // kaon
629     indexPID = 3;
630     break;
631
632   case 2212: // proton
633     indexPID = 4;
634     break;
635
636   default:
637     break;
638   }
639
640   // If the particle is not e,mu,pi,K or p the PID probabilities are set to 0
641   if (indexPID < AliPID::kSPECIES) {
642     fR[indexPID]=1.;
643     fITSr[indexPID]=1.;
644     fTPCr[indexPID]=1.;
645     fTRDr[indexPID]=1.;
646     fTOFr[indexPID]=1.;
647     fHMPIDr[indexPID]=1.;
648
649   }
650   // AliESD track label
651   SetLabel(part->GetUniqueID());
652
653 }
654
655 //_______________________________________________________________________
656 AliESDtrack::~AliESDtrack(){ 
657   //
658   // This is destructor according Coding Conventrions 
659   //
660   //printf("Delete track\n");
661   delete fIp; 
662   delete fTPCInner; 
663   delete fOp;
664   delete fHMPIDp;
665   delete fCp; 
666   delete fFriendTrack;
667   if(fTRDnSlices)
668     delete[] fTRDslices;
669 }
670
671 AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
672   
673
674   if(&source == this) return *this;
675   AliExternalTrackParam::operator=(source);
676
677   
678   if(source.fCp){
679     // we have the trackparam: assign or copy construct
680     if(fCp)*fCp = *source.fCp;
681     else fCp = new AliExternalTrackParam(*source.fCp);
682   }
683   else{
684     // no track param delete the old one
685     if(fCp)delete fCp;
686     fCp = 0;
687   }
688
689   if(source.fIp){
690     // we have the trackparam: assign or copy construct
691     if(fIp)*fIp = *source.fIp;
692     else fIp = new AliExternalTrackParam(*source.fIp);
693   }
694   else{
695     // no track param delete the old one
696     if(fIp)delete fIp;
697     fIp = 0;
698   }
699
700
701   if(source.fTPCInner){
702     // we have the trackparam: assign or copy construct
703     if(fTPCInner) *fTPCInner = *source.fTPCInner;
704     else fTPCInner = new AliExternalTrackParam(*source.fTPCInner);
705   }
706   else{
707     // no track param delete the old one
708     if(fTPCInner)delete fTPCInner;
709     fTPCInner = 0;
710   }
711
712
713   if(source.fOp){
714     // we have the trackparam: assign or copy construct
715     if(fOp) *fOp = *source.fOp;
716     else fOp = new AliExternalTrackParam(*source.fOp);
717   }
718   else{
719     // no track param delete the old one
720     if(fOp)delete fOp;
721     fOp = 0;
722   }
723
724   
725   if(source.fHMPIDp){
726     // we have the trackparam: assign or copy construct
727     if(fHMPIDp) *fHMPIDp = *source.fHMPIDp;
728     else fHMPIDp = new AliExternalTrackParam(*source.fHMPIDp);
729   }
730   else{
731     // no track param delete the old one
732     if(fHMPIDp)delete fHMPIDp;
733     fHMPIDp = 0;
734   }
735
736   
737   // copy also the friend track 
738   // use copy constructor
739   if(source.fFriendTrack){
740     // we have the trackparam: assign or copy construct
741     delete fFriendTrack; fFriendTrack=new AliESDfriendTrack(*source.fFriendTrack);
742   }
743   else{
744     // no track param delete the old one
745     delete fFriendTrack; fFriendTrack= 0;
746   }
747
748   fTPCClusterMap = source.fTPCClusterMap; 
749   fTPCSharedMap  = source.fTPCSharedMap;  
750   // the simple stuff
751   fFlags    = source.fFlags; 
752   fID       = source.fID;             
753   fLabel    = source.fLabel;
754   fITSLabel = source.fITSLabel;
755   for(int i = 0; i< 12;++i){
756     fITSModule[i] = source.fITSModule[i];
757   }
758   fTPCLabel = source.fTPCLabel; 
759   fTRDLabel = source.fTRDLabel;
760   for(int i = 0; i< 3;++i){
761     fTOFLabel[i] = source.fTOFLabel[i];    
762   }
763   fTOFCalChannel = source.fTOFCalChannel;
764   fTOFindex      = source.fTOFindex;
765   fHMPIDqn       = source.fHMPIDqn;
766   fHMPIDcluIdx   = source.fHMPIDcluIdx; 
767   fEMCALindex    = source.fEMCALindex;
768
769   for(int i = 0; i< 3;++i){
770     fKinkIndexes[i] = source.fKinkIndexes[i]; 
771     fV0Indexes[i]   = source.fV0Indexes[i]; 
772   }
773
774   for(int i = 0; i< AliPID::kSPECIES;++i){
775     fR[i]     = source.fR[i];
776     fITSr[i]  = source.fITSr[i];
777     fTPCr[i]  = source.fTPCr[i];
778     fTRDr[i]  = source.fTRDr[i];
779     fTOFr[i]  = source.fTOFr[i];
780     fHMPIDr[i] = source.fHMPIDr[i];
781     fTrackTime[i] = source.fTrackTime[i];  
782   }
783
784   fHMPIDtrkTheta = source.fHMPIDtrkTheta;
785   fHMPIDtrkPhi   = source.fHMPIDtrkPhi;
786   fHMPIDsignal   = source.fHMPIDsignal; 
787
788   
789   fTrackLength   = source. fTrackLength;
790   fdTPC  = source.fdTPC; 
791   fzTPC  = source.fzTPC; 
792   fCddTPC = source.fCddTPC;
793   fCdzTPC = source.fCdzTPC;
794   fCzzTPC = source.fCzzTPC;
795   fCchi2TPC = source.fCchi2TPC;
796
797   fD  = source.fD; 
798   fZ  = source.fZ; 
799   fCdd = source.fCdd;
800   fCdz = source.fCdz;
801   fCzz = source.fCzz;
802   fCchi2     = source.fCchi2;
803
804   fITSchi2   = source.fITSchi2;             
805   fTPCchi2   = source.fTPCchi2;            
806   fTRDchi2   = source.fTRDchi2;      
807   fTOFchi2   = source.fTOFchi2;      
808   fHMPIDchi2 = source.fHMPIDchi2;      
809
810   fGlobalChi2 = source.fGlobalChi2;      
811
812   fITSsignal  = source.fITSsignal;     
813   for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=source.fITSdEdxSamples[i];}
814   fTPCsignal  = source.fTPCsignal;     
815   fTPCsignalS = source.fTPCsignalS;    
816   for(int i = 0; i< 4;++i){
817     fTPCPoints[i] = source.fTPCPoints[i];  
818   }
819   fTRDsignal = source.fTRDsignal;
820
821   for(int i = 0;i < kTRDnPlanes;++i){
822     fTRDTimBin[i] = source.fTRDTimBin[i];   
823   }
824
825   if(fTRDnSlices)
826     delete[] fTRDslices;
827   fTRDslices=0;
828   fTRDnSlices=source.fTRDnSlices;
829   if (fTRDnSlices) {
830     fTRDslices=new Double32_t[fTRDnSlices];
831     for(int j = 0;j < fTRDnSlices;++j) fTRDslices[j] = source.fTRDslices[j];
832   }
833
834   fTRDQuality =   source.fTRDQuality;     
835   fTRDBudget  =   source.fTRDBudget;      
836   fTOFsignal  =   source.fTOFsignal;     
837   fTOFsignalToT = source.fTOFsignalToT;   
838   fTOFsignalRaw = source.fTOFsignalRaw;  
839   fTOFsignalDz  = source.fTOFsignalDz;      
840   fTOFsignalDx  = source.fTOFsignalDx;      
841   
842   for(int i = 0;i<10;++i){
843     fTOFInfo[i] = source.fTOFInfo[i];    
844   }
845
846   fHMPIDtrkX = source.fHMPIDtrkX; 
847   fHMPIDtrkY = source.fHMPIDtrkY; 
848   fHMPIDmipX = source.fHMPIDmipX;
849   fHMPIDmipY = source.fHMPIDmipY; 
850
851   fTPCncls    = source.fTPCncls;      
852   fTPCnclsF   = source.fTPCnclsF;     
853   fTPCsignalN = source.fTPCsignalN;   
854
855   fITSncls = source.fITSncls;       
856   fITSClusterMap = source.fITSClusterMap; 
857   fTRDncls   = source.fTRDncls;       
858   fTRDncls0  = source.fTRDncls0;      
859   fTRDntracklets  = source.fTRDntracklets; 
860   fVertexID = source.fVertexID;
861   return *this;
862 }
863
864
865
866 void AliESDtrack::Copy(TObject &obj) const {
867   
868   // this overwrites the virtual TOBject::Copy()
869   // to allow run time copying without casting
870   // in AliESDEvent
871
872   if(this==&obj)return;
873   AliESDtrack *robj = dynamic_cast<AliESDtrack*>(&obj);
874   if(!robj)return; // not an AliESDtrack
875   *robj = *this;
876
877 }
878
879
880
881 void AliESDtrack::AddCalibObject(TObject * object){
882   //
883   // add calib object to the list
884   //
885   if (!fFriendTrack) fFriendTrack  = new AliESDfriendTrack;
886   fFriendTrack->AddCalibObject(object);
887 }
888
889 TObject *  AliESDtrack::GetCalibObject(Int_t index){
890   //
891   // return calib objct at given position
892   //
893   if (!fFriendTrack) return 0;
894   return fFriendTrack->GetCalibObject(index);
895 }
896
897
898 Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
899   
900   // Fills the information of the TPC-only first reconstruction pass
901   // into the passed ESDtrack object. For consistency fTPCInner is also filled
902   // again
903
904
905
906   // For data produced before r26675
907   // RelateToVertexTPC was not properly called during reco
908   // so you'll have to call it again, before FillTPCOnlyTrack
909   //  Float_t p[2],cov[3];
910   // track->GetImpactParametersTPC(p,cov); 
911   // if(p[0]==0&&p[1]==0) // <- Default values
912   //  track->RelateToVertexTPC(esd->GetPrimaryVertexTPC(),esd->GetMagneticField(),kVeryBig);
913   
914
915   if(!fTPCInner)return kFALSE;
916
917   // fill the TPC track params to the global track parameters
918   track.Set(fTPCInner->GetX(),fTPCInner->GetAlpha(),fTPCInner->GetParameter(),fTPCInner->GetCovariance());
919   track.fD = fdTPC;
920   track.fZ = fzTPC;
921   track.fCdd = fCddTPC;
922   track.fCdz = fCdzTPC;
923   track.fCzz = fCzzTPC;
924
925   // copy the TPCinner parameters
926   if(track.fTPCInner) *track.fTPCInner = *fTPCInner;
927   else track.fTPCInner = new AliExternalTrackParam(*fTPCInner);
928   track.fdTPC   = fdTPC;
929   track.fzTPC   = fzTPC;
930   track.fCddTPC = fCddTPC;
931   track.fCdzTPC = fCdzTPC;
932   track.fCzzTPC = fCzzTPC;
933   track.fCchi2TPC = fCchi2TPC;
934
935
936   // copy all other TPC specific parameters
937
938   // replace label by TPC label
939   track.fLabel    = fTPCLabel;
940   track.fTPCLabel = fTPCLabel;
941
942   track.fTPCchi2 = fTPCchi2; 
943   track.fTPCsignal = fTPCsignal;
944   track.fTPCsignalS = fTPCsignalS;
945   for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
946
947   track.fTPCncls    = fTPCncls;     
948   track.fTPCnclsF   = fTPCnclsF;     
949   track.fTPCsignalN =  fTPCsignalN;
950
951   // PID 
952   for(int i=0;i<AliPID::kSPECIES;++i){
953     track.fTPCr[i] = fTPCr[i];
954     // combined PID is TPC only!
955     track.fR[i] = fTPCr[i];
956   }
957   track.fTPCClusterMap = fTPCClusterMap;
958   track.fTPCSharedMap = fTPCSharedMap;
959
960
961   // reset the flags
962   track.fFlags = kTPCin;
963   track.fID    = fID;
964
965   track.fFlags |= fFlags & kTPCpid; //copy the TPCpid status flag
966  
967   for (Int_t i=0;i<3;i++) track.fKinkIndexes[i] = fKinkIndexes[i];
968   
969   return kTRUE;
970     
971 }
972
973 //_______________________________________________________________________
974 void AliESDtrack::MakeMiniESDtrack(){
975   // Resets everything except
976   // fFlags: Reconstruction status flags 
977   // fLabel: Track label
978   // fID:  Unique ID of the track
979   // Impact parameter information
980   // fR[AliPID::kSPECIES]: combined "detector response probability"
981   // Running track parameters in the base class (AliExternalTrackParam)
982   
983   fTrackLength = 0;
984
985   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i] = 0;
986
987   // Reset track parameters constrained to the primary vertex
988   delete fCp;fCp = 0;
989
990   // Reset track parameters at the inner wall of TPC
991   delete fIp;fIp = 0;
992   delete fTPCInner;fTPCInner=0;
993   // Reset track parameters at the inner wall of the TRD
994   delete fOp;fOp = 0;
995   // Reset track parameters at the HMPID
996   delete fHMPIDp;fHMPIDp = 0;
997
998
999   // Reset ITS track related information
1000   fITSchi2 = 0;
1001   fITSncls = 0;       
1002   fITSClusterMap=0;
1003   fITSsignal = 0;     
1004   for (Int_t i=0;i<4;i++) fITSdEdxSamples[i] = 0.;
1005   for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0; 
1006   fITSLabel = 0;       
1007
1008   // Reset TPC related track information
1009   fTPCchi2 = 0;       
1010   fTPCncls = 0;       
1011   fTPCnclsF = 0;       
1012   fTPCClusterMap = 0;  
1013   fTPCSharedMap = 0;  
1014   fTPCsignal= 0;      
1015   fTPCsignalS= 0;      
1016   fTPCsignalN= 0;      
1017   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=0; 
1018   fTPCLabel=0;       
1019   for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
1020   for (Int_t i=0; i<3;i++)   fKinkIndexes[i] = 0;
1021   for (Int_t i=0; i<3;i++)   fV0Indexes[i] = 0;
1022
1023   // Reset TRD related track information
1024   fTRDchi2 = 0;        
1025   fTRDncls = 0;       
1026   fTRDncls0 = 0;       
1027   fTRDsignal = 0;      
1028   for (Int_t i=0;i<kTRDnPlanes;i++) {
1029     fTRDTimBin[i]  = 0;
1030   }
1031   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0; 
1032   fTRDLabel = 0;       
1033   fTRDQuality  = 0;
1034   fTRDntracklets = 0;
1035   if(fTRDnSlices)
1036     delete[] fTRDslices;
1037   fTRDslices=0x0;
1038   fTRDnSlices=0;
1039   fTRDBudget  = 0;
1040
1041   // Reset TOF related track information
1042   fTOFchi2 = 0;        
1043   fTOFindex = -1;       
1044   fTOFsignal = 0;      
1045   fTOFCalChannel = 0;
1046   fTOFsignalToT = 0;
1047   fTOFsignalRaw = 0;
1048   fTOFsignalDz = 0;
1049   fTOFsignalDx = 0;
1050   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
1051   for (Int_t i=0;i<3;i++) fTOFLabel[i] = 0;
1052   for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
1053
1054   // Reset HMPID related track information
1055   fHMPIDchi2 = 0;     
1056   fHMPIDqn = 0;     
1057   fHMPIDcluIdx = -1;     
1058   fHMPIDsignal = 0;     
1059   for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
1060   fHMPIDtrkTheta = 0;     
1061   fHMPIDtrkPhi = 0;      
1062   fHMPIDtrkX = 0;     
1063   fHMPIDtrkY = 0;      
1064   fHMPIDmipX = 0;
1065   fHMPIDmipY = 0;
1066   fEMCALindex = kEMCALNoMatch;
1067
1068   // reset global track chi2
1069   fGlobalChi2 = 0;
1070
1071   fVertexID = -2; // an orphan track
1072
1073   delete fFriendTrack; fFriendTrack = 0;
1074
1075 //_______________________________________________________________________
1076 Double_t AliESDtrack::GetMass() const {
1077   // Returns the mass of the most probable particle type
1078   Float_t max=0.;
1079   Int_t k=-1;
1080   for (Int_t i=0; i<AliPID::kSPECIES; i++) {
1081     if (fR[i]>max) {k=i; max=fR[i];}
1082   }
1083   if (k==0) { // dE/dx "crossing points" in the TPC
1084      Double_t p=GetP();
1085      if ((p>0.38)&&(p<0.48))
1086         if (fR[0]<fR[3]*10.) return AliPID::ParticleMass(AliPID::kKaon);
1087      if ((p>0.75)&&(p<0.85))
1088         if (fR[0]<fR[4]*10.) return AliPID::ParticleMass(AliPID::kProton);
1089      return 0.00051;
1090   }
1091   if (k==1) return AliPID::ParticleMass(AliPID::kMuon); 
1092   if (k==2||k==-1) return AliPID::ParticleMass(AliPID::kPion);
1093   if (k==3) return AliPID::ParticleMass(AliPID::kKaon);
1094   if (k==4) return AliPID::ParticleMass(AliPID::kProton);
1095   AliWarning("Undefined mass !");
1096   return AliPID::ParticleMass(AliPID::kPion);
1097 }
1098
1099 //______________________________________________________________________________
1100 Double_t AliESDtrack::E() const
1101 {
1102   // Returns the energy of the particle given its assumed mass.
1103   // Assumes the pion mass if the particle can't be identified properly.
1104   
1105   Double_t m = M();
1106   Double_t p = P();
1107   return TMath::Sqrt(p*p + m*m);
1108 }
1109
1110 //______________________________________________________________________________
1111 Double_t AliESDtrack::Y() const
1112 {
1113   // Returns the rapidity of a particle given its assumed mass.
1114   // Assumes the pion mass if the particle can't be identified properly.
1115   
1116   Double_t e = E();
1117   Double_t pz = Pz();
1118   if (e != TMath::Abs(pz)) { // energy was not equal to pz
1119     return 0.5*TMath::Log((e+pz)/(e-pz));
1120   } else { // energy was equal to pz
1121     return -999.;
1122   }
1123 }
1124
1125 //_______________________________________________________________________
1126 Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
1127   //
1128   // This function updates track's running parameters 
1129   //
1130   Int_t *index=0;
1131   Bool_t rc=kTRUE;
1132
1133   SetStatus(flags);
1134   fLabel=t->GetLabel();
1135
1136   if (t->IsStartedTimeIntegral()) {
1137     SetStatus(kTIME);
1138     Double_t times[10];t->GetIntegratedTimes(times); SetIntegratedTimes(times);
1139     SetIntegratedLength(t->GetIntegratedLength());
1140   }
1141
1142   Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1143   if (flags==kITSout) fFriendTrack->SetITSOut(*t);
1144   if (flags==kTPCout) fFriendTrack->SetTPCOut(*t);
1145   if (flags==kTRDrefit) fFriendTrack->SetTRDIn(*t);
1146   
1147   switch (flags) {
1148     
1149   case kITSin: case kITSout: case kITSrefit:
1150     fITSClusterMap=0;
1151     fITSncls=t->GetNumberOfClusters();
1152     index=fFriendTrack->GetITSindices(); 
1153     for (Int_t i=0;i<AliESDfriendTrack::kMaxITScluster;i++) {
1154         index[i]=t->GetClusterIndex(i);
1155         if (i<fITSncls) {
1156            Int_t l=(index[i] & 0xf0000000) >> 28;
1157            SETBIT(fITSClusterMap,l);                 
1158         }
1159     }
1160     fITSchi2=t->GetChi2();
1161     fITSsignal=t->GetPIDsignal();
1162     fITSLabel = t->GetLabel();
1163     // keep in fOp the parameters outside ITS for ITS stand-alone tracks 
1164     if (flags==kITSout) { 
1165       if (!fOp) fOp=new AliExternalTrackParam(*t);
1166       else 
1167         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1168     }   
1169     break;
1170     
1171   case kTPCin: case kTPCrefit:
1172     fTPCLabel = t->GetLabel();
1173     if (flags==kTPCin)  fTPCInner=new AliExternalTrackParam(*t);
1174     if (!fIp) fIp=new AliExternalTrackParam(*t);
1175     else 
1176       fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1177   case kTPCout:
1178     index=fFriendTrack->GetTPCindices(); 
1179     if (flags & kTPCout){
1180       if (!fOp) fOp=new AliExternalTrackParam(*t);
1181       else 
1182         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1183     }
1184     fTPCncls=t->GetNumberOfClusters();    
1185     fTPCchi2=t->GetChi2();
1186     
1187      {//prevrow must be declared in separate namespace, otherwise compiler cries:
1188       //"jump to case label crosses initialization of `Int_t prevrow'"
1189        Int_t prevrow = -1;
1190        //       for (Int_t i=0;i<fTPCncls;i++) 
1191        for (Int_t i=0;i<AliESDfriendTrack::kMaxTPCcluster;i++) 
1192         {
1193           index[i]=t->GetClusterIndex(i);
1194           Int_t idx = index[i];
1195
1196           if (idx<0) continue; 
1197
1198           // Piotr's Cluster Map for HBT  
1199           // ### please change accordingly if cluster array is changing 
1200           // to "New TPC Tracking" style (with gaps in array) 
1201           Int_t sect = (idx&0xff000000)>>24;
1202           Int_t row = (idx&0x00ff0000)>>16;
1203           if (sect > 18) row +=63; //if it is outer sector, add number of inner sectors
1204
1205           fTPCClusterMap.SetBitNumber(row,kTRUE);
1206
1207           //Fill the gap between previous row and this row with 0 bits
1208           //In case  ###  pleas change it as well - just set bit 0 in case there 
1209           //is no associated clusters for current "i"
1210           if (prevrow < 0) 
1211            {
1212              prevrow = row;//if previous bit was not assigned yet == this is the first one
1213            }
1214           else
1215            { //we don't know the order (inner to outer or reverse)
1216              //just to be save in case it is going to change
1217              Int_t n = 0, m = 0;
1218              if (prevrow < row)
1219               {
1220                 n = prevrow;
1221                 m = row;
1222               }
1223              else
1224               {
1225                 n = row;
1226                 m = prevrow;
1227               }
1228
1229              for (Int_t j = n+1; j < m; j++)
1230               {
1231                 fTPCClusterMap.SetBitNumber(j,kFALSE);
1232               }
1233              prevrow = row; 
1234            }
1235           // End Of Piotr's Cluster Map for HBT
1236         }
1237      }
1238     fTPCsignal=t->GetPIDsignal();
1239     break;
1240
1241   case kTRDin: case kTRDrefit:
1242     break;
1243   case kTRDout:
1244     index     = fFriendTrack->GetTRDindices();
1245     fTRDLabel = t->GetLabel(); 
1246     fTRDchi2  = t->GetChi2();
1247     fTRDncls  = t->GetNumberOfClusters();
1248     for (Int_t i=0;i<6;i++) index[i]=t->GetTrackletIndex(i);
1249     
1250     fTRDsignal=t->GetPIDsignal();
1251     break;
1252   case kTRDbackup:
1253     if (!fOp) fOp=new AliExternalTrackParam(*t);
1254     else 
1255       fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1256     fTRDncls0 = t->GetNumberOfClusters(); 
1257     break;
1258   case kTOFin: 
1259     break;
1260   case kTOFout: 
1261     break;
1262   case kTRDStop:
1263     break;
1264   case kHMPIDout:
1265   if (!fHMPIDp) fHMPIDp=new AliExternalTrackParam(*t);
1266     else 
1267       fHMPIDp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1268     break;
1269   default: 
1270     AliError("Wrong flag !");
1271     return kFALSE;
1272   }
1273
1274   return rc;
1275 }
1276
1277 //_______________________________________________________________________
1278 void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const {
1279   //---------------------------------------------------------------------
1280   // This function returns external representation of the track parameters
1281   //---------------------------------------------------------------------
1282   x=GetX();
1283   for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i];
1284 }
1285
1286 //_______________________________________________________________________
1287 void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const {
1288   //---------------------------------------------------------------------
1289   // This function returns external representation of the cov. matrix
1290   //---------------------------------------------------------------------
1291   for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i];
1292 }
1293
1294 //_______________________________________________________________________
1295 Bool_t AliESDtrack::GetConstrainedExternalParameters
1296                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1297   //---------------------------------------------------------------------
1298   // This function returns the constrained external track parameters
1299   //---------------------------------------------------------------------
1300   if (!fCp) return kFALSE;
1301   alpha=fCp->GetAlpha();
1302   x=fCp->GetX();
1303   for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i];
1304   return kTRUE;
1305 }
1306
1307 //_______________________________________________________________________
1308 Bool_t 
1309 AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const {
1310   //---------------------------------------------------------------------
1311   // This function returns the constrained external cov. matrix
1312   //---------------------------------------------------------------------
1313   if (!fCp) return kFALSE;
1314   for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i];
1315   return kTRUE;
1316 }
1317
1318 Bool_t
1319 AliESDtrack::GetInnerExternalParameters
1320                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1321   //---------------------------------------------------------------------
1322   // This function returns external representation of the track parameters 
1323   // at the inner layer of TPC
1324   //---------------------------------------------------------------------
1325   if (!fIp) return kFALSE;
1326   alpha=fIp->GetAlpha();
1327   x=fIp->GetX();
1328   for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i];
1329   return kTRUE;
1330 }
1331
1332 Bool_t 
1333 AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const {
1334  //---------------------------------------------------------------------
1335  // This function returns external representation of the cov. matrix 
1336  // at the inner layer of TPC
1337  //---------------------------------------------------------------------
1338   if (!fIp) return kFALSE;
1339   for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i];
1340   return kTRUE;
1341 }
1342
1343 void 
1344 AliESDtrack::SetOuterParam(const AliExternalTrackParam *p, ULong_t flags) {
1345   //
1346   // This is a direct setter for the outer track parameters
1347   //
1348   SetStatus(flags);
1349   if (fOp) delete fOp;
1350   fOp=new AliExternalTrackParam(*p);
1351 }
1352
1353 void 
1354 AliESDtrack::SetOuterHmpParam(const AliExternalTrackParam *p, ULong_t flags) {
1355   //
1356   // This is a direct setter for the outer track parameters
1357   //
1358   SetStatus(flags);
1359   if (fHMPIDp) delete fHMPIDp;
1360   fHMPIDp=new AliExternalTrackParam(*p);
1361 }
1362
1363 Bool_t 
1364 AliESDtrack::GetOuterExternalParameters
1365                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1366   //---------------------------------------------------------------------
1367   // This function returns external representation of the track parameters 
1368   // at the inner layer of TRD
1369   //---------------------------------------------------------------------
1370   if (!fOp) return kFALSE;
1371   alpha=fOp->GetAlpha();
1372   x=fOp->GetX();
1373   for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i];
1374   return kTRUE;
1375 }
1376
1377 Bool_t 
1378 AliESDtrack::GetOuterHmpExternalParameters
1379                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1380   //---------------------------------------------------------------------
1381   // This function returns external representation of the track parameters 
1382   // at the inner layer of TRD
1383   //---------------------------------------------------------------------
1384   if (!fHMPIDp) return kFALSE;
1385   alpha=fHMPIDp->GetAlpha();
1386   x=fHMPIDp->GetX();
1387   for (Int_t i=0; i<5; i++) p[i]=fHMPIDp->GetParameter()[i];
1388   return kTRUE;
1389 }
1390
1391 Bool_t 
1392 AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const {
1393  //---------------------------------------------------------------------
1394  // This function returns external representation of the cov. matrix 
1395  // at the inner layer of TRD
1396  //---------------------------------------------------------------------
1397   if (!fOp) return kFALSE;
1398   for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i];
1399   return kTRUE;
1400 }
1401
1402 Bool_t 
1403 AliESDtrack::GetOuterHmpExternalCovariance(Double_t cov[15]) const {
1404  //---------------------------------------------------------------------
1405  // This function returns external representation of the cov. matrix 
1406  // at the inner layer of TRD
1407  //---------------------------------------------------------------------
1408   if (!fHMPIDp) return kFALSE;
1409   for (Int_t i=0; i<15; i++) cov[i]=fHMPIDp->GetCovariance()[i];
1410   return kTRUE;
1411 }
1412
1413 Int_t AliESDtrack::GetNcls(Int_t idet) const
1414 {
1415   // Get number of clusters by subdetector index
1416   //
1417   Int_t ncls = 0;
1418   switch(idet){
1419   case 0:
1420     ncls = fITSncls;
1421     break;
1422   case 1:
1423     ncls = fTPCncls;
1424     break;
1425   case 2:
1426     ncls = fTRDncls;
1427     break;
1428   case 3:
1429     if (fTOFindex != -1)
1430       ncls = 1;
1431     break;
1432   case 4: //PHOS
1433     break;
1434   case 5: //HMPID
1435     if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1436       if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1437         ncls = 1;
1438       }
1439     }    
1440     break;
1441   default:
1442     break;
1443   }
1444   return ncls;
1445 }
1446
1447 Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
1448 {
1449   // Get cluster index array by subdetector index
1450   //
1451   Int_t ncls = 0;
1452   switch(idet){
1453   case 0:
1454     ncls = GetITSclusters(idx);
1455     break;
1456   case 1:
1457     ncls = GetTPCclusters(idx);
1458     break;
1459   case 2:
1460     ncls = GetTRDclusters(idx);
1461     break;
1462   case 3:
1463     if (fTOFindex != -1) {
1464       idx[0] = fTOFindex;
1465       ncls = 1;
1466     }
1467     break;
1468   case 4: //PHOS
1469     break;
1470   case 5:
1471     if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1472       if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1473         idx[0] = GetHMPIDcluIdx();
1474         ncls = 1;
1475       }
1476     }    
1477     break;
1478   case 6: //EMCAL
1479     break;
1480   default:
1481     break;
1482   }
1483   return ncls;
1484 }
1485
1486 //_______________________________________________________________________
1487 void AliESDtrack::GetIntegratedTimes(Double_t *times) const {
1488   // Returns the array with integrated times for each particle hypothesis
1489   for (Int_t i=0; i<AliPID::kSPECIES; i++) times[i]=fTrackTime[i];
1490 }
1491
1492 //_______________________________________________________________________
1493 void AliESDtrack::SetIntegratedTimes(const Double_t *times) {
1494   // Sets the array with integrated times for each particle hypotesis
1495   for (Int_t i=0; i<AliPID::kSPECIES; i++) fTrackTime[i]=times[i];
1496 }
1497
1498 //_______________________________________________________________________
1499 void AliESDtrack::SetITSpid(const Double_t *p) {
1500   // Sets values for the probability of each particle type (in ITS)
1501   SetPIDValues(fITSr,p,AliPID::kSPECIES);
1502   SetStatus(AliESDtrack::kITSpid);
1503 }
1504
1505 //_______________________________________________________________________
1506 void AliESDtrack::GetITSpid(Double_t *p) const {
1507   // Gets the probability of each particle type (in ITS)
1508   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fITSr[i];
1509 }
1510
1511 //_______________________________________________________________________
1512 Char_t AliESDtrack::GetITSclusters(Int_t *idx) const {
1513   //---------------------------------------------------------------------
1514   // This function returns indices of the assgined ITS clusters 
1515   //---------------------------------------------------------------------
1516   if (idx!=0) {
1517      Int_t *index=fFriendTrack->GetITSindices();
1518      for (Int_t i=0; i<AliESDfriendTrack::kMaxITScluster; i++) {
1519          if ( (i>=fITSncls) && (i<6) ) idx[i]=-1;
1520          else idx[i]=index[i];
1521      }
1522   }
1523   return fITSncls;
1524 }
1525
1526 //_______________________________________________________________________
1527 Bool_t AliESDtrack::GetITSModuleIndexInfo(Int_t ilayer,Int_t &idet,Int_t &status,
1528                                          Float_t &xloc,Float_t &zloc) const {
1529   //----------------------------------------------------------------------
1530   // This function encodes in the module number also the status of cluster association
1531   // "status" can have the following values: 
1532   // 1 "found" (cluster is associated), 
1533   // 2 "dead" (module is dead from OCDB), 
1534   // 3 "skipped" (module or layer forced to be skipped),
1535   // 4 "outinz" (track out of z acceptance), 
1536   // 5 "nocls" (no clusters in the road), 
1537   // 6 "norefit" (cluster rejected during refit), 
1538   // 7 "deadzspd" (holes in z in SPD)
1539   // Also given are the coordinates of the crossing point of track and module
1540   // (in the local module ref. system)
1541   // WARNING: THIS METHOD HAS TO BE SYNCHRONIZED WITH AliITStrackV2::GetModuleIndexInfo()!
1542   //----------------------------------------------------------------------
1543
1544   if(fITSModule[ilayer]==-1) {
1545     idet = -1;
1546     status=0;
1547     xloc=-99.; zloc=-99.;
1548     return kFALSE;
1549   }
1550
1551   Int_t module = fITSModule[ilayer];
1552
1553   idet = Int_t(module/1000000);
1554
1555   module -= idet*1000000;
1556
1557   status = Int_t(module/100000);
1558
1559   module -= status*100000;
1560
1561   Int_t signs = Int_t(module/10000);
1562
1563   module-=signs*10000;
1564
1565   Int_t xInt = Int_t(module/100);
1566   module -= xInt*100;
1567
1568   Int_t zInt = module;
1569
1570   if(signs==1) { xInt*=1; zInt*=1; }
1571   if(signs==2) { xInt*=1; zInt*=-1; }
1572   if(signs==3) { xInt*=-1; zInt*=1; }
1573   if(signs==4) { xInt*=-1; zInt*=-1; }
1574
1575   xloc = 0.1*(Float_t)xInt;
1576   zloc = 0.1*(Float_t)zInt;
1577
1578   if(status==4) idet = -1;
1579
1580   return kTRUE;
1581 }
1582
1583 //_______________________________________________________________________
1584 UShort_t AliESDtrack::GetTPCclusters(Int_t *idx) const {
1585   //---------------------------------------------------------------------
1586   // This function returns indices of the assgined ITS clusters 
1587   //---------------------------------------------------------------------
1588   if (idx!=0) {
1589     Int_t *index=fFriendTrack->GetTPCindices();
1590     for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=index[i];
1591   }
1592   return fTPCncls;
1593 }
1594
1595 Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
1596   //
1597   // GetDensity of the clusters on given region between row0 and row1
1598   // Dead zone effect takin into acoount
1599   //
1600   Int_t good  = 0;
1601   Int_t found = 0;
1602   //  
1603   Int_t *index=fFriendTrack->GetTPCindices();
1604   for (Int_t i=row0;i<=row1;i++){     
1605     Int_t idx = index[i];
1606     if (idx!=-1)  good++;             // track outside of dead zone
1607     if (idx>0)    found++;
1608   }
1609   Float_t density=0.5;
1610   if (good>(row1-row0)*0.5) density = Float_t(found)/Float_t(good);
1611   return density;
1612 }
1613
1614 //_______________________________________________________________________
1615 void AliESDtrack::SetTPCpid(const Double_t *p) {  
1616   // Sets values for the probability of each particle type (in TPC)
1617   SetPIDValues(fTPCr,p,AliPID::kSPECIES);
1618   SetStatus(AliESDtrack::kTPCpid);
1619 }
1620
1621 //_______________________________________________________________________
1622 void AliESDtrack::GetTPCpid(Double_t *p) const {
1623   // Gets the probability of each particle type (in TPC)
1624   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTPCr[i];
1625 }
1626
1627 //_______________________________________________________________________
1628 UChar_t AliESDtrack::GetTRDclusters(Int_t *idx) const {
1629   //---------------------------------------------------------------------
1630   // This function returns indices of the assgined TRD clusters 
1631   //---------------------------------------------------------------------
1632   if (idx!=0) {
1633      Int_t *index=fFriendTrack->GetTRDindices();
1634      for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=index[i];
1635   }
1636   return fTRDncls;
1637 }
1638
1639 //_______________________________________________________________________
1640 UChar_t AliESDtrack::GetTRDtracklets(Int_t *idx) const {
1641 //
1642 // This function returns the number of TRD tracklets used in tracking
1643 // and it fills the indices of these tracklets in the array "idx" as they 
1644 // are registered in the TRD track list. 
1645 // 
1646 // Caution :
1647 //   1. The idx array has to be allocated with a size >= AliESDtrack::kTRDnPlanes
1648 //   2. The idx array store not only the index but also the layer of the tracklet. 
1649 //      Therefore tracks with TRD gaps contain default values for indices [-1] 
1650
1651   if (!idx) return GetTRDntracklets();
1652   Int_t *index=fFriendTrack->GetTRDindices(), n(0);
1653   for (Int_t i=0; i<kTRDnPlanes; i++){ 
1654     if(index[i]>=0) n++;
1655     idx[i]=index[i];
1656   }
1657   return n;
1658 }
1659
1660 //_______________________________________________________________________
1661 void AliESDtrack::SetTRDpid(const Double_t *p) {  
1662   // Sets values for the probability of each particle type (in TRD)
1663   SetPIDValues(fTRDr,p,AliPID::kSPECIES);
1664   SetStatus(AliESDtrack::kTRDpid);
1665 }
1666
1667 //_______________________________________________________________________
1668 void AliESDtrack::GetTRDpid(Double_t *p) const {
1669   // Gets the probability of each particle type (in TRD)
1670   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTRDr[i];
1671 }
1672
1673 //_______________________________________________________________________
1674 void    AliESDtrack::SetTRDpid(Int_t iSpecies, Float_t p)
1675 {
1676   // Sets the probability of particle type iSpecies to p (in TRD)
1677   fTRDr[iSpecies] = p;
1678 }
1679
1680 Double_t AliESDtrack::GetTRDpid(Int_t iSpecies) const
1681 {
1682   // Returns the probability of particle type iSpecies (in TRD)
1683   return fTRDr[iSpecies];
1684 }
1685
1686 //____________________________________________________
1687 Int_t AliESDtrack::GetNumberOfTRDslices() const 
1688 {
1689   // built in backward compatibility
1690   Int_t idx = fTRDnSlices - (kTRDnPlanes<<1);
1691   return idx<18 ? fTRDnSlices/kTRDnPlanes : idx/kTRDnPlanes;
1692 }
1693
1694 //____________________________________________________
1695 Double_t AliESDtrack::GetTRDmomentum(Int_t plane, Double_t *sp) const
1696 {
1697 //Returns momentum estimation and optional its error (sp)
1698 // in TRD layer "plane".
1699
1700   if (!fTRDnSlices) {
1701     //    AliError("No TRD info allocated for this track !");
1702     return -1.;
1703   }
1704   if ((plane<0) || (plane>=kTRDnPlanes)) {
1705     AliError("Info for TRD plane not available!");
1706     return -1.;
1707   }
1708
1709   Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
1710   // Protection for backward compatibility
1711   if(idx<(GetNumberOfTRDslices()*kTRDnPlanes)) return -1.;
1712
1713   if(sp) (*sp) = fTRDslices[idx+kTRDnPlanes];
1714   return fTRDslices[idx];
1715 }
1716
1717 //____________________________________________________
1718 Double_t  AliESDtrack::GetTRDslice(Int_t plane, Int_t slice) const {
1719   //Gets the charge from the slice of the plane
1720
1721   if(!fTRDslices) {
1722     //AliError("No TRD slices allocated for this track !");
1723     return -1.;
1724   }
1725   if ((plane<0) || (plane>=kTRDnPlanes)) {
1726     AliError("Info for TRD plane not available !");
1727     return -1.;
1728   }
1729   Int_t ns=GetNumberOfTRDslices();
1730   if ((slice<-1) || (slice>=ns)) {
1731     //AliError("Wrong TRD slice !");  
1732     return -1.;
1733   }
1734
1735   if(slice>=0) return fTRDslices[plane*ns + slice];
1736
1737   // return average of the dEdx measurements
1738   Double_t q=0.; Double32_t *s = &fTRDslices[plane*ns];
1739   for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
1740   return q/ns;
1741 }
1742
1743 //____________________________________________________
1744 void  AliESDtrack::SetNumberOfTRDslices(Int_t n) {
1745   //Sets the number of slices used for PID 
1746   if (fTRDnSlices) return;
1747
1748   fTRDnSlices=n;
1749   fTRDslices=new Double32_t[fTRDnSlices];
1750   
1751   // set-up correctly the allocated memory
1752   memset(fTRDslices, 0, n*sizeof(Double32_t));
1753   for (Int_t i=GetNumberOfTRDslices(); i--;) fTRDslices[i]=-1.;
1754 }
1755
1756 //____________________________________________________
1757 void  AliESDtrack::SetTRDslice(Double_t q, Int_t plane, Int_t slice) {
1758   //Sets the charge q in the slice of the plane
1759   if(!fTRDslices) {
1760     AliError("No TRD slices allocated for this track !");
1761     return;
1762   }
1763   if ((plane<0) || (plane>=kTRDnPlanes)) {
1764     AliError("Info for TRD plane not allocated !");
1765     return;
1766   }
1767   Int_t ns=GetNumberOfTRDslices();
1768   if ((slice<0) || (slice>=ns)) {
1769     AliError("Wrong TRD slice !");
1770     return;
1771   }
1772   Int_t n=plane*ns + slice;
1773   fTRDslices[n]=q;
1774 }
1775
1776
1777 //____________________________________________________
1778 void AliESDtrack::SetTRDmomentum(Double_t p, Int_t plane, Double_t *sp)
1779 {
1780   if(!fTRDslices) {
1781     AliError("No TRD slices allocated for this track !");
1782     return;
1783   }
1784   if ((plane<0) || (plane>=kTRDnPlanes)) {
1785     AliError("Info for TRD plane not allocated !");
1786     return;
1787   }
1788
1789   Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
1790   // Protection for backward compatibility
1791   if(idx<GetNumberOfTRDslices()*kTRDnPlanes) return;
1792
1793   if(sp) fTRDslices[idx+kTRDnPlanes] = (*sp);
1794   fTRDslices[idx] = p;
1795 }
1796
1797
1798 //_______________________________________________________________________
1799 void AliESDtrack::SetTOFpid(const Double_t *p) {  
1800   // Sets the probability of each particle type (in TOF)
1801   SetPIDValues(fTOFr,p,AliPID::kSPECIES);
1802   SetStatus(AliESDtrack::kTOFpid);
1803 }
1804
1805 //_______________________________________________________________________
1806 void AliESDtrack::SetTOFLabel(const Int_t *p) {  
1807   // Sets  (in TOF)
1808   for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
1809 }
1810
1811 //_______________________________________________________________________
1812 void AliESDtrack::GetTOFpid(Double_t *p) const {
1813   // Gets probabilities of each particle type (in TOF)
1814   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTOFr[i];
1815 }
1816
1817 //_______________________________________________________________________
1818 void AliESDtrack::GetTOFLabel(Int_t *p) const {
1819   // Gets (in TOF)
1820   for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
1821 }
1822
1823 //_______________________________________________________________________
1824 void AliESDtrack::GetTOFInfo(Float_t *info) const {
1825   // Gets (in TOF)
1826   for (Int_t i=0; i<10; i++) info[i]=fTOFInfo[i];
1827 }
1828
1829 //_______________________________________________________________________
1830 void AliESDtrack::SetTOFInfo(Float_t*info) {
1831   // Gets (in TOF)
1832   for (Int_t i=0; i<10; i++) fTOFInfo[i]=info[i];
1833 }
1834
1835
1836
1837 //_______________________________________________________________________
1838 void AliESDtrack::SetHMPIDpid(const Double_t *p) {  
1839   // Sets the probability of each particle type (in HMPID)
1840   SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
1841   SetStatus(AliESDtrack::kHMPIDpid);
1842 }
1843
1844 //_______________________________________________________________________
1845 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
1846   // Gets probabilities of each particle type (in HMPID)
1847   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fHMPIDr[i];
1848 }
1849
1850
1851
1852 //_______________________________________________________________________
1853 void AliESDtrack::SetESDpid(const Double_t *p) {  
1854   // Sets the probability of each particle type for the ESD track
1855   SetPIDValues(fR,p,AliPID::kSPECIES);
1856   SetStatus(AliESDtrack::kESDpid);
1857 }
1858
1859 //_______________________________________________________________________
1860 void AliESDtrack::GetESDpid(Double_t *p) const {
1861   // Gets probability of each particle type for the ESD track
1862   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fR[i];
1863 }
1864
1865 //_______________________________________________________________________
1866 Bool_t AliESDtrack::RelateToVertexTPC(const AliESDVertex *vtx, 
1867 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
1868   //
1869   // Try to relate the TPC-only track parameters to the vertex "vtx", 
1870   // if the (rough) transverse impact parameter is not bigger then "maxd". 
1871   //            Magnetic field is "b" (kG).
1872   //
1873   // a) The TPC-only paramters are extapolated to the DCA to the vertex.
1874   // b) The impact parameters and their covariance matrix are calculated.
1875   // c) An attempt to constrain the TPC-only params to the vertex is done.
1876   //    The constrained params are returned via "cParam".
1877   //
1878   // In the case of success, the returned value is kTRUE
1879   // otherwise, it's kFALSE)
1880   // 
1881
1882   if (!fTPCInner) return kFALSE;
1883   if (!vtx) return kFALSE;
1884
1885   Double_t dz[2],cov[3];
1886   if (!fTPCInner->PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
1887
1888   fdTPC = dz[0];
1889   fzTPC = dz[1];  
1890   fCddTPC = cov[0];
1891   fCdzTPC = cov[1];
1892   fCzzTPC = cov[2];
1893   
1894   Double_t covar[6]; vtx->GetCovMatrix(covar);
1895   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
1896   Double_t c[3]={covar[2],0.,covar[5]};
1897
1898   Double_t chi2=GetPredictedChi2(p,c);
1899   if (chi2>kVeryBig) return kFALSE;
1900
1901   fCchi2TPC=chi2;
1902
1903   if (!cParam) return kTRUE;
1904
1905   *cParam = *fTPCInner;
1906   if (!cParam->Update(p,c)) return kFALSE;
1907
1908   return kTRUE;
1909 }
1910
1911 //_______________________________________________________________________
1912 Bool_t AliESDtrack::RelateToVertexTPCBxByBz(const AliESDVertex *vtx, 
1913 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
1914   //
1915   // Try to relate the TPC-only track parameters to the vertex "vtx", 
1916   // if the (rough) transverse impact parameter is not bigger then "maxd". 
1917   //
1918   // All three components of the magnetic field ,"b[3]" (kG), 
1919   // are taken into account.
1920   //
1921   // a) The TPC-only paramters are extapolated to the DCA to the vertex.
1922   // b) The impact parameters and their covariance matrix are calculated.
1923   // c) An attempt to constrain the TPC-only params to the vertex is done.
1924   //    The constrained params are returned via "cParam".
1925   //
1926   // In the case of success, the returned value is kTRUE
1927   // otherwise, it's kFALSE)
1928   // 
1929
1930   if (!fTPCInner) return kFALSE;
1931   if (!vtx) return kFALSE;
1932
1933   Double_t dz[2],cov[3];
1934   if (!fTPCInner->PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
1935
1936   fdTPC = dz[0];
1937   fzTPC = dz[1];  
1938   fCddTPC = cov[0];
1939   fCdzTPC = cov[1];
1940   fCzzTPC = cov[2];
1941   
1942   Double_t covar[6]; vtx->GetCovMatrix(covar);
1943   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
1944   Double_t c[3]={covar[2],0.,covar[5]};
1945
1946   Double_t chi2=GetPredictedChi2(p,c);
1947   if (chi2>kVeryBig) return kFALSE;
1948
1949   fCchi2TPC=chi2;
1950
1951   if (!cParam) return kTRUE;
1952
1953   *cParam = *fTPCInner;
1954   if (!cParam->Update(p,c)) return kFALSE;
1955
1956   return kTRUE;
1957 }
1958
1959 //_______________________________________________________________________
1960 Bool_t AliESDtrack::RelateToVertex(const AliESDVertex *vtx, 
1961 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
1962   //
1963   // Try to relate this track to the vertex "vtx", 
1964   // if the (rough) transverse impact parameter is not bigger then "maxd". 
1965   //            Magnetic field is "b" (kG).
1966   //
1967   // a) The track gets extapolated to the DCA to the vertex.
1968   // b) The impact parameters and their covariance matrix are calculated.
1969   // c) An attempt to constrain this track to the vertex is done.
1970   //    The constrained params are returned via "cParam".
1971   //
1972   // In the case of success, the returned value is kTRUE
1973   // (otherwise, it's kFALSE)
1974   //  
1975
1976   if (!vtx) return kFALSE;
1977
1978   Double_t dz[2],cov[3];
1979   if (!PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
1980
1981   fD = dz[0];
1982   fZ = dz[1];  
1983   fCdd = cov[0];
1984   fCdz = cov[1];
1985   fCzz = cov[2];
1986   
1987   Double_t covar[6]; vtx->GetCovMatrix(covar);
1988   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
1989   Double_t c[3]={covar[2],0.,covar[5]};
1990
1991   Double_t chi2=GetPredictedChi2(p,c);
1992   if (chi2>kVeryBig) return kFALSE;
1993
1994   fCchi2=chi2;
1995
1996
1997   //--- Could now these lines be removed ? ---
1998   delete fCp;
1999   fCp=new AliExternalTrackParam(*this);  
2000
2001   if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2002   //----------------------------------------
2003
2004   fVertexID = vtx->GetID();
2005
2006   if (!cParam) return kTRUE;
2007
2008   *cParam = *this;
2009   if (!cParam->Update(p,c)) return kFALSE; 
2010
2011   return kTRUE;
2012 }
2013
2014 //_______________________________________________________________________
2015 Bool_t AliESDtrack::RelateToVertexBxByBz(const AliESDVertex *vtx, 
2016 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2017   //
2018   // Try to relate this track to the vertex "vtx", 
2019   // if the (rough) transverse impact parameter is not bigger then "maxd". 
2020   //            Magnetic field is "b" (kG).
2021   //
2022   // a) The track gets extapolated to the DCA to the vertex.
2023   // b) The impact parameters and their covariance matrix are calculated.
2024   // c) An attempt to constrain this track to the vertex is done.
2025   //    The constrained params are returned via "cParam".
2026   //
2027   // In the case of success, the returned value is kTRUE
2028   // (otherwise, it's kFALSE)
2029   //  
2030
2031   if (!vtx) return kFALSE;
2032
2033   Double_t dz[2],cov[3];
2034   if (!PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2035
2036   fD = dz[0];
2037   fZ = dz[1];  
2038   fCdd = cov[0];
2039   fCdz = cov[1];
2040   fCzz = cov[2];
2041   
2042   Double_t covar[6]; vtx->GetCovMatrix(covar);
2043   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2044   Double_t c[3]={covar[2],0.,covar[5]};
2045
2046   Double_t chi2=GetPredictedChi2(p,c);
2047   if (chi2>kVeryBig) return kFALSE;
2048
2049   fCchi2=chi2;
2050
2051
2052   //--- Could now these lines be removed ? ---
2053   delete fCp;
2054   fCp=new AliExternalTrackParam(*this);  
2055
2056   if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2057   //----------------------------------------
2058
2059   fVertexID = vtx->GetID();
2060
2061   if (!cParam) return kTRUE;
2062
2063   *cParam = *this;
2064   if (!cParam->Update(p,c)) return kFALSE; 
2065
2066   return kTRUE;
2067 }
2068
2069 //_______________________________________________________________________
2070 void AliESDtrack::Print(Option_t *) const {
2071   // Prints info on the track
2072   AliExternalTrackParam::Print();
2073   printf("ESD track info\n") ; 
2074   Double_t p[AliPID::kSPECIESN] ; 
2075   Int_t index = 0 ; 
2076   if( IsOn(kITSpid) ){
2077     printf("From ITS: ") ; 
2078     GetITSpid(p) ; 
2079     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2080       printf("%f, ", p[index]) ;
2081     printf("\n           signal = %f\n", GetITSsignal()) ;
2082   } 
2083   if( IsOn(kTPCpid) ){
2084     printf("From TPC: ") ; 
2085     GetTPCpid(p) ; 
2086     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2087       printf("%f, ", p[index]) ;
2088     printf("\n           signal = %f\n", GetTPCsignal()) ;
2089   }
2090   if( IsOn(kTRDpid) ){
2091     printf("From TRD: ") ; 
2092     GetTRDpid(p) ; 
2093     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2094       printf("%f, ", p[index]) ;
2095       printf("\n           signal = %f\n", GetTRDsignal()) ;
2096   }
2097   if( IsOn(kTOFpid) ){
2098     printf("From TOF: ") ; 
2099     GetTOFpid(p) ; 
2100     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2101       printf("%f, ", p[index]) ;
2102     printf("\n           signal = %f\n", GetTOFsignal()) ;
2103   }
2104   if( IsOn(kHMPIDpid) ){
2105     printf("From HMPID: ") ; 
2106     GetHMPIDpid(p) ; 
2107     for(index = 0 ; index < AliPID::kSPECIES; index++) 
2108       printf("%f, ", p[index]) ;
2109     printf("\n           signal = %f\n", GetHMPIDsignal()) ;
2110   }
2111
2112
2113
2114 //
2115 // Draw functionality
2116 // Origin: Marian Ivanov, Marian.Ivanov@cern.ch
2117 //
2118 void AliESDtrack::FillPolymarker(TPolyMarker3D *pol, Float_t magF, Float_t minR, Float_t maxR, Float_t stepR){
2119   //
2120   // Fill points in the polymarker
2121   //
2122   TObjArray arrayRef;
2123   arrayRef.AddLast(new AliExternalTrackParam(*this));
2124   if (fIp) arrayRef.AddLast(new AliExternalTrackParam(*fIp));
2125   if (fOp) arrayRef.AddLast(new AliExternalTrackParam(*fOp));
2126   if (fHMPIDp) arrayRef.AddLast(new AliExternalTrackParam(*fHMPIDp));
2127   //
2128   Double_t mpos[3]={0,0,0};
2129   Int_t entries=arrayRef.GetEntries();
2130   for (Int_t i=0;i<entries;i++){
2131     Double_t pos[3];
2132     ((AliExternalTrackParam*)arrayRef.At(i))->GetXYZ(pos);
2133     mpos[0]+=pos[0]/entries;
2134     mpos[1]+=pos[1]/entries;
2135     mpos[2]+=pos[2]/entries;    
2136   }
2137   // Rotate to the mean position
2138   //
2139   Float_t fi= TMath::ATan2(mpos[1],mpos[0]);
2140   for (Int_t i=0;i<entries;i++){
2141     Bool_t res = ((AliExternalTrackParam*)arrayRef.At(i))->Rotate(fi);
2142     if (!res) delete arrayRef.RemoveAt(i);
2143   }
2144   Int_t counter=0;
2145   for (Double_t r=minR; r<maxR; r+=stepR){
2146     Double_t sweight=0;
2147     Double_t mlpos[3]={0,0,0};
2148     for (Int_t i=0;i<entries;i++){
2149       Double_t point[3]={0,0,0};
2150       AliExternalTrackParam *param = ((AliExternalTrackParam*)arrayRef.At(i));
2151       if (!param) continue;
2152       if (param->GetXYZAt(r,magF,point)){
2153         Double_t weight = 1./(10.+(r-param->GetX())*(r-param->GetX()));
2154         sweight+=weight;
2155         mlpos[0]+=point[0]*weight;
2156         mlpos[1]+=point[1]*weight;
2157         mlpos[2]+=point[2]*weight;
2158       }
2159     }
2160     if (sweight>0){
2161       mlpos[0]/=sweight;
2162       mlpos[1]/=sweight;
2163       mlpos[2]/=sweight;      
2164       pol->SetPoint(counter,mlpos[0],mlpos[1], mlpos[2]);
2165       printf("xyz\t%f\t%f\t%f\n",mlpos[0], mlpos[1],mlpos[2]);
2166       counter++;
2167     }
2168   }
2169 }
2170
2171 //_______________________________________________________________________
2172 void AliESDtrack::SetITSdEdxSamples(const Double_t s[4]) {
2173   //
2174   // Store the dE/dx samples measured by the two SSD and two SDD layers.
2175   // These samples are corrected for the track segment length. 
2176   //
2177   for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
2178 }
2179
2180 //_______________________________________________________________________
2181 void AliESDtrack::GetITSdEdxSamples(Double_t *s) const {
2182   //
2183   // Get the dE/dx samples measured by the two SSD and two SDD layers.  
2184   // These samples are corrected for the track segment length.
2185   //
2186   for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
2187 }