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