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