]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCseed.cxx
VZERO volumes now placed in common mother.
[u/mrichter/AliRoot.git] / TPC / AliTPCseed.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
17
18
19 //-----------------------------------------------------------------
20 //           Implementation of the TPC seed class
21 //        This class is used by the AliTPCtrackerMI class
22 //      Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch
23 //-----------------------------------------------------------------
24 #include "TClonesArray.h"
25 #include "AliTPCseed.h"
26 #include "AliTPCReconstructor.h"
27
28 ClassImp(AliTPCseed)
29
30
31
32 AliTPCseed::AliTPCseed():
33   AliTPCtrack(),
34   fEsd(0x0),
35   fClusterOwner(kFALSE),
36   fPoints(0x0),
37   fEPoints(0x0),
38   fRow(0),
39   fSector(-1),
40   fRelativeSector(-1),
41   fCurrentSigmaY2(1e10),
42   fCurrentSigmaZ2(1e10),
43   fErrorY2(1e10),
44   fErrorZ2(1e10),
45   fCurrentCluster(0x0),
46   fCurrentClusterIndex1(-1),
47   fInDead(kFALSE),
48   fIsSeeding(kFALSE),
49   fNoCluster(0),
50   fSort(0),
51   fBSigned(kFALSE),
52   fSeedType(0),
53   fSeed1(-1),
54   fSeed2(-1),
55   fMAngular(0),
56   fCircular(0)
57 {
58   //
59   for (Int_t i=0;i<160;i++) SetClusterIndex2(i,-3);
60   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
61   for (Int_t i=0;i<3;i++)   fKinkIndexes[i]=0;
62   for (Int_t i=0;i<AliPID::kSPECIES;i++)   fTPCr[i]=0.2;
63   for (Int_t i=0;i<4;i++) {
64     fDEDX[i] = 0.;
65     fSDEDX[i] = 1e10;
66     fNCDEDX[i] = 0;
67   }
68   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
69 }
70
71 AliTPCseed::AliTPCseed(const AliTPCseed &s, Bool_t clusterOwner):
72   AliTPCtrack(s),
73   fEsd(0x0),
74   fClusterOwner(clusterOwner),
75   fPoints(0x0),
76   fEPoints(0x0),
77   fRow(0),
78   fSector(-1),
79   fRelativeSector(-1),
80   fCurrentSigmaY2(1e10),
81   fCurrentSigmaZ2(1e10),
82   fErrorY2(1e10),
83   fErrorZ2(1e10),
84   fCurrentCluster(0x0),
85   fCurrentClusterIndex1(-1),
86   fInDead(kFALSE),
87   fIsSeeding(kFALSE),
88   fNoCluster(0),
89   fSort(0),
90   fBSigned(kFALSE),
91   fSeedType(0),
92   fSeed1(-1),
93   fSeed2(-1),
94   fMAngular(0),
95   fCircular(0)
96 {
97   //---------------------
98   // dummy copy constructor
99   //-------------------------
100   for (Int_t i=0;i<160;i++) {
101     fClusterPointer[i]=0;
102     if (fClusterOwner){
103       if (s.fClusterPointer[i])
104         fClusterPointer[i] = new AliTPCclusterMI(*(s.fClusterPointer[i]));
105     }else{
106       fClusterPointer[i] = s.fClusterPointer[i];
107     }
108     fTrackPoints[i] = s.fTrackPoints[i];
109   }
110   for (Int_t i=0;i<160;i++) fIndex[i] = s.fIndex[i];
111   for (Int_t i=0;i<AliPID::kSPECIES;i++)   fTPCr[i]=s.fTPCr[i];
112   for (Int_t i=0;i<4;i++) {
113     fDEDX[i] = s.fDEDX[i];
114     fSDEDX[i] = s.fSDEDX[i];
115     fNCDEDX[i] = s.fNCDEDX[i];
116   }
117   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = s.fOverlapLabels[i];
118 }
119
120
121 AliTPCseed::AliTPCseed(const AliTPCtrack &t):
122   AliTPCtrack(t),
123   fEsd(0x0),
124   fClusterOwner(kFALSE),
125   fPoints(0x0),
126   fEPoints(0x0),
127   fRow(0),
128   fSector(-1),
129   fRelativeSector(-1),
130   fCurrentSigmaY2(1e10),
131   fCurrentSigmaZ2(1e10),
132   fErrorY2(1e10),
133   fErrorZ2(1e10),
134   fCurrentCluster(0x0),
135   fCurrentClusterIndex1(-1),
136   fInDead(kFALSE),
137   fIsSeeding(kFALSE),
138   fNoCluster(0),
139   fSort(0),
140   fBSigned(kFALSE),
141   fSeedType(0),
142   fSeed1(-1),
143   fSeed2(-1),
144   fMAngular(0),
145   fCircular(0)
146 {
147   //
148   // Constructor from AliTPCtrack
149   //
150   fFirstPoint =0;
151   for (Int_t i=0;i<5;i++)   fTPCr[i]=0.2;
152   for (Int_t i=0;i<160;i++) {
153     fClusterPointer[i] = 0;
154     Int_t index = t.GetClusterIndex(i);
155     if (index>=-1){ 
156       SetClusterIndex2(i,index);
157     }
158     else{
159       SetClusterIndex2(i,-3); 
160     }    
161   }
162   for (Int_t i=0;i<4;i++) {
163     fDEDX[i] = 0.;
164     fSDEDX[i] = 1e10;
165     fNCDEDX[i] = 0;
166   }
167   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
168 }
169
170 AliTPCseed::AliTPCseed(Double_t xr, Double_t alpha, const Double_t xx[5],
171                        const Double_t cc[15], Int_t index):      
172   AliTPCtrack(xr, alpha, xx, cc, index),
173   fEsd(0x0),
174   fClusterOwner(kFALSE),
175   fPoints(0x0),
176   fEPoints(0x0),
177   fRow(0),
178   fSector(-1),
179   fRelativeSector(-1),
180   fCurrentSigmaY2(1e10),
181   fCurrentSigmaZ2(1e10),
182   fErrorY2(1e10),
183   fErrorZ2(1e10),
184   fCurrentCluster(0x0),
185   fCurrentClusterIndex1(-1),
186   fInDead(kFALSE),
187   fIsSeeding(kFALSE),
188   fNoCluster(0),
189   fSort(0),
190   fBSigned(kFALSE),
191   fSeedType(0),
192   fSeed1(-1),
193   fSeed2(-1),
194   fMAngular(0),
195   fCircular(0)
196 {
197   //
198   // Constructor
199   //
200   fFirstPoint =0;
201   for (Int_t i=0;i<160;i++) SetClusterIndex2(i,-3);
202   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
203   for (Int_t i=0;i<5;i++)   fTPCr[i]=0.2;
204   for (Int_t i=0;i<4;i++) {
205     fDEDX[i] = 0.;
206     fSDEDX[i] = 1e10;
207     fNCDEDX[i] = 0;
208   }
209   for (Int_t i=0;i<12;i++) fOverlapLabels[i] = -1;
210 }
211
212 AliTPCseed::~AliTPCseed(){
213   //
214   // destructor
215   if (fPoints) delete fPoints;
216   fPoints =0;
217   if (fEPoints) delete fEPoints;
218   fEPoints = 0;
219   fNoCluster =0;
220   if (fClusterOwner){
221     for (Int_t icluster=0; icluster<160; icluster++){
222       delete fClusterPointer[icluster];
223     }
224   }
225 }
226 //_________________________________________________
227 AliTPCseed & AliTPCseed::operator =(const AliTPCseed & param)
228 {
229   //
230   // assignment operator - dummy
231   //
232   fRow=param.fRow;
233   return (*this);
234 }
235 //____________________________________________________
236 AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
237 {
238   //
239   // 
240   return &fTrackPoints[i];
241 }
242
243 void AliTPCseed::RebuildSeed()
244 {
245   //
246   // rebuild seed to be ready for storing
247   AliTPCclusterMI cldummy;
248   cldummy.SetQ(0);
249   AliTPCTrackPoint pdummy;
250   pdummy.GetTPoint().SetShared(10);
251   for (Int_t i=0;i<160;i++){
252     AliTPCclusterMI * cl0 = fClusterPointer[i];
253     AliTPCTrackPoint *trpoint = (AliTPCTrackPoint*)fPoints->UncheckedAt(i);     
254     if (cl0){
255       trpoint->GetTPoint() = *(GetTrackPoint(i));
256       trpoint->GetCPoint() = *cl0;
257       trpoint->GetCPoint().SetQ(TMath::Abs(cl0->GetQ()));
258     }
259     else{
260       *trpoint = pdummy;
261       trpoint->GetCPoint()= cldummy;
262     }
263     
264   }
265
266 }
267
268
269 Double_t AliTPCseed::GetDensityFirst(Int_t n)
270 {
271   //
272   //
273   // return cluster for n rows bellow first point
274   Int_t nfoundable = 1;
275   Int_t nfound      = 1;
276   for (Int_t i=fLastPoint-1;i>0&&nfoundable<n; i--){
277     Int_t index = GetClusterIndex2(i);
278     if (index!=-1) nfoundable++;
279     if (index>0) nfound++;
280   }
281   if (nfoundable<n) return 0;
282   return Double_t(nfound)/Double_t(nfoundable);
283
284 }
285
286
287 void AliTPCseed::GetClusterStatistic(Int_t first, Int_t last, Int_t &found, Int_t &foundable, Int_t &shared, Bool_t plus2)
288 {
289   // get cluster stat.  on given region
290   //
291   found       = 0;
292   foundable   = 0;
293   shared      =0;
294   for (Int_t i=first;i<last; i++){
295     Int_t index = GetClusterIndex2(i);
296     if (index!=-1) foundable++;
297     if (fClusterPointer[i]) {
298       found++;
299     }
300     else 
301       continue;
302
303     if (fClusterPointer[i]->IsUsed(10)) {
304       shared++;
305       continue;
306     }
307     if (!plus2) continue; //take also neighborhoud
308     //
309     if ( (i>0) && fClusterPointer[i-1]){
310       if (fClusterPointer[i-1]->IsUsed(10)) {
311         shared++;
312         continue;
313       }
314     }
315     if ( fClusterPointer[i+1]){
316       if (fClusterPointer[i+1]->IsUsed(10)) {
317         shared++;
318         continue;
319       }
320     }
321     
322   }
323   //if (shared>found){
324     //Error("AliTPCseed::GetClusterStatistic","problem\n");
325   //}
326 }
327
328
329
330
331
332 void AliTPCseed::Reset(Bool_t all)
333 {
334   //
335   //
336   SetNumberOfClusters(0);
337   fNFoundable = 0;
338   SetChi2(0);
339   ResetCovariance(10.);
340   /*
341   if (fTrackPoints){
342     for (Int_t i=0;i<8;i++){
343       delete [] fTrackPoints[i];
344     }
345     delete fTrackPoints;
346     fTrackPoints =0;
347   }
348   */
349
350   if (all){   
351     for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
352     for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
353   }
354
355 }
356
357
358 void AliTPCseed::Modify(Double_t factor)
359 {
360
361   //------------------------------------------------------------------
362   //This function makes a track forget its history :)  
363   //------------------------------------------------------------------
364   if (factor<=0) {
365     ResetCovariance(10.);
366     return;
367   }
368   ResetCovariance(factor);
369
370   SetNumberOfClusters(0);
371   fNFoundable =0;
372   SetChi2(0);
373   fRemoval = 0;
374   fCurrentSigmaY2 = 0.000005;
375   fCurrentSigmaZ2 = 0.000005;
376   fNoCluster     = 0;
377   //fFirstPoint = 160;
378   //fLastPoint  = 0;
379 }
380
381
382
383
384 Int_t  AliTPCseed::GetProlongation(Double_t xk, Double_t &y, Double_t & z) const
385 {
386   //-----------------------------------------------------------------
387   // This function find proloncation of a track to a reference plane x=xk.
388   // doesn't change internal state of the track
389   //-----------------------------------------------------------------
390   
391   Double_t x1=GetX(), x2=x1+(xk-x1), dx=x2-x1;
392
393   if (TMath::Abs(GetSnp()+GetC()*dx) >= AliTPCReconstructor::GetMaxSnpTrack()) {   
394     return 0;
395   }
396
397   //  Double_t y1=fP0, z1=fP1;
398   Double_t c1=GetSnp(), r1=sqrt(1.- c1*c1);
399   Double_t c2=c1 + GetC()*dx, r2=sqrt(1.- c2*c2);
400   
401   y = GetY();
402   z = GetZ();
403   //y += dx*(c1+c2)/(r1+r2);
404   //z += dx*(c1+c2)/(c1*r2 + c2*r1)*fP3;
405   
406   Double_t dy = dx*(c1+c2)/(r1+r2);
407   Double_t dz = 0;
408   //
409   Double_t delta = GetC()*dx*(c1+c2)/(c1*r2 + c2*r1);
410   /*
411   if (TMath::Abs(delta)>0.0001){
412     dz = fP3*TMath::ASin(delta)/fP4;
413   }else{
414     dz = dx*fP3*(c1+c2)/(c1*r2 + c2*r1);
415   }
416   */
417   //  dz =  fP3*AliTPCFastMath::FastAsin(delta)/fP4;
418   dz =  GetTgl()*TMath::ASin(delta)/GetC();
419   //
420   y+=dy;
421   z+=dz;
422   
423
424   return 1;  
425 }
426
427
428 //_____________________________________________________________________________
429 Double_t AliTPCseed::GetPredictedChi2(const AliCluster *c) const 
430 {
431   //-----------------------------------------------------------------
432   // This function calculates a predicted chi2 increment.
433   //-----------------------------------------------------------------
434   Double_t p[2]={c->GetY(), c->GetZ()};
435   Double_t cov[3]={fErrorY2, 0., fErrorZ2};
436   return AliExternalTrackParam::GetPredictedChi2(p,cov);
437 }
438
439 //_________________________________________________________________________________________
440
441
442 Int_t AliTPCseed::Compare(const TObject *o) const {
443   //-----------------------------------------------------------------
444   // This function compares tracks according to the sector - for given sector according z
445   //-----------------------------------------------------------------
446   AliTPCseed *t=(AliTPCseed*)o;
447
448   if (fSort == 0){
449     if (t->fRelativeSector>fRelativeSector) return -1;
450     if (t->fRelativeSector<fRelativeSector) return 1;
451     Double_t z2 = t->GetZ();
452     Double_t z1 = GetZ();
453     if (z2>z1) return 1;
454     if (z2<z1) return -1;
455     return 0;
456   }
457   else {
458     Float_t f2 =1;
459     f2 = 1-20*TMath::Sqrt(t->GetSigma1Pt2())/(TMath::Abs(t->Get1Pt())+0.0066);
460     if (t->fBConstrain) f2=1.2;
461
462     Float_t f1 =1;
463     f1 = 1-20*TMath::Sqrt(GetSigma1Pt2())/(TMath::Abs(Get1Pt())+0.0066);
464
465     if (fBConstrain)   f1=1.2;
466  
467     if (t->GetNumberOfClusters()*f2 <GetNumberOfClusters()*f1) return -1;
468     else return +1;
469   }
470 }
471
472
473
474
475 //_____________________________________________________________________________
476 Bool_t AliTPCseed::Update(const AliCluster *c, Double_t chisq, Int_t /*index*/)
477 {
478   //-----------------------------------------------------------------
479   // This function associates a cluster with this track.
480   //-----------------------------------------------------------------
481   Double_t p[2]={c->GetY(), c->GetZ()};
482   Double_t cov[3]={fErrorY2, 0., fErrorZ2};
483
484   if (!AliExternalTrackParam::Update(p,cov)) return kFALSE;
485
486   Int_t n=GetNumberOfClusters();
487   //  fIndex[n]=index;
488   SetNumberOfClusters(n+1);
489   SetChi2(GetChi2()+chisq);
490
491   return kTRUE;
492 }
493
494
495
496 //_____________________________________________________________________________
497 Float_t AliTPCseed::CookdEdx(Double_t low, Double_t up,Int_t i1, Int_t i2, Bool_t onlyused) {
498   //-----------------------------------------------------------------
499   // This funtion calculates dE/dX within the "low" and "up" cuts.
500   //-----------------------------------------------------------------
501
502   Float_t amp[200];
503   Float_t angular[200];
504   Float_t weight[200];
505   Int_t index[200];
506   //Int_t nc = 0;
507   //  TClonesArray & arr = *fPoints; 
508   Float_t meanlog = 100.;
509   
510   Float_t mean[4]  = {0,0,0,0};
511   Float_t sigma[4] = {1000,1000,1000,1000};
512   Int_t nc[4]      = {0,0,0,0};
513   Float_t norm[4]    = {1000,1000,1000,1000};
514   //
515   //
516   fNShared =0;
517
518   for (Int_t of =0; of<4; of++){    
519     for (Int_t i=of+i1;i<i2;i+=4)
520       {
521         Int_t index = fIndex[i];
522         if (index<0||index&0x8000) continue;
523
524         //AliTPCTrackPoint * point = (AliTPCTrackPoint *) arr.At(i);
525         AliTPCTrackerPoint * point = GetTrackPoint(i);
526         //AliTPCTrackerPoint * pointm = GetTrackPoint(i-1);
527         //AliTPCTrackerPoint * pointp = 0;
528         //if (i<159) pointp = GetTrackPoint(i+1);
529
530         if (point==0) continue;
531         AliTPCclusterMI * cl = fClusterPointer[i];
532         if (cl==0) continue;    
533         if (onlyused && (!cl->IsUsed(10))) continue;
534         if (cl->IsUsed(11)) {
535           fNShared++;
536           continue;
537         }
538         Int_t   type   = cl->GetType();
539         //if (point->fIsShared){
540         //  fNShared++;
541         //  continue;
542         //}
543         //if (pointm) 
544         //  if (pointm->fIsShared) continue;
545         //if (pointp) 
546         //  if (pointp->fIsShared) continue;
547
548         if (type<0) continue;
549         //if (type>10) continue;       
550         //if (point->GetErrY()==0) continue;
551         //if (point->GetErrZ()==0) continue;
552
553         //Float_t ddy = (point->GetY()-cl->GetY())/point->GetErrY();
554         //Float_t ddz = (point->GetZ()-cl->GetZ())/point->GetErrZ();
555         //if ((ddy*ddy+ddz*ddz)>10) continue; 
556
557
558         //      if (point->GetCPoint().GetMax()<5) continue;
559         if (cl->GetMax()<5) continue;
560         Float_t angley = point->GetAngleY();
561         Float_t anglez = point->GetAngleZ();
562
563         Float_t rsigmay2 =  point->GetSigmaY();
564         Float_t rsigmaz2 =  point->GetSigmaZ();
565         /*
566         Float_t ns = 1.;
567         if (pointm){
568           rsigmay +=  pointm->GetTPoint().GetSigmaY();
569           rsigmaz +=  pointm->GetTPoint().GetSigmaZ();
570           ns+=1.;
571         }
572         if (pointp){
573           rsigmay +=  pointp->GetTPoint().GetSigmaY();
574           rsigmaz +=  pointp->GetTPoint().GetSigmaZ();
575           ns+=1.;
576         }
577         rsigmay/=ns;
578         rsigmaz/=ns;
579         */
580
581         Float_t rsigma = TMath::Sqrt(rsigmay2*rsigmaz2);
582
583         Float_t ampc   = 0;     // normalization to the number of electrons
584         if (i>64){
585           //      ampc = 1.*point->GetCPoint().GetMax();
586           ampc = 1.*cl->GetMax();
587           //ampc = 1.*point->GetCPoint().GetQ();          
588           //      AliTPCClusterPoint & p = point->GetCPoint();
589           //      Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.6)) - TMath::Abs(p.GetY()/0.6)+0.5);
590           // Float_t iz =  (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
591           //Float_t dz = 
592           //  TMath::Abs( Int_t(iz) - iz + 0.5);
593           //ampc *= 1.15*(1-0.3*dy);
594           //ampc *= 1.15*(1-0.3*dz);
595           //      Float_t zfactor = (AliTPCReconstructor::GetCtgRange()-0.0004*TMath::Abs(point->GetCPoint().GetZ()));
596           //ampc               *=zfactor; 
597         }
598         else{ 
599           //ampc = 1.0*point->GetCPoint().GetMax(); 
600           ampc = 1.0*cl->GetMax(); 
601           //ampc = 1.0*point->GetCPoint().GetQ(); 
602           //AliTPCClusterPoint & p = point->GetCPoint();
603           // Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.4)) - TMath::Abs(p.GetY()/0.4)+0.5);
604           //Float_t iz =  (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
605           //Float_t dz = 
606           //  TMath::Abs( Int_t(iz) - iz + 0.5);
607
608           //ampc *= 1.15*(1-0.3*dy);
609           //ampc *= 1.15*(1-0.3*dz);
610           //    Float_t zfactor = (1.02-0.000*TMath::Abs(point->GetCPoint().GetZ()));
611           //ampc               *=zfactor; 
612
613         }
614         ampc *= 2.0;     // put mean value to channel 50
615         //ampc *= 0.58;     // put mean value to channel 50
616         Float_t w      =  1.;
617         //      if (type>0)  w =  1./(type/2.-0.5); 
618         //      Float_t z = TMath::Abs(cl->GetZ());
619         if (i<64) {
620           ampc /= 0.6;
621           //ampc /= (1+0.0008*z);
622         } else
623           if (i>128){
624             ampc /=1.5;
625             //ampc /= (1+0.0008*z);
626           }else{
627             //ampc /= (1+0.0008*z);
628           }
629         
630         if (type<0) {  //amp at the border - lower weight
631           // w*= 2.;
632           
633           continue;
634         }
635         if (rsigma>1.5) ampc/=1.3;  // if big backround
636         amp[nc[of]]        = ampc;
637         angular[nc[of]]    = TMath::Sqrt(1.+angley*angley+anglez*anglez);
638         weight[nc[of]]     = w;
639         nc[of]++;
640       }
641     
642     TMath::Sort(nc[of],amp,index,kFALSE);
643     Float_t sumamp=0;
644     Float_t sumamp2=0;
645     Float_t sumw=0;
646     //meanlog = amp[index[Int_t(nc[of]*0.33)]];
647     meanlog = 50;
648     for (Int_t i=int(nc[of]*low+0.5);i<int(nc[of]*up+0.5);i++){
649       Float_t ampl      = amp[index[i]]/angular[index[i]];
650       ampl              = meanlog*TMath::Log(1.+ampl/meanlog);
651       //
652       sumw    += weight[index[i]]; 
653       sumamp  += weight[index[i]]*ampl;
654       sumamp2 += weight[index[i]]*ampl*ampl;
655       norm[of]    += angular[index[i]]*weight[index[i]];
656     }
657     if (sumw<1){ 
658       SetdEdx(0);  
659     }
660     else {
661       norm[of] /= sumw;
662       mean[of]  = sumamp/sumw;
663       sigma[of] = sumamp2/sumw-mean[of]*mean[of];
664       if (sigma[of]>0.1) 
665         sigma[of] = TMath::Sqrt(sigma[of]);
666       else
667         sigma[of] = 1000;
668       
669     mean[of] = (TMath::Exp(mean[of]/meanlog)-1)*meanlog;
670     //mean  *=(1-0.02*(sigma/(mean*0.17)-1.));
671     //mean *=(1-0.1*(norm-1.));
672     }
673   }
674
675   Float_t dedx =0;
676   fSdEdx =0;
677   fMAngular =0;
678   //  mean[0]*= (1-0.05*(sigma[0]/(0.01+mean[1]*0.18)-1));
679   //  mean[1]*= (1-0.05*(sigma[1]/(0.01+mean[0]*0.18)-1));
680
681   
682   //  dedx = (mean[0]* TMath::Sqrt((1.+nc[0]))+ mean[1]* TMath::Sqrt((1.+nc[1])) )/ 
683   //  (  TMath::Sqrt((1.+nc[0]))+TMath::Sqrt((1.+nc[1])));
684
685   Int_t norm2 = 0;
686   Int_t norm3 = 0;
687   for (Int_t i =0;i<4;i++){
688     if (nc[i]>2&&nc[i]<1000){
689       dedx      += mean[i] *nc[i];
690       fSdEdx    += sigma[i]*(nc[i]-2);
691       fMAngular += norm[i] *nc[i];    
692       norm2     += nc[i];
693       norm3     += nc[i]-2;
694     }
695     fDEDX[i]  = mean[i];             
696     fSDEDX[i] = sigma[i];            
697     fNCDEDX[i]= nc[i]; 
698   }
699
700   if (norm3>0){
701     dedx   /=norm2;
702     fSdEdx /=norm3;
703     fMAngular/=norm2;
704   }
705   else{
706     SetdEdx(0);
707     return 0;
708   }
709   //  Float_t dedx1 =dedx;
710   /*
711   dedx =0;
712   for (Int_t i =0;i<4;i++){
713     if (nc[i]>2&&nc[i]<1000){
714       mean[i]   = mean[i]*(1-0.12*(sigma[i]/(fSdEdx)-1.));
715       dedx      += mean[i] *nc[i];
716     }
717     fDEDX[i]  = mean[i];                
718   }
719   dedx /= norm2;
720   */
721
722   
723   SetdEdx(dedx);
724   return dedx;
725 }
726 Double_t AliTPCseed::Bethe(Double_t bg){
727   //
728   // This is the Bethe-Bloch function normalised to 1 at the minimum
729   //
730   Double_t bg2=bg*bg;
731   Double_t bethe;
732   if (bg<3.5e1) 
733     bethe=(1.+ bg2)/bg2*(log(5940*bg2) - bg2/(1.+ bg2));
734   else // Density effect ( approximately :) 
735     bethe=1.15*(1.+ bg2)/bg2*(log(3.5*5940*bg) - bg2/(1.+ bg2));
736   return bethe/11.091;
737 }
738
739 void AliTPCseed::CookPID()
740 {
741   //
742   // cook PID information according dEdx
743   //
744   Double_t fRange = 10.;
745   Double_t fRes   = 0.1;
746   Double_t fMIP   = 47.;
747   //
748   Int_t ns=AliPID::kSPECIES;
749   Double_t sumr =0;
750   for (Int_t j=0; j<ns; j++) {
751     Double_t mass=AliPID::ParticleMass(j);
752     Double_t mom=GetP();
753     Double_t dedx=fdEdx/fMIP;
754     Double_t bethe=Bethe(mom/mass); 
755     Double_t sigma=fRes*bethe;
756     if (sigma>0.001){
757       if (TMath::Abs(dedx-bethe) > fRange*sigma) {
758         fTPCr[j]=TMath::Exp(-0.5*fRange*fRange)/sigma;
759         sumr+=fTPCr[j];
760         continue;
761       }
762       fTPCr[j]=TMath::Exp(-0.5*(dedx-bethe)*(dedx-bethe)/(sigma*sigma))/sigma;
763       sumr+=fTPCr[j];
764     }
765     else{
766       fTPCr[j]=1.;
767       sumr+=fTPCr[j];
768     }
769   }
770   for (Int_t j=0; j<ns; j++) {
771     fTPCr[j]/=sumr;           //normalize
772   }
773 }
774
775 /*
776 void AliTPCseed::CookdEdx2(Double_t low, Double_t up) {
777   //-----------------------------------------------------------------
778   // This funtion calculates dE/dX within the "low" and "up" cuts.
779   //-----------------------------------------------------------------
780
781   Float_t amp[200];
782   Float_t angular[200];
783   Float_t weight[200];
784   Int_t index[200];
785   Bool_t inlimit[200];
786   for (Int_t i=0;i<200;i++) inlimit[i]=kFALSE;
787   for (Int_t i=0;i<200;i++) amp[i]=10000;
788   for (Int_t i=0;i<200;i++) angular[i]= 1;;
789   
790
791   //
792   Float_t meanlog = 100.;
793   Int_t indexde[4]={0,64,128,160};
794
795   Float_t amean     =0;
796   Float_t asigma    =0;
797   Float_t anc       =0;
798   Float_t anorm     =0;
799
800   Float_t mean[4]  = {0,0,0,0};
801   Float_t sigma[4] = {1000,1000,1000,1000};
802   Int_t nc[4]      = {0,0,0,0};
803   Float_t norm[4]    = {1000,1000,1000,1000};
804   //
805   //
806   fNShared =0;
807
808   //  for (Int_t of =0; of<3; of++){    
809   //  for (Int_t i=indexde[of];i<indexde[of+1];i++)
810   for (Int_t i =0; i<160;i++)
811     {
812         AliTPCTrackPoint * point = GetTrackPoint(i);
813         if (point==0) continue;
814         if (point->fIsShared){
815           fNShared++;     
816           continue;
817         }
818         Int_t   type   = point->GetCPoint().GetType();
819         if (type<0) continue;
820         if (point->GetCPoint().GetMax()<5) continue;
821         Float_t angley = point->GetTPoint().GetAngleY();
822         Float_t anglez = point->GetTPoint().GetAngleZ();
823         Float_t rsigmay =  point->GetCPoint().GetSigmaY();
824         Float_t rsigmaz =  point->GetCPoint().GetSigmaZ();
825         Float_t rsigma = TMath::Sqrt(rsigmay*rsigmaz);
826
827         Float_t ampc   = 0;     // normalization to the number of electrons
828         if (i>64){
829           ampc =  point->GetCPoint().GetMax();
830         }
831         else{ 
832           ampc = point->GetCPoint().GetMax(); 
833         }
834         ampc *= 2.0;     // put mean value to channel 50
835         //      ampc *= 0.565;     // put mean value to channel 50
836
837         Float_t w      =  1.;
838         Float_t z = TMath::Abs(point->GetCPoint().GetZ());
839         if (i<64) {
840           ampc /= 0.63;
841         } else
842           if (i>128){
843             ampc /=1.51;
844           }             
845         if (type<0) {  //amp at the border - lower weight                 
846           continue;
847         }
848         if (rsigma>1.5) ampc/=1.3;  // if big backround
849         angular[i]    = TMath::Sqrt(1.+angley*angley+anglez*anglez);
850         amp[i]        = ampc/angular[i];
851         weight[i]     = w;
852         anc++;
853     }
854
855   TMath::Sort(159,amp,index,kFALSE);
856   for (Int_t i=int(anc*low+0.5);i<int(anc*up+0.5);i++){      
857     inlimit[index[i]] = kTRUE;  // take all clusters
858   }
859   
860   //  meanlog = amp[index[Int_t(anc*0.3)]];
861   meanlog =10000.;
862   for (Int_t of =0; of<3; of++){    
863     Float_t sumamp=0;
864     Float_t sumamp2=0;
865     Float_t sumw=0;    
866    for (Int_t i=indexde[of];i<indexde[of+1];i++)
867       {
868         if (inlimit[i]==kFALSE) continue;
869         Float_t ampl      = amp[i];
870         ///angular[i];
871         ampl              = meanlog*TMath::Log(1.+ampl/meanlog);
872         //
873         sumw    += weight[i]; 
874         sumamp  += weight[i]*ampl;
875         sumamp2 += weight[i]*ampl*ampl;
876         norm[of]    += angular[i]*weight[i];
877         nc[of]++;
878       }
879    if (sumw<1){ 
880      SetdEdx(0);  
881    }
882    else {
883      norm[of] /= sumw;
884      mean[of]  = sumamp/sumw;
885      sigma[of] = sumamp2/sumw-mean[of]*mean[of];
886      if (sigma[of]>0.1) 
887        sigma[of] = TMath::Sqrt(sigma[of]);
888      else
889        sigma[of] = 1000;      
890      mean[of] = (TMath::Exp(mean[of]/meanlog)-1)*meanlog;
891    }
892   }
893     
894   Float_t dedx =0;
895   fSdEdx =0;
896   fMAngular =0;
897   //
898   Int_t norm2 = 0;
899   Int_t norm3 = 0;
900   Float_t www[3] = {12.,14.,17.};
901   //Float_t www[3] = {1.,1.,1.};
902
903   for (Int_t i =0;i<3;i++){
904     if (nc[i]>2&&nc[i]<1000){
905       dedx      += mean[i] *nc[i]*www[i]/sigma[i];
906       fSdEdx    += sigma[i]*(nc[i]-2)*www[i]/sigma[i];
907       fMAngular += norm[i] *nc[i];    
908       norm2     += nc[i]*www[i]/sigma[i];
909       norm3     += (nc[i]-2)*www[i]/sigma[i];
910     }
911     fDEDX[i]  = mean[i];             
912     fSDEDX[i] = sigma[i];            
913     fNCDEDX[i]= nc[i]; 
914   }
915
916   if (norm3>0){
917     dedx   /=norm2;
918     fSdEdx /=norm3;
919     fMAngular/=norm2;
920   }
921   else{
922     SetdEdx(0);
923     return;
924   }
925   //  Float_t dedx1 =dedx;
926   
927   dedx =0;
928   Float_t norm4 = 0;
929   for (Int_t i =0;i<3;i++){
930     if (nc[i]>2&&nc[i]<1000&&sigma[i]>3){
931       //mean[i]   = mean[i]*(1+0.08*(sigma[i]/(fSdEdx)-1.));
932       dedx      += mean[i] *(nc[i])/(sigma[i]);
933       norm4     += (nc[i])/(sigma[i]);
934     }
935     fDEDX[i]  = mean[i];                
936   }
937   if (norm4>0) dedx /= norm4;
938   
939
940   
941   SetdEdx(dedx);
942     
943   //mi deDX
944
945 }
946 */
947 Double_t AliTPCseed::GetYat(Double_t xk) const {
948 //-----------------------------------------------------------------
949 // This function calculates the Y-coordinate of a track at the plane x=xk.
950 //-----------------------------------------------------------------
951   if (TMath::Abs(GetSnp())>AliTPCReconstructor::GetMaxSnpTrack()) return 0.; //patch 01 jan 06
952     Double_t c1=GetSnp(), r1=TMath::Sqrt(1.- c1*c1);
953     Double_t c2=c1+GetC()*(xk-GetX());
954     if (TMath::Abs(c2)>AliTPCReconstructor::GetMaxSnpTrack()) return 0;
955     Double_t r2=TMath::Sqrt(1.- c2*c2);
956     return GetY() + (xk-GetX())*(c1+c2)/(r1+r2);
957 }
958