]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliESDtrack.cxx
Comments explaining the meaning of the different track parameters stored in the ESD...
[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
119 #include "AliESDVertex.h"
120 #include "AliESDtrack.h"
121 #include "AliKalmanTrack.h"
122 #include "AliLog.h"
123 #include "AliTrackPointArray.h"
124 #include "TPolyMarker3D.h"
125
126 ClassImp(AliESDtrack)
127
128 void SetPIDValues(Double_t * dest, const Double_t * src, Int_t n) {
129   // This function copies "n" PID weights from "scr" to "dest"
130   // and normalizes their sum to 1 thus producing conditional probabilities.
131   // The negative weights are set to 0.
132   // In case all the weights are non-positive they are replaced by
133   // uniform probabilities
134
135   if (n<=0) return;
136
137   Float_t uniform = 1./(Float_t)n;
138
139   Float_t sum = 0;
140   for (Int_t i=0; i<n; i++) 
141     if (src[i]>=0) {
142       sum+=src[i];
143       dest[i] = src[i];
144     }
145     else {
146       dest[i] = 0;
147     }
148
149   if(sum>0)
150     for (Int_t i=0; i<n; i++) dest[i] /= sum;
151   else
152     for (Int_t i=0; i<n; i++) dest[i] = uniform;
153 }
154
155 //_______________________________________________________________________
156 AliESDtrack::AliESDtrack() : 
157   AliExternalTrackParam(),
158   fCp(0),
159   fIp(0),
160   fTPCInner(0),
161   fOp(0),
162   fFriendTrack(new AliESDfriendTrack()),
163   fTPCClusterMap(159),//number of padrows
164   fTPCSharedMap(159),//number of padrows
165   fFlags(0),
166   fID(0),
167   fLabel(0),
168   fITSLabel(0),
169   fTPCLabel(0),
170   fTRDLabel(0),
171   fTOFCalChannel(0),
172   fTOFindex(-1),
173   fHMPIDqn(0),
174   fHMPIDcluIdx(0),
175   fEMCALindex(kEMCALNoMatch),
176   fHMPIDtrkTheta(0),
177   fHMPIDtrkPhi(0),
178   fHMPIDsignal(0),
179   fTrackLength(0),
180   fdTPC(0),fzTPC(0),
181   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
182   fD(0),fZ(0),
183   fCdd(0),fCdz(0),fCzz(0),
184   fCchi2(0),
185   fITSchi2(0),
186   fTPCchi2(0),
187   fTRDchi2(0),
188   fTOFchi2(0),
189   fHMPIDchi2(0),
190   fITSsignal(0),
191   fTPCsignal(0),
192   fTPCsignalS(0),
193   fTRDsignal(0),
194   fTRDQuality(0),
195   fTRDBudget(0),
196   fTOFsignal(0),
197   fTOFsignalToT(0),
198   fTOFsignalRaw(0),
199   fTOFsignalDz(0),
200   fHMPIDtrkX(0),
201   fHMPIDtrkY(0),
202   fHMPIDmipX(0),
203   fHMPIDmipY(0),
204   fTPCncls(0),
205   fTPCnclsF(0),
206   fTPCsignalN(0),
207   fITSncls(0),
208   fITSClusterMap(0),
209   fTRDncls(0),
210   fTRDncls0(0),
211   fTRDpidQuality(0),
212   fTRDnSlices(0),
213   fTRDslices(0x0)
214   
215 {
216   //
217   // The default ESD constructor 
218   //
219   Int_t i;
220   for (i=0; i<AliPID::kSPECIES; i++) {
221     fTrackTime[i]=0.;
222     fR[i]=0.;
223     fITSr[i]=0.;
224     fTPCr[i]=0.;
225     fTRDr[i]=0.;
226     fTOFr[i]=0.;
227     fHMPIDr[i]=0.;
228   }
229   
230   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
231   for (i=0; i<3; i++)   { fV0Indexes[i]=0;}
232   for (i=0;i<kTRDnPlanes;i++) {
233     fTRDTimBin[i]=0;
234   }
235   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
236   for (i=0;i<3;i++) {fTOFLabel[i]=0;}
237   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
238   for (i=0;i<12;i++) {fITSModule[i]=-1;}
239 }
240
241 //_______________________________________________________________________
242 AliESDtrack::AliESDtrack(const AliESDtrack& track):
243   AliExternalTrackParam(track),
244   fCp(0),
245   fIp(0),
246   fTPCInner(0),
247   fOp(0),
248   fFriendTrack(0),
249   fTPCClusterMap(track.fTPCClusterMap),
250   fTPCSharedMap(track.fTPCSharedMap),
251   fFlags(track.fFlags),
252   fID(track.fID),
253   fLabel(track.fLabel),
254   fITSLabel(track.fITSLabel),
255   fTPCLabel(track.fTPCLabel),
256   fTRDLabel(track.fTRDLabel),
257   fTOFCalChannel(track.fTOFCalChannel),
258   fTOFindex(track.fTOFindex),
259   fHMPIDqn(track.fHMPIDqn),
260   fHMPIDcluIdx(track.fHMPIDcluIdx),
261   fEMCALindex(track.fEMCALindex),
262   fHMPIDtrkTheta(track.fHMPIDtrkTheta),
263   fHMPIDtrkPhi(track.fHMPIDtrkPhi),
264   fHMPIDsignal(track.fHMPIDsignal),
265   fTrackLength(track.fTrackLength),
266   fdTPC(track.fdTPC),fzTPC(track.fzTPC),
267   fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
268   fD(track.fD),fZ(track.fZ),
269   fCdd(track.fCdd),fCdz(track.fCdz),fCzz(track.fCzz),
270   fCchi2(track.fCchi2),
271   fITSchi2(track.fITSchi2),
272   fTPCchi2(track.fTPCchi2),
273   fTRDchi2(track.fTRDchi2),
274   fTOFchi2(track.fTOFchi2),
275   fHMPIDchi2(track.fHMPIDchi2),
276   fITSsignal(track.fITSsignal),
277   fTPCsignal(track.fTPCsignal),
278   fTPCsignalS(track.fTPCsignalS),
279   fTRDsignal(track.fTRDsignal),
280   fTRDQuality(track.fTRDQuality),
281   fTRDBudget(track.fTRDBudget),
282   fTOFsignal(track.fTOFsignal),
283   fTOFsignalToT(track.fTOFsignalToT),
284   fTOFsignalRaw(track.fTOFsignalRaw),
285   fTOFsignalDz(track.fTOFsignalDz),
286   fHMPIDtrkX(track.fHMPIDtrkX),
287   fHMPIDtrkY(track.fHMPIDtrkY),
288   fHMPIDmipX(track.fHMPIDmipX),
289   fHMPIDmipY(track.fHMPIDmipY),
290   fTPCncls(track.fTPCncls),
291   fTPCnclsF(track.fTPCnclsF),
292   fTPCsignalN(track.fTPCsignalN),
293   fITSncls(track.fITSncls),
294   fITSClusterMap(track.fITSClusterMap),
295   fTRDncls(track.fTRDncls),
296   fTRDncls0(track.fTRDncls0),
297   fTRDpidQuality(track.fTRDpidQuality),
298   fTRDnSlices(track.fTRDnSlices),
299   fTRDslices(0x0)
300 {
301   //
302   //copy constructor
303   //
304   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i]=track.fTrackTime[i];
305   for (Int_t i=0;i<AliPID::kSPECIES;i++)  fR[i]=track.fR[i];
306   //
307   for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=track.fITSr[i]; 
308   //
309   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=track.fTPCr[i]; 
310   for (Int_t i=0;i<4;i++) {fTPCPoints[i]=track.fTPCPoints[i];}
311   for (Int_t i=0; i<3;i++)   { fKinkIndexes[i]=track.fKinkIndexes[i];}
312   for (Int_t i=0; i<3;i++)   { fV0Indexes[i]=track.fV0Indexes[i];}
313   //
314   for (Int_t i=0;i<kTRDnPlanes;i++) {
315     fTRDTimBin[i]=track.fTRDTimBin[i];
316   }
317
318   if (fTRDnSlices) {
319     fTRDslices=new Double32_t[fTRDnSlices];
320     for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=track.fTRDslices[i];
321   }
322
323   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i]=track.fTRDr[i]; 
324   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i]=track.fTOFr[i];
325   for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
326   for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
327   for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
328   for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i]=track.fHMPIDr[i];
329
330   if (track.fCp) fCp=new AliExternalTrackParam(*track.fCp);
331   if (track.fIp) fIp=new AliExternalTrackParam(*track.fIp);
332   if (track.fTPCInner) fTPCInner=new AliExternalTrackParam(*track.fTPCInner);
333   if (track.fOp) fOp=new AliExternalTrackParam(*track.fOp);
334
335   if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
336 }
337
338 //_______________________________________________________________________
339 AliESDtrack::AliESDtrack(TParticle * part) : 
340   AliExternalTrackParam(),
341   fCp(0),
342   fIp(0),
343   fTPCInner(0),
344   fOp(0),
345   fFriendTrack(0),
346   fTPCClusterMap(159),//number of padrows
347   fTPCSharedMap(159),//number of padrows
348   fFlags(0),
349   fID(0),
350   fLabel(0),
351   fITSLabel(0),
352   fTPCLabel(0),
353   fTRDLabel(0),
354   fTOFCalChannel(0),
355   fTOFindex(-1),
356   fHMPIDqn(0),
357   fHMPIDcluIdx(0),
358   fEMCALindex(kEMCALNoMatch),
359   fHMPIDtrkTheta(0),
360   fHMPIDtrkPhi(0),
361   fHMPIDsignal(0),
362   fTrackLength(0),
363   fdTPC(0),fzTPC(0),
364   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
365   fD(0),fZ(0),
366   fCdd(0),fCdz(0),fCzz(0),
367   fCchi2(0),
368   fITSchi2(0),
369   fTPCchi2(0),
370   fTRDchi2(0),
371   fTOFchi2(0),
372   fHMPIDchi2(0),
373   fITSsignal(0),
374   fTPCsignal(0),
375   fTPCsignalS(0),
376   fTRDsignal(0),
377   fTRDQuality(0),
378   fTRDBudget(0),
379   fTOFsignal(0),
380   fTOFsignalToT(0),
381   fTOFsignalRaw(0),
382   fTOFsignalDz(0),
383   fHMPIDtrkX(0),
384   fHMPIDtrkY(0),
385   fHMPIDmipX(0),
386   fHMPIDmipY(0),
387   fTPCncls(0),
388   fTPCnclsF(0),
389   fTPCsignalN(0),
390   fITSncls(0),
391   fITSClusterMap(0),
392   fTRDncls(0),
393   fTRDncls0(0),
394   fTRDpidQuality(0),
395   fTRDnSlices(0),
396   fTRDslices(0x0)
397 {
398   //
399   // ESD track from TParticle
400   //
401
402   // Reset all the arrays
403   Int_t i;
404   for (i=0; i<AliPID::kSPECIES; i++) {
405     fTrackTime[i]=0.;
406     fR[i]=0.;
407     fITSr[i]=0.;
408     fTPCr[i]=0.;
409     fTRDr[i]=0.;
410     fTOFr[i]=0.;
411     fHMPIDr[i]=0.;
412   }
413   
414   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
415   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
416   for (i=0;i<kTRDnPlanes;i++) {
417     fTRDTimBin[i]=0;
418   }
419   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
420   for (i=0;i<3;i++) {fTOFLabel[i]=0;}
421   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
422   for (i=0;i<12;i++) {fITSModule[i]=-1;}
423
424   // Calculate the AliExternalTrackParam content
425
426   Double_t xref;
427   Double_t alpha;
428   Double_t param[5];
429   Double_t covar[15];
430
431   // Calculate alpha: the rotation angle of the corresponding local system (TPC sector)
432   alpha = part->Phi()*180./TMath::Pi();
433   if (alpha<0) alpha+= 360.;
434   if (alpha>360) alpha -= 360.;
435
436   Int_t sector = (Int_t)(alpha/20.);
437   alpha = 10. + 20.*sector;
438   alpha /= 180;
439   alpha *= TMath::Pi();
440
441   // Covariance matrix: no errors, the parameters are exact
442   for (i=0; i<15; i++) covar[i]=0.;
443
444   // Get the vertex of origin and the momentum
445   TVector3 ver(part->Vx(),part->Vy(),part->Vz());
446   TVector3 mom(part->Px(),part->Py(),part->Pz());
447
448   // Rotate to the local coordinate system (TPC sector)
449   ver.RotateZ(-alpha);
450   mom.RotateZ(-alpha);
451
452   // X of the referense plane
453   xref = ver.X();
454
455   Int_t pdgCode = part->GetPdgCode();
456
457   Double_t charge = 
458     TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge();
459
460   param[0] = ver.Y();
461   param[1] = ver.Z();
462   param[2] = TMath::Sin(mom.Phi());
463   param[3] = mom.Pz()/mom.Pt();
464   param[4] = TMath::Sign(1/mom.Pt(),charge);
465
466   // Set AliExternalTrackParam
467   Set(xref, alpha, param, covar);
468
469   // Set the PID
470   Int_t indexPID = 99;
471
472   switch (TMath::Abs(pdgCode)) {
473
474   case  11: // electron
475     indexPID = 0;
476     break;
477
478   case 13: // muon
479     indexPID = 1;
480     break;
481
482   case 211: // pion
483     indexPID = 2;
484     break;
485
486   case 321: // kaon
487     indexPID = 3;
488     break;
489
490   case 2212: // proton
491     indexPID = 4;
492     break;
493
494   default:
495     break;
496   }
497
498   // If the particle is not e,mu,pi,K or p the PID probabilities are set to 0
499   if (indexPID < AliPID::kSPECIES) {
500     fR[indexPID]=1.;
501     fITSr[indexPID]=1.;
502     fTPCr[indexPID]=1.;
503     fTRDr[indexPID]=1.;
504     fTOFr[indexPID]=1.;
505     fHMPIDr[indexPID]=1.;
506
507   }
508   // AliESD track label
509   SetLabel(part->GetUniqueID());
510
511 }
512
513 //_______________________________________________________________________
514 AliESDtrack::~AliESDtrack(){ 
515   //
516   // This is destructor according Coding Conventrions 
517   //
518   //printf("Delete track\n");
519   delete fIp; 
520   delete fTPCInner; 
521   delete fOp;
522   delete fCp; 
523   delete fFriendTrack;
524   if(fTRDnSlices)
525     delete[] fTRDslices;
526 }
527
528 AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
529   
530
531   if(&source == this) return *this;
532   AliExternalTrackParam::operator=(source);
533
534   
535   if(source.fCp){
536     // we have the trackparam: assign or copy construct
537     if(fCp)*fCp = *source.fCp;
538     else fCp = new AliExternalTrackParam(*source.fCp);
539   }
540   else{
541     // no track param delete the old one
542     if(fCp)delete fCp;
543     fCp = 0;
544   }
545
546   if(source.fIp){
547     // we have the trackparam: assign or copy construct
548     if(fIp)*fIp = *source.fIp;
549     else fIp = new AliExternalTrackParam(*source.fIp);
550   }
551   else{
552     // no track param delete the old one
553     if(fIp)delete fIp;
554     fIp = 0;
555   }
556
557
558   if(source.fTPCInner){
559     // we have the trackparam: assign or copy construct
560     if(fTPCInner) *fTPCInner = *source.fTPCInner;
561     else fTPCInner = new AliExternalTrackParam(*source.fTPCInner);
562   }
563   else{
564     // no track param delete the old one
565     if(fTPCInner)delete fTPCInner;
566     fTPCInner = 0;
567   }
568
569
570   if(source.fOp){
571     // we have the trackparam: assign or copy construct
572     if(fOp) *fOp = *source.fOp;
573     else fOp = new AliExternalTrackParam(*source.fOp);
574   }
575   else{
576     // no track param delete the old one
577     if(fOp)delete fOp;
578     fOp = 0;
579   }
580
581   // copy also the friend track 
582   // use copy constructor
583   if(source.fFriendTrack){
584     // we have the trackparam: assign or copy construct
585     delete fFriendTrack; fFriendTrack=new AliESDfriendTrack(*source.fFriendTrack);
586   }
587   else{
588     // no track param delete the old one
589     delete fFriendTrack; fFriendTrack= 0;
590   }
591
592   fTPCClusterMap = source.fTPCClusterMap; 
593   fTPCSharedMap  = source.fTPCSharedMap;  
594   // the simple stuff
595   fFlags    = source.fFlags; 
596   fID       = source.fID;             
597   fLabel    = source.fLabel;
598   fITSLabel = source.fITSLabel;
599   for(int i = 0; i< 12;++i){
600     fITSModule[i] = source.fITSModule[i];
601   }
602   fTPCLabel = source.fTPCLabel; 
603   fTRDLabel = source.fTRDLabel;
604   for(int i = 0; i< 3;++i){
605     fTOFLabel[i] = source.fTOFLabel[i];    
606   }
607   fTOFCalChannel = source.fTOFCalChannel;
608   fTOFindex      = source.fTOFindex;
609   fHMPIDqn       = source.fHMPIDqn;
610   fHMPIDcluIdx   = source.fHMPIDcluIdx; 
611   fEMCALindex    = source.fEMCALindex;
612
613   for(int i = 0; i< 3;++i){
614     fKinkIndexes[i] = source.fKinkIndexes[i]; 
615     fV0Indexes[i]   = source.fV0Indexes[i]; 
616   }
617
618   for(int i = 0; i< AliPID::kSPECIES;++i){
619     fR[i]     = source.fR[i];
620     fITSr[i]  = source.fITSr[i];
621     fTPCr[i]  = source.fTPCr[i];
622     fTRDr[i]  = source.fTRDr[i];
623     fTOFr[i]  = source.fTOFr[i];
624     fHMPIDr[i] = source.fHMPIDr[i];
625     fTrackTime[i] = source.fTrackTime[i];  
626   }
627
628   fHMPIDtrkTheta = source.fHMPIDtrkTheta;
629   fHMPIDtrkPhi   = source.fHMPIDtrkPhi;
630   fHMPIDsignal   = source.fHMPIDsignal; 
631
632   
633   fTrackLength   = source. fTrackLength;
634   fdTPC  = source.fdTPC; 
635   fzTPC  = source.fzTPC; 
636   fCddTPC = source.fCddTPC;
637   fCdzTPC = source.fCdzTPC;
638   fCzzTPC = source.fCzzTPC;
639   fD  = source.fD; 
640   fZ  = source.fZ; 
641   fCdd = source.fCdd;
642   fCdz = source.fCdz;
643   fCzz = source.fCzz;
644
645   fCchi2     = source.fCchi2;
646   fITSchi2   = source.fITSchi2;             
647   fTPCchi2   = source.fTPCchi2;            
648   fTRDchi2   = source.fTRDchi2;      
649   fTOFchi2   = source.fTOFchi2;      
650   fHMPIDchi2 = source.fHMPIDchi2;      
651
652
653   fITSsignal  = source.fITSsignal;     
654   fTPCsignal  = source.fTPCsignal;     
655   fTPCsignalS = source.fTPCsignalS;    
656   for(int i = 0; i< 4;++i){
657     fTPCPoints[i] = source.fTPCPoints[i];  
658   }
659   fTRDsignal = source.fTRDsignal;
660
661   for(int i = 0;i < kTRDnPlanes;++i){
662     fTRDTimBin[i] = source.fTRDTimBin[i];   
663   }
664
665   if(fTRDnSlices)
666     delete[] fTRDslices;
667   fTRDslices=0;
668   fTRDnSlices=source.fTRDnSlices;
669   if (fTRDnSlices) {
670     fTRDslices=new Double32_t[fTRDnSlices];
671     for(int j = 0;j < fTRDnSlices;++j) fTRDslices[j] = source.fTRDslices[j];
672   }
673
674   fTRDQuality =   source.fTRDQuality;     
675   fTRDBudget  =   source.fTRDBudget;      
676   fTOFsignal  =   source.fTOFsignal;     
677   fTOFsignalToT = source.fTOFsignalToT;   
678   fTOFsignalRaw = source.fTOFsignalRaw;  
679   fTOFsignalDz  = source.fTOFsignalDz;      
680   
681   for(int i = 0;i<10;++i){
682     fTOFInfo[i] = source.fTOFInfo[i];    
683   }
684
685   fHMPIDtrkX = source.fHMPIDtrkX; 
686   fHMPIDtrkY = source.fHMPIDtrkY; 
687   fHMPIDmipX = source.fHMPIDmipX;
688   fHMPIDmipY = source.fHMPIDmipY; 
689
690   fTPCncls    = source.fTPCncls;      
691   fTPCnclsF   = source.fTPCnclsF;     
692   fTPCsignalN = source.fTPCsignalN;   
693
694   fITSncls = source.fITSncls;       
695   fITSClusterMap = source.fITSClusterMap; 
696   fTRDncls   = source.fTRDncls;       
697   fTRDncls0  = source.fTRDncls0;      
698   fTRDpidQuality  = source.fTRDpidQuality; 
699   return *this;
700 }
701
702
703
704 void AliESDtrack::Copy(TObject &obj) const {
705   
706   // this overwrites the virtual TOBject::Copy()
707   // to allow run time copying without casting
708   // in AliESDEvent
709
710   if(this==&obj)return;
711   AliESDtrack *robj = dynamic_cast<AliESDtrack*>(&obj);
712   if(!robj)return; // not an AliESDtrack
713   *robj = *this;
714
715 }
716
717
718
719 void AliESDtrack::AddCalibObject(TObject * object){
720   //
721   // add calib object to the list
722   //
723   if (!fFriendTrack) fFriendTrack  = new AliESDfriendTrack;
724   fFriendTrack->AddCalibObject(object);
725 }
726
727 TObject *  AliESDtrack::GetCalibObject(Int_t index){
728   //
729   // return calib objct at given position
730   //
731   if (!fFriendTrack) return 0;
732   return fFriendTrack->GetCalibObject(index);
733 }
734
735
736 const Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
737   
738   // Fills the information of the TPC-only first reconstruction pass
739   // into the passed ESDtrack object. For consistency fTPCInner is also filled
740   // again
741
742   if(!fTPCInner)return kFALSE;
743
744   // fill the TPC track params to the global track parameters
745   track.Set(fTPCInner->GetX(),fTPCInner->GetAlpha(),fTPCInner->GetParameter(),fTPCInner->GetCovariance());
746   track.fD = fdTPC;
747   track.fZ = fzTPC;
748   track.fCdd = fCddTPC;
749   track.fCdz = fCdzTPC;
750   track.fCzz = fCzzTPC;
751
752   // copy the TPCinner parameters
753   if(track.fTPCInner) *track.fTPCInner = *fTPCInner;
754   else track.fTPCInner = new AliExternalTrackParam(*fTPCInner);
755   track.fdTPC   = fdTPC;
756   track.fzTPC   = fzTPC;
757   track.fCddTPC = fCddTPC;
758   track.fCdzTPC = fCdzTPC;
759   track.fCzzTPC = fCzzTPC;
760
761
762   // copy all other TPC specific parameters
763
764   // replace label by TPC label
765   track.fLabel    = fTPCLabel;
766   track.fTPCLabel = fTPCLabel;
767
768   track.fTPCchi2 = fTPCchi2; 
769   track.fTPCsignal = fTPCsignal;
770   track.fTPCsignalS = fTPCsignalS;
771   for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
772
773   track.fTPCncls    = fTPCncls;     
774   track.fTPCnclsF   = fTPCnclsF;     
775   track.fTPCsignalN =  fTPCsignalN;
776
777   // PID 
778   for(int i=0;i<AliPID::kSPECIES;++i){
779     track.fTPCr[i] = fTPCr[i];
780     // combined PID is TPC only!
781     track.fR[i] = fTPCr[i];
782   }
783   track.fTPCClusterMap = fTPCClusterMap;
784   track.fTPCSharedMap = fTPCSharedMap;
785
786
787   // reset the flags
788   track.fFlags = kTPCin;
789   track.fID    = fID;
790
791  
792   for (Int_t i=0;i<3;i++) track.fKinkIndexes[i] = fKinkIndexes[i];
793   
794   return kTRUE;
795     
796 }
797
798 //_______________________________________________________________________
799 void AliESDtrack::MakeMiniESDtrack(){
800   // Resets everything except
801   // fFlags: Reconstruction status flags 
802   // fLabel: Track label
803   // fID:  Unique ID of the track
804   // Impact parameter information
805   // fR[AliPID::kSPECIES]: combined "detector response probability"
806   // Running track parameters in the base class (AliExternalTrackParam)
807   
808   fTrackLength = 0;
809
810   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i] = 0;
811
812   // Reset track parameters constrained to the primary vertex
813   delete fCp;fCp = 0;
814   fCchi2 = 0;
815
816   // Reset track parameters at the inner wall of TPC
817   delete fIp;fIp = 0;
818   delete fTPCInner;fTPCInner=0;
819   // Reset track parameters at the inner wall of the TRD
820   delete fOp;fOp = 0;
821
822
823   // Reset ITS track related information
824   fITSchi2 = 0;
825   fITSncls = 0;       
826   fITSClusterMap=0;
827   fITSsignal = 0;     
828   for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0; 
829   fITSLabel = 0;       
830
831   // Reset TPC related track information
832   fTPCchi2 = 0;       
833   fTPCncls = 0;       
834   fTPCnclsF = 0;       
835   fTPCClusterMap = 0;  
836   fTPCSharedMap = 0;  
837   fTPCsignal= 0;      
838   fTPCsignalS= 0;      
839   fTPCsignalN= 0;      
840   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=0; 
841   fTPCLabel=0;       
842   for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
843   for (Int_t i=0; i<3;i++)   fKinkIndexes[i] = 0;
844   for (Int_t i=0; i<3;i++)   fV0Indexes[i] = 0;
845
846   // Reset TRD related track information
847   fTRDchi2 = 0;        
848   fTRDncls = 0;       
849   fTRDncls0 = 0;       
850   fTRDsignal = 0;      
851   for (Int_t i=0;i<kTRDnPlanes;i++) {
852     fTRDTimBin[i]  = 0;
853   }
854   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0; 
855   fTRDLabel = 0;       
856   fTRDQuality  = 0;
857   fTRDpidQuality = 0;
858   if(fTRDnSlices)
859     delete[] fTRDslices;
860   fTRDslices=0x0;
861   fTRDnSlices=0;
862   fTRDBudget  = 0;
863
864   // Reset TOF related track information
865   fTOFchi2 = 0;        
866   fTOFindex = -1;       
867   fTOFsignal = 0;      
868   fTOFCalChannel = 0;
869   fTOFsignalToT = 0;
870   fTOFsignalRaw = 0;
871   fTOFsignalDz = 0;
872   for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
873   for (Int_t i=0;i<3;i++) fTOFLabel[i] = 0;
874   for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
875
876   // Reset HMPID related track information
877   fHMPIDchi2 = 0;     
878   fHMPIDqn = 0;     
879   fHMPIDcluIdx = 0;     
880   fHMPIDsignal = 0;     
881   for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
882   fHMPIDtrkTheta = 0;     
883   fHMPIDtrkPhi = 0;      
884   fHMPIDtrkX = 0;     
885   fHMPIDtrkY = 0;      
886   fHMPIDmipX = 0;
887   fHMPIDmipY = 0;
888   fEMCALindex = kEMCALNoMatch;
889
890   delete fFriendTrack; fFriendTrack = 0;
891
892 //_______________________________________________________________________
893 Double_t AliESDtrack::GetMass() const {
894   // Returns the mass of the most probable particle type
895   Float_t max=0.;
896   Int_t k=-1;
897   for (Int_t i=0; i<AliPID::kSPECIES; i++) {
898     if (fR[i]>max) {k=i; max=fR[i];}
899   }
900   if (k==0) { // dE/dx "crossing points" in the TPC
901      Double_t p=GetP();
902      if ((p>0.38)&&(p<0.48))
903         if (fR[0]<fR[3]*10.) return AliPID::ParticleMass(AliPID::kKaon);
904      if ((p>0.75)&&(p<0.85))
905         if (fR[0]<fR[4]*10.) return AliPID::ParticleMass(AliPID::kProton);
906      return 0.00051;
907   }
908   if (k==1) return AliPID::ParticleMass(AliPID::kMuon); 
909   if (k==2||k==-1) return AliPID::ParticleMass(AliPID::kPion);
910   if (k==3) return AliPID::ParticleMass(AliPID::kKaon);
911   if (k==4) return AliPID::ParticleMass(AliPID::kProton);
912   AliWarning("Undefined mass !");
913   return AliPID::ParticleMass(AliPID::kPion);
914 }
915
916 //______________________________________________________________________________
917 Double_t AliESDtrack::E() const
918 {
919   // Returns the energy of the particle given its assumed mass.
920   // Assumes the pion mass if the particle can't be identified properly.
921   
922   Double_t m = M();
923   Double_t p = P();
924   return TMath::Sqrt(p*p + m*m);
925 }
926
927 //______________________________________________________________________________
928 Double_t AliESDtrack::Y() const
929 {
930   // Returns the rapidity of a particle given its assumed mass.
931   // Assumes the pion mass if the particle can't be identified properly.
932   
933   Double_t e = E();
934   Double_t pz = Pz();
935   if (e != TMath::Abs(pz)) { // energy was not equal to pz
936     return 0.5*TMath::Log((e+pz)/(e-pz));
937   } else { // energy was equal to pz
938     return -999.;
939   }
940 }
941
942 //_______________________________________________________________________
943 Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
944   //
945   // This function updates track's running parameters 
946   //
947   Int_t *index=0;
948   Bool_t rc=kTRUE;
949
950   SetStatus(flags);
951   fLabel=t->GetLabel();
952
953   if (t->IsStartedTimeIntegral()) {
954     SetStatus(kTIME);
955     Double_t times[10];t->GetIntegratedTimes(times); SetIntegratedTimes(times);
956     SetIntegratedLength(t->GetIntegratedLength());
957   }
958
959   Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
960   
961   switch (flags) {
962     
963   case kITSin: case kITSout: case kITSrefit:
964     fITSClusterMap=0;
965     fITSncls=t->GetNumberOfClusters();
966     index=fFriendTrack->GetITSindices(); 
967     for (Int_t i=0;i<AliESDfriendTrack::kMaxITScluster;i++) {
968         index[i]=t->GetClusterIndex(i);
969         if (i<fITSncls) {
970            Int_t l=(index[i] & 0xf0000000) >> 28;
971            SETBIT(fITSClusterMap,l);                 
972         }
973     }
974     fITSchi2=t->GetChi2();
975     fITSsignal=t->GetPIDsignal();
976     fITSLabel = t->GetLabel();
977     // keep in fOp the parameters outside ITS for ITS stand-alone tracks 
978     if (flags==kITSout) { 
979       if (!fOp) fOp=new AliExternalTrackParam(*t);
980       else 
981         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
982     }      
983     break;
984     
985   case kTPCin: case kTPCrefit:
986     fTPCLabel = t->GetLabel();
987     if (flags==kTPCin)  fTPCInner=new AliExternalTrackParam(*t);
988     if (!fIp) fIp=new AliExternalTrackParam(*t);
989     else 
990       fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
991   case kTPCout:
992     index=fFriendTrack->GetTPCindices(); 
993     if (flags & kTPCout){
994       if (!fOp) fOp=new AliExternalTrackParam(*t);
995       else 
996         fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
997     }
998     fTPCncls=t->GetNumberOfClusters();    
999     fTPCchi2=t->GetChi2();
1000     
1001      {//prevrow must be declared in separate namespace, otherwise compiler cries:
1002       //"jump to case label crosses initialization of `Int_t prevrow'"
1003        Int_t prevrow = -1;
1004        //       for (Int_t i=0;i<fTPCncls;i++) 
1005        for (Int_t i=0;i<AliESDfriendTrack::kMaxTPCcluster;i++) 
1006         {
1007           index[i]=t->GetClusterIndex(i);
1008           Int_t idx = index[i];
1009
1010           if (idx<0) continue; 
1011
1012           // Piotr's Cluster Map for HBT  
1013           // ### please change accordingly if cluster array is changing 
1014           // to "New TPC Tracking" style (with gaps in array) 
1015           Int_t sect = (idx&0xff000000)>>24;
1016           Int_t row = (idx&0x00ff0000)>>16;
1017           if (sect > 18) row +=63; //if it is outer sector, add number of inner sectors
1018
1019           fTPCClusterMap.SetBitNumber(row,kTRUE);
1020
1021           //Fill the gap between previous row and this row with 0 bits
1022           //In case  ###  pleas change it as well - just set bit 0 in case there 
1023           //is no associated clusters for current "i"
1024           if (prevrow < 0) 
1025            {
1026              prevrow = row;//if previous bit was not assigned yet == this is the first one
1027            }
1028           else
1029            { //we don't know the order (inner to outer or reverse)
1030              //just to be save in case it is going to change
1031              Int_t n = 0, m = 0;
1032              if (prevrow < row)
1033               {
1034                 n = prevrow;
1035                 m = row;
1036               }
1037              else
1038               {
1039                 n = row;
1040                 m = prevrow;
1041               }
1042
1043              for (Int_t j = n+1; j < m; j++)
1044               {
1045                 fTPCClusterMap.SetBitNumber(j,kFALSE);
1046               }
1047              prevrow = row; 
1048            }
1049           // End Of Piotr's Cluster Map for HBT
1050         }
1051      }
1052     fTPCsignal=t->GetPIDsignal();
1053     break;
1054
1055   case kTRDout: case kTRDin: case kTRDrefit:
1056     index     = fFriendTrack->GetTRDindices();
1057     fTRDLabel = t->GetLabel(); 
1058     fTRDchi2  = t->GetChi2();
1059     fTRDncls  = t->GetNumberOfClusters();
1060     for (Int_t i=0;i<6;i++) index[i]=t->GetTrackletIndex(i);
1061     
1062     fTRDsignal=t->GetPIDsignal();
1063     break;
1064   case kTRDbackup:
1065     if (!fOp) fOp=new AliExternalTrackParam(*t);
1066     else 
1067       fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1068     fTRDncls0 = t->GetNumberOfClusters(); 
1069     break;
1070   case kTOFin: 
1071     break;
1072   case kTOFout: 
1073     break;
1074   case kTRDStop:
1075     break;
1076   default: 
1077     AliError("Wrong flag !");
1078     return kFALSE;
1079   }
1080
1081   return rc;
1082 }
1083
1084 //_______________________________________________________________________
1085 void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const {
1086   //---------------------------------------------------------------------
1087   // This function returns external representation of the track parameters
1088   //---------------------------------------------------------------------
1089   x=GetX();
1090   for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i];
1091 }
1092
1093 //_______________________________________________________________________
1094 void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const {
1095   //---------------------------------------------------------------------
1096   // This function returns external representation of the cov. matrix
1097   //---------------------------------------------------------------------
1098   for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i];
1099 }
1100
1101 //_______________________________________________________________________
1102 Bool_t AliESDtrack::GetConstrainedExternalParameters
1103                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1104   //---------------------------------------------------------------------
1105   // This function returns the constrained external track parameters
1106   //---------------------------------------------------------------------
1107   if (!fCp) return kFALSE;
1108   alpha=fCp->GetAlpha();
1109   x=fCp->GetX();
1110   for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i];
1111   return kTRUE;
1112 }
1113
1114 //_______________________________________________________________________
1115 Bool_t 
1116 AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const {
1117   //---------------------------------------------------------------------
1118   // This function returns the constrained external cov. matrix
1119   //---------------------------------------------------------------------
1120   if (!fCp) return kFALSE;
1121   for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i];
1122   return kTRUE;
1123 }
1124
1125 Bool_t
1126 AliESDtrack::GetInnerExternalParameters
1127                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1128   //---------------------------------------------------------------------
1129   // This function returns external representation of the track parameters 
1130   // at the inner layer of TPC
1131   //---------------------------------------------------------------------
1132   if (!fIp) return kFALSE;
1133   alpha=fIp->GetAlpha();
1134   x=fIp->GetX();
1135   for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i];
1136   return kTRUE;
1137 }
1138
1139 Bool_t 
1140 AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const {
1141  //---------------------------------------------------------------------
1142  // This function returns external representation of the cov. matrix 
1143  // at the inner layer of TPC
1144  //---------------------------------------------------------------------
1145   if (!fIp) return kFALSE;
1146   for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i];
1147   return kTRUE;
1148 }
1149
1150 Bool_t 
1151 AliESDtrack::GetOuterExternalParameters
1152                  (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1153   //---------------------------------------------------------------------
1154   // This function returns external representation of the track parameters 
1155   // at the inner layer of TRD
1156   //---------------------------------------------------------------------
1157   if (!fOp) return kFALSE;
1158   alpha=fOp->GetAlpha();
1159   x=fOp->GetX();
1160   for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i];
1161   return kTRUE;
1162 }
1163
1164 Bool_t 
1165 AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const {
1166  //---------------------------------------------------------------------
1167  // This function returns external representation of the cov. matrix 
1168  // at the inner layer of TRD
1169  //---------------------------------------------------------------------
1170   if (!fOp) return kFALSE;
1171   for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i];
1172   return kTRUE;
1173 }
1174
1175 Int_t AliESDtrack::GetNcls(Int_t idet) const
1176 {
1177   // Get number of clusters by subdetector index
1178   //
1179   Int_t ncls = 0;
1180   switch(idet){
1181   case 0:
1182     ncls = fITSncls;
1183     break;
1184   case 1:
1185     ncls = fTPCncls;
1186     break;
1187   case 2:
1188     ncls = fTRDncls;
1189     break;
1190   case 3:
1191     if (fTOFindex != -1)
1192       ncls = 1;
1193     break;
1194   default:
1195     break;
1196   }
1197   return ncls;
1198 }
1199
1200 Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
1201 {
1202   // Get cluster index array by subdetector index
1203   //
1204   Int_t ncls = 0;
1205   switch(idet){
1206   case 0:
1207     ncls = GetITSclusters(idx);
1208     break;
1209   case 1:
1210     ncls = GetTPCclusters(idx);
1211     break;
1212   case 2:
1213     ncls = GetTRDclusters(idx);
1214     break;
1215   case 3:
1216     if (fTOFindex != -1) {
1217       idx[0] = fTOFindex;
1218       ncls = 1;
1219     }
1220     break;
1221   case 4: //PHOS
1222     break;
1223   case 5:
1224     if (fHMPIDcluIdx != 0) {
1225       idx[0] = GetHMPIDcluIdx();
1226       ncls = 1;
1227     }    
1228     break;
1229   case 6: //EMCAL
1230     break;
1231   default:
1232     break;
1233   }
1234   return ncls;
1235 }
1236
1237 //_______________________________________________________________________
1238 void AliESDtrack::GetIntegratedTimes(Double_t *times) const {
1239   // Returns the array with integrated times for each particle hypothesis
1240   for (Int_t i=0; i<AliPID::kSPECIES; i++) times[i]=fTrackTime[i];
1241 }
1242
1243 //_______________________________________________________________________
1244 void AliESDtrack::SetIntegratedTimes(const Double_t *times) {
1245   // Sets the array with integrated times for each particle hypotesis
1246   for (Int_t i=0; i<AliPID::kSPECIES; i++) fTrackTime[i]=times[i];
1247 }
1248
1249 //_______________________________________________________________________
1250 void AliESDtrack::SetITSpid(const Double_t *p) {
1251   // Sets values for the probability of each particle type (in ITS)
1252   SetPIDValues(fITSr,p,AliPID::kSPECIES);
1253   SetStatus(AliESDtrack::kITSpid);
1254 }
1255
1256 //_______________________________________________________________________
1257 void AliESDtrack::GetITSpid(Double_t *p) const {
1258   // Gets the probability of each particle type (in ITS)
1259   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fITSr[i];
1260 }
1261
1262 //_______________________________________________________________________
1263 Char_t AliESDtrack::GetITSclusters(Int_t *idx) const {
1264   //---------------------------------------------------------------------
1265   // This function returns indices of the assgined ITS clusters 
1266   //---------------------------------------------------------------------
1267   if (idx!=0) {
1268      Int_t *index=fFriendTrack->GetITSindices();
1269      for (Int_t i=0; i<AliESDfriendTrack::kMaxITScluster; i++) {
1270          if ( (i>=fITSncls) && (i<6) ) idx[i]=-1;
1271          else idx[i]=index[i];
1272      }
1273   }
1274   return fITSncls;
1275 }
1276
1277 //_______________________________________________________________________
1278 Bool_t AliESDtrack::GetITSModuleIndexInfo(Int_t ilayer,Int_t &idet,Int_t &status,
1279                                          Float_t &xloc,Float_t &zloc) const {
1280   //----------------------------------------------------------------------
1281   // This function encodes in the module number also the status of cluster association
1282   // "status" can have the following values: 
1283   // 1 "found" (cluster is associated), 
1284   // 2 "dead" (module is dead from OCDB), 
1285   // 3 "skipped" (module or layer forced to be skipped),
1286   // 4 "outinz" (track out of z acceptance), 
1287   // 5 "nocls" (no clusters in the road), 
1288   // 6 "norefit" (cluster rejected during refit), 
1289   // 7 "deadzspd" (holes in z in SPD)
1290   // Also given are the coordinates of the crossing point of track and module
1291   // (in the local module ref. system)
1292   // WARNING: THIS METHOD HAS TO BE SYNCHRONIZED WITH AliITStrackV2::GetModuleIndexInfo()!
1293   //----------------------------------------------------------------------
1294
1295   if(fITSModule[ilayer]==-1) {
1296     AliError("fModule was not set !");
1297     idet = -1;
1298     status=0;
1299     xloc=-99.; zloc=-99.;
1300     return kFALSE;
1301   }
1302
1303   Int_t module = fITSModule[ilayer];
1304
1305   idet = Int_t(module/1000000);
1306
1307   module -= idet*1000000;
1308
1309   status = Int_t(module/100000);
1310
1311   module -= status*100000;
1312
1313   Int_t signs = Int_t(module/10000);
1314
1315   module-=signs*10000;
1316
1317   Int_t xInt = Int_t(module/100);
1318   module -= xInt*100;
1319
1320   Int_t zInt = module;
1321
1322   if(signs==1) { xInt*=1; zInt*=1; }
1323   if(signs==2) { xInt*=1; zInt*=-1; }
1324   if(signs==3) { xInt*=-1; zInt*=1; }
1325   if(signs==4) { xInt*=-1; zInt*=-1; }
1326
1327   xloc = 0.1*(Float_t)xInt;
1328   zloc = 0.1*(Float_t)zInt;
1329
1330   if(status==4) idet = -1;
1331
1332   return kTRUE;
1333 }
1334
1335 //_______________________________________________________________________
1336 UShort_t AliESDtrack::GetTPCclusters(Int_t *idx) const {
1337   //---------------------------------------------------------------------
1338   // This function returns indices of the assgined ITS clusters 
1339   //---------------------------------------------------------------------
1340   if (idx!=0) {
1341     Int_t *index=fFriendTrack->GetTPCindices();
1342     for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=index[i];
1343   }
1344   return fTPCncls;
1345 }
1346
1347 Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
1348   //
1349   // GetDensity of the clusters on given region between row0 and row1
1350   // Dead zone effect takin into acoount
1351   //
1352   Int_t good  = 0;
1353   Int_t found = 0;
1354   //  
1355   Int_t *index=fFriendTrack->GetTPCindices();
1356   for (Int_t i=row0;i<=row1;i++){     
1357     Int_t idx = index[i];
1358     if (idx!=-1)  good++;             // track outside of dead zone
1359     if (idx>0)    found++;
1360   }
1361   Float_t density=0.5;
1362   if (good>(row1-row0)*0.5) density = Float_t(found)/Float_t(good);
1363   return density;
1364 }
1365
1366 //_______________________________________________________________________
1367 void AliESDtrack::SetTPCpid(const Double_t *p) {  
1368   // Sets values for the probability of each particle type (in TPC)
1369   SetPIDValues(fTPCr,p,AliPID::kSPECIES);
1370   SetStatus(AliESDtrack::kTPCpid);
1371 }
1372
1373 //_______________________________________________________________________
1374 void AliESDtrack::GetTPCpid(Double_t *p) const {
1375   // Gets the probability of each particle type (in TPC)
1376   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTPCr[i];
1377 }
1378
1379 //_______________________________________________________________________
1380 UChar_t AliESDtrack::GetTRDclusters(Int_t *idx) const {
1381   //---------------------------------------------------------------------
1382   // This function returns indices of the assgined TRD clusters 
1383   //---------------------------------------------------------------------
1384   if (idx!=0) {
1385      Int_t *index=fFriendTrack->GetTRDindices();
1386      for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=index[i];
1387   }
1388   return fTRDncls;
1389 }
1390
1391 //_______________________________________________________________________
1392 UChar_t AliESDtrack::GetTRDtracklets(Int_t *idx) const {
1393   //---------------------------------------------------------------------
1394   // This function returns indices of the assigned TRD tracklets 
1395   //---------------------------------------------------------------------
1396   if (idx!=0) {
1397      Int_t *index=fFriendTrack->GetTRDindices();
1398      for (Int_t i=0; i<6/*AliESDfriendTrack::kMaxTRDcluster*/; i++) idx[i]=index[i];
1399   }
1400   return fTRDncls;
1401 }
1402
1403 //_______________________________________________________________________
1404 void AliESDtrack::SetTRDpid(const Double_t *p) {  
1405   // Sets values for the probability of each particle type (in TRD)
1406   SetPIDValues(fTRDr,p,AliPID::kSPECIES);
1407   SetStatus(AliESDtrack::kTRDpid);
1408 }
1409
1410 //_______________________________________________________________________
1411 void AliESDtrack::GetTRDpid(Double_t *p) const {
1412   // Gets the probability of each particle type (in TRD)
1413   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTRDr[i];
1414 }
1415
1416 //_______________________________________________________________________
1417 void    AliESDtrack::SetTRDpid(Int_t iSpecies, Float_t p)
1418 {
1419   // Sets the probability of particle type iSpecies to p (in TRD)
1420   fTRDr[iSpecies] = p;
1421 }
1422
1423 Double_t AliESDtrack::GetTRDpid(Int_t iSpecies) const
1424 {
1425   // Returns the probability of particle type iSpecies (in TRD)
1426   return fTRDr[iSpecies];
1427 }
1428
1429 void  AliESDtrack::SetNumberOfTRDslices(Int_t n) {
1430   //Sets the number of slices used for PID 
1431   if (fTRDnSlices != 0) return;
1432   fTRDnSlices=kTRDnPlanes*n;
1433   fTRDslices=new Double32_t[fTRDnSlices];
1434   for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=-1.;
1435 }
1436
1437 void  AliESDtrack::SetTRDslice(Double_t q, Int_t plane, Int_t slice) {
1438   //Sets the charge q in the slice of the plane
1439   Int_t ns=GetNumberOfTRDslices();
1440   if (ns==0) {
1441     AliError("No TRD slices allocated for this track !");
1442     return;
1443   }
1444
1445   if ((plane<0) || (plane>=kTRDnPlanes)) {
1446     AliError("Wrong TRD plane !");
1447     return;
1448   }
1449   if ((slice<0) || (slice>=ns)) {
1450     AliError("Wrong TRD slice !");
1451     return;
1452   }
1453   Int_t n=plane*ns + slice;
1454   fTRDslices[n]=q;
1455 }
1456
1457 Double_t  AliESDtrack::GetTRDslice(Int_t plane, Int_t slice) const {
1458   //Gets the charge from the slice of the plane
1459   Int_t ns=GetNumberOfTRDslices();
1460   if (ns==0) {
1461     //AliError("No TRD slices allocated for this track !");
1462     return -1.;
1463   }
1464
1465   if ((plane<0) || (plane>=kTRDnPlanes)) {
1466     AliError("Wrong TRD plane !");
1467     return -1.;
1468   }
1469   if ((slice<-1) || (slice>=ns)) {
1470     //AliError("Wrong TRD slice !");  
1471     return -1.;
1472   }
1473
1474   if (slice==-1) {
1475     Double_t q=0.;
1476     for (Int_t i=0; i<ns; i++) q+=fTRDslices[plane*ns + i];
1477     return q/ns;
1478   }
1479
1480   return fTRDslices[plane*ns + slice];
1481 }
1482
1483
1484 //_______________________________________________________________________
1485 void AliESDtrack::SetTOFpid(const Double_t *p) {  
1486   // Sets the probability of each particle type (in TOF)
1487   SetPIDValues(fTOFr,p,AliPID::kSPECIES);
1488   SetStatus(AliESDtrack::kTOFpid);
1489 }
1490
1491 //_______________________________________________________________________
1492 void AliESDtrack::SetTOFLabel(const Int_t *p) {  
1493   // Sets  (in TOF)
1494   for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
1495 }
1496
1497 //_______________________________________________________________________
1498 void AliESDtrack::GetTOFpid(Double_t *p) const {
1499   // Gets probabilities of each particle type (in TOF)
1500   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTOFr[i];
1501 }
1502
1503 //_______________________________________________________________________
1504 void AliESDtrack::GetTOFLabel(Int_t *p) const {
1505   // Gets (in TOF)
1506   for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
1507 }
1508
1509 //_______________________________________________________________________
1510 void AliESDtrack::GetTOFInfo(Float_t *info) const {
1511   // Gets (in TOF)
1512   for (Int_t i=0; i<10; i++) info[i]=fTOFInfo[i];
1513 }
1514
1515 //_______________________________________________________________________
1516 void AliESDtrack::SetTOFInfo(Float_t*info) {
1517   // Gets (in TOF)
1518   for (Int_t i=0; i<10; i++) fTOFInfo[i]=info[i];
1519 }
1520
1521
1522
1523 //_______________________________________________________________________
1524 void AliESDtrack::SetHMPIDpid(const Double_t *p) {  
1525   // Sets the probability of each particle type (in HMPID)
1526   SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
1527   SetStatus(AliESDtrack::kHMPIDpid);
1528 }
1529
1530 //_______________________________________________________________________
1531 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
1532   // Gets probabilities of each particle type (in HMPID)
1533   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fHMPIDr[i];
1534 }
1535
1536
1537
1538 //_______________________________________________________________________
1539 void AliESDtrack::SetESDpid(const Double_t *p) {  
1540   // Sets the probability of each particle type for the ESD track
1541   SetPIDValues(fR,p,AliPID::kSPECIES);
1542   SetStatus(AliESDtrack::kESDpid);
1543 }
1544
1545 //_______________________________________________________________________
1546 void AliESDtrack::GetESDpid(Double_t *p) const {
1547   // Gets probability of each particle type for the ESD track
1548   for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fR[i];
1549 }
1550
1551 //_______________________________________________________________________
1552 Bool_t AliESDtrack::RelateToVertexTPC
1553 (const AliESDVertex *vtx, Double_t b, Double_t maxd) {
1554   //
1555   // Try to relate the TPC-only track paramters to the vertex "vtx", 
1556   // if the (rough) transverse impact parameter is not bigger then "maxd". 
1557   //            Magnetic field is "b" (kG).
1558   //
1559   // a) The TPC-only paramters are extapolated to the DCA to the vertex.
1560   // b) The impact parameters and their covariance matrix are calculated.
1561   //
1562
1563   if (!fTPCInner) return kFALSE;
1564   if (!vtx) return kFALSE;
1565
1566   Double_t dz[2],cov[3];
1567   if (!fTPCInner->PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
1568
1569   fdTPC = dz[0];
1570   fzTPC = dz[1];  
1571   fCddTPC = cov[0];
1572   fCdzTPC = cov[1];
1573   fCzzTPC = cov[2];
1574   
1575   return kTRUE;
1576 }
1577
1578 //_______________________________________________________________________
1579 Bool_t AliESDtrack::RelateToVertex
1580 (const AliESDVertex *vtx, Double_t b, Double_t maxd) {
1581   //
1582   // Try to relate this track to the vertex "vtx", 
1583   // if the (rough) transverse impact parameter is not bigger then "maxd". 
1584   //            Magnetic field is "b" (kG).
1585   //
1586   // a) The track gets extapolated to the DCA to the vertex.
1587   // b) The impact parameters and their covariance matrix are calculated.
1588   // c) An attempt to constrain this track to the vertex is done.
1589   //
1590   //    In the case of success, the returned value is kTRUE
1591   //    (otherwise, it's kFALSE)
1592   //  
1593
1594   if (!vtx) return kFALSE;
1595
1596   Double_t dz[2],cov[3];
1597   if (!PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
1598
1599   fD = dz[0];
1600   fZ = dz[1];  
1601   fCdd = cov[0];
1602   fCdz = cov[1];
1603   fCzz = cov[2];
1604   
1605   Double_t covar[6]; vtx->GetCovMatrix(covar);
1606   Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
1607   Double_t c[3]={covar[2],0.,covar[5]};
1608
1609   Double_t chi2=GetPredictedChi2(p,c);
1610   if (chi2>77.) return kFALSE;
1611
1612   delete fCp;
1613   fCp=new AliExternalTrackParam(*this);  
1614
1615   if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
1616   
1617   fCchi2=chi2;
1618   return kTRUE;
1619 }
1620
1621 //_______________________________________________________________________
1622 void AliESDtrack::Print(Option_t *) const {
1623   // Prints info on the track
1624   AliExternalTrackParam::Print();
1625   printf("ESD track info\n") ; 
1626   Double_t p[AliPID::kSPECIESN] ; 
1627   Int_t index = 0 ; 
1628   if( IsOn(kITSpid) ){
1629     printf("From ITS: ") ; 
1630     GetITSpid(p) ; 
1631     for(index = 0 ; index < AliPID::kSPECIES; index++) 
1632       printf("%f, ", p[index]) ;
1633     printf("\n           signal = %f\n", GetITSsignal()) ;
1634   } 
1635   if( IsOn(kTPCpid) ){
1636     printf("From TPC: ") ; 
1637     GetTPCpid(p) ; 
1638     for(index = 0 ; index < AliPID::kSPECIES; index++) 
1639       printf("%f, ", p[index]) ;
1640     printf("\n           signal = %f\n", GetTPCsignal()) ;
1641   }
1642   if( IsOn(kTRDpid) ){
1643     printf("From TRD: ") ; 
1644     GetTRDpid(p) ; 
1645     for(index = 0 ; index < AliPID::kSPECIES; index++) 
1646       printf("%f, ", p[index]) ;
1647       printf("\n           signal = %f\n", GetTRDsignal()) ;
1648   }
1649   if( IsOn(kTOFpid) ){
1650     printf("From TOF: ") ; 
1651     GetTOFpid(p) ; 
1652     for(index = 0 ; index < AliPID::kSPECIES; index++) 
1653       printf("%f, ", p[index]) ;
1654     printf("\n           signal = %f\n", GetTOFsignal()) ;
1655   }
1656   if( IsOn(kHMPIDpid) ){
1657     printf("From HMPID: ") ; 
1658     GetHMPIDpid(p) ; 
1659     for(index = 0 ; index < AliPID::kSPECIES; index++) 
1660       printf("%f, ", p[index]) ;
1661     printf("\n           signal = %f\n", GetHMPIDsignal()) ;
1662   }
1663
1664
1665
1666 //
1667 // Draw functionality
1668 // Origin: Marian Ivanov, Marian.Ivanov@cern.ch
1669 //
1670 void AliESDtrack::FillPolymarker(TPolyMarker3D *pol, Float_t magF, Float_t minR, Float_t maxR, Float_t stepR){
1671   //
1672   // Fill points in the polymarker
1673   //
1674   TObjArray arrayRef;
1675   arrayRef.AddLast(new AliExternalTrackParam(*this));
1676   if (fIp) arrayRef.AddLast(new AliExternalTrackParam(*fIp));
1677   if (fOp) arrayRef.AddLast(new AliExternalTrackParam(*fOp));
1678   //
1679   Double_t mpos[3]={0,0,0};
1680   Int_t entries=arrayRef.GetEntries();
1681   for (Int_t i=0;i<entries;i++){
1682     Double_t pos[3];
1683     ((AliExternalTrackParam*)arrayRef.At(i))->GetXYZ(pos);
1684     mpos[0]+=pos[0]/entries;
1685     mpos[1]+=pos[1]/entries;
1686     mpos[2]+=pos[2]/entries;    
1687   }
1688   // Rotate to the mean position
1689   //
1690   Float_t fi= TMath::ATan2(mpos[1],mpos[0]);
1691   for (Int_t i=0;i<entries;i++){
1692     Bool_t res = ((AliExternalTrackParam*)arrayRef.At(i))->Rotate(fi);
1693     if (!res) delete arrayRef.RemoveAt(i);
1694   }
1695   Int_t counter=0;
1696   for (Double_t r=minR; r<maxR; r+=stepR){
1697     Double_t sweight=0;
1698     Double_t mlpos[3]={0,0,0};
1699     for (Int_t i=0;i<entries;i++){
1700       Double_t point[3]={0,0,0};
1701       AliExternalTrackParam *param = ((AliExternalTrackParam*)arrayRef.At(i));
1702       if (!param) continue;
1703       if (param->GetXYZAt(r,magF,point)){
1704         Double_t weight = 1./(10.+(r-param->GetX())*(r-param->GetX()));
1705         sweight+=weight;
1706         mlpos[0]+=point[0]*weight;
1707         mlpos[1]+=point[1]*weight;
1708         mlpos[2]+=point[2]*weight;
1709       }
1710     }
1711     if (sweight>0){
1712       mlpos[0]/=sweight;
1713       mlpos[1]/=sweight;
1714       mlpos[2]/=sweight;      
1715       pol->SetPoint(counter,mlpos[0],mlpos[1], mlpos[2]);
1716       printf("xyz\t%f\t%f\t%f\n",mlpos[0], mlpos[1],mlpos[2]);
1717       counter++;
1718     }
1719   }
1720 }