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