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