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