]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCtracker.cxx
Forward declarations
[u/mrichter/AliRoot.git] / TPC / AliTPCtracker.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 $Log$
18 Revision 1.2  2000/06/30 12:07:50  kowal2
19 Updated from the TPC-PreRelease branch
20
21 Revision 1.1.2.1  2000/06/25 08:53:55  kowal2
22 Splitted from AliTPCtracking
23
24 */
25
26 //-------------------------------------------------------
27 //          Implementation of the TPC tracker
28 //
29 //   Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch 
30 //-------------------------------------------------------
31
32 #include "AliTPCtracker.h"
33 #include "AliTPCcluster.h"
34 #include <TObjArray.h>
35 #include <TFile.h>
36 #include "AliTPCClustersArray.h"
37 #include "AliTPCClustersRow.h"
38 #include <TTree.h>
39
40 const AliTPCParam *AliTPCtracker::AliTPCSector::fgParam;
41
42 //_____________________________________________________________________________
43 Double_t SigmaY2(Double_t r, Double_t tgl, Double_t pt)
44 {
45   //
46   // Parametrised error of the cluster reconstruction (pad direction)   
47   //
48   // Sigma rphi
49   const Float_t kArphi=0.41818e-2;
50   const Float_t kBrphi=0.17460e-4;
51   const Float_t kCrphi=0.30993e-2;
52   const Float_t kDrphi=0.41061e-3;
53   
54   pt=TMath::Abs(pt)*1000.;
55   Double_t x=r/pt;
56   tgl=TMath::Abs(tgl);
57   Double_t s=kArphi - kBrphi*r*tgl + kCrphi*x*x + kDrphi*x;
58   if (s<0.4e-3) s=0.4e-3;
59   s*=1.3; //Iouri Belikov
60
61   return s;
62 }
63
64 //_____________________________________________________________________________
65 Double_t SigmaZ2(Double_t r, Double_t tgl) 
66 {
67   //
68   // Parametrised error of the cluster reconstruction (drift direction)
69   //
70   // Sigma z
71   const Float_t kAz=0.39614e-2;
72   const Float_t kBz=0.22443e-4;
73   const Float_t kCz=0.51504e-1;
74   
75
76   tgl=TMath::Abs(tgl);
77   Double_t s=kAz - kBz*r*tgl + kCz*tgl*tgl;
78   if (s<0.4e-3) s=0.4e-3;
79   s*=1.3; //Iouri Belikov
80
81   return s;
82 }
83
84 //_____________________________________________________________________________
85 inline Double_t f1(Double_t x1,Double_t y1,
86                    Double_t x2,Double_t y2,
87                    Double_t x3,Double_t y3) 
88 {
89   //-----------------------------------------------------------------
90   // Initial approximation of the track curvature
91   //-----------------------------------------------------------------
92   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
93   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
94                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
95   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
96                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
97
98   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
99
100   return -xr*yr/sqrt(xr*xr+yr*yr); 
101 }
102
103
104 //_____________________________________________________________________________
105 inline Double_t f2(Double_t x1,Double_t y1,
106                    Double_t x2,Double_t y2,
107                    Double_t x3,Double_t y3) 
108 {
109   //-----------------------------------------------------------------
110   // Initial approximation of the track curvature times center of curvature
111   //-----------------------------------------------------------------
112   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
113   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
114                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
115   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
116                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
117
118   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
119   
120   return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
121 }
122
123 //_____________________________________________________________________________
124 inline Double_t f3(Double_t x1,Double_t y1, 
125                    Double_t x2,Double_t y2,
126                    Double_t z1,Double_t z2) 
127 {
128   //-----------------------------------------------------------------
129   // Initial approximation of the tangent of the track dip angle
130   //-----------------------------------------------------------------
131   return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
132 }
133
134 //_____________________________________________________________________________
135 Int_t AliTPCtracker::FindProlongation(AliTPCseed& t, const AliTPCSector *sec,
136 Int_t s, Int_t rf) 
137 {
138   //-----------------------------------------------------------------
139   // This function tries to find a track prolongation.
140   //-----------------------------------------------------------------
141   const Int_t kSKIP=(t.GetNumberOfClusters()<10) ? 
142                         10 : Int_t(0.5*sec->GetNRows());
143   Int_t tryAgain=kSKIP;
144   Double_t alpha=sec->GetAlpha();
145   Int_t ns=Int_t(2*TMath::Pi()/alpha+0.5);
146
147   for (Int_t nr=sec->GetRowNumber(t.GetX())-1; nr>=rf; nr--) {
148     Double_t x=sec->GetX(nr), ymax=sec->GetMaxY(nr);
149     if (!t.PropagateTo(x)) return 0;
150
151     AliTPCcluster *cl=0;
152     UInt_t index=0;
153     Double_t maxchi2=12.;
154     const AliTPCRow &krow=sec[s][nr];
155     Double_t sy2=SigmaY2(t.GetX(),t.GetTgl(),t.GetPt());
156     Double_t sz2=SigmaZ2(t.GetX(),t.GetTgl());
157     Double_t road=4.*sqrt(t.GetSigmaY2() + sy2), y=t.GetY(), z=t.GetZ();
158
159     if (road>30) {
160       if (t.GetNumberOfClusters()>4) 
161         cerr<<t.GetNumberOfClusters()
162         <<"FindProlongation warning: Too broad road !\n"; 
163       return 0;
164     }
165
166     if (krow) {
167       for (Int_t i=krow.Find(y-road); i<krow; i++) {
168         AliTPCcluster* c=(AliTPCcluster*)(krow[i]);
169         if (c->GetY() > y+road) break;
170         if (c->IsUsed()) continue;
171         if ((c->GetZ()-z)*(c->GetZ()-z) > 16.*(t.GetSigmaZ2()+sz2)) continue;
172         Double_t chi2=t.GetPredictedChi2(c);
173         if (chi2 > maxchi2) continue;
174         maxchi2=chi2;
175         cl=c;
176         index=krow.GetIndex(i);       
177       }
178     }
179     if (cl) {
180       Float_t l=sec->GetPadPitchWidth();
181       t.SetSampledEdx(cl->GetQ()/l,t.GetNumberOfClusters());
182       t.Update(cl,maxchi2,index);
183       tryAgain=kSKIP;
184     } else {
185       if (tryAgain==0) break;
186       if (y > ymax) {
187          s = (s+1) % ns;
188          if (!t.Rotate(alpha)) return 0;
189       } else if (y <-ymax) {
190          s = (s-1+ns) % ns;
191          if (!t.Rotate(-alpha)) return 0;
192       }
193       tryAgain--;
194     }
195   }
196
197   return 1;
198
199 }
200
201 //_____________________________________________________________________________
202 void 
203 AliTPCtracker::MakeSeeds(TObjArray& seeds,const AliTPCSector *sec, Int_t max,
204 Int_t i1, Int_t i2)
205 {
206   //-----------------------------------------------------------------
207   // This function creates track seeds.
208   //-----------------------------------------------------------------
209   Double_t x[5], c[15];
210
211   Double_t alpha=sec->GetAlpha(), shift=sec->GetAlphaShift();
212   Double_t cs=cos(alpha), sn=sin(alpha);
213
214   Double_t x1 =sec->GetX(i1);
215   Double_t xx2=sec->GetX(i2);
216
217   for (Int_t ns=0; ns<max; ns++) {
218     Int_t nl=sec[(ns-1+max)%max][i2];
219     Int_t nm=sec[ns][i2];
220     Int_t nu=sec[(ns+1)%max][i2];
221     const AliTPCRow& kr1=sec[ns][i1];
222     for (Int_t is=0; is < kr1; is++) {
223       Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
224       for (Int_t js=0; js < nl+nm+nu; js++) {
225         const AliTPCcluster *kcl;
226         Double_t x2,   y2,   z2;
227         Double_t x3=0.,y3=0.;
228
229         if (js<nl) {
230           const AliTPCRow& kr2=sec[(ns-1+max)%max][i2];
231           kcl=kr2[js];
232           y2=kcl->GetY(); z2=kcl->GetZ();
233           x2= xx2*cs+y2*sn;
234           y2=-xx2*sn+y2*cs;
235         } else 
236           if (js<nl+nm) {
237             const AliTPCRow& kr2=sec[ns][i2];
238             kcl=kr2[js-nl];
239             x2=xx2; y2=kcl->GetY(); z2=kcl->GetZ();
240           } else {
241             const AliTPCRow& kr2=sec[(ns+1)%max][i2];
242             kcl=kr2[js-nl-nm];
243             y2=kcl->GetY(); z2=kcl->GetZ();
244             x2=xx2*cs-y2*sn;
245             y2=xx2*sn+y2*cs;
246           }
247
248         Double_t zz=z1 - z1/x1*(x1-x2); 
249         if (TMath::Abs(zz-z2)>5.) continue;
250
251         Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
252         if (d==0.) {cerr<<"MakeSeeds warning: Straight seed !\n"; continue;}
253
254         x[0]=y1;
255         x[1]=z1;
256         x[2]=f1(x1,y1,x2,y2,x3,y3);
257         if (TMath::Abs(x[2]) >= 0.0066) continue;
258         x[3]=f2(x1,y1,x2,y2,x3,y3);
259         //if (TMath::Abs(x[2]*x1-x[3]) >= 0.99999) continue;
260         x[4]=f3(x1,y1,x2,y2,z1,z2);
261         if (TMath::Abs(x[4]) > 1.2) continue;
262         Double_t a=asin(x[3]);
263         Double_t zv=z1 - x[4]/x[2]*(a+asin(x[2]*x1-x[3]));
264         if (TMath::Abs(zv)>10.) continue; 
265
266         Double_t sy1=kr1[is]->GetSigmaY2(), sz1=kr1[is]->GetSigmaZ2();
267         Double_t sy2=kcl->GetSigmaY2(),     sz2=kcl->GetSigmaZ2();
268         Double_t sy3=100*0.025, sy=0.1, sz=0.1;
269
270         Double_t f20=(f1(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
271         Double_t f22=(f1(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
272         Double_t f24=(f1(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
273         Double_t f30=(f2(x1,y1+sy,x2,y2,x3,y3)-x[3])/sy;
274         Double_t f32=(f2(x1,y1,x2,y2+sy,x3,y3)-x[3])/sy;
275         Double_t f34=(f2(x1,y1,x2,y2,x3,y3+sy)-x[3])/sy;
276         Double_t f40=(f3(x1,y1+sy,x2,y2,z1,z2)-x[4])/sy;
277         Double_t f41=(f3(x1,y1,x2,y2,z1+sz,z2)-x[4])/sz;
278         Double_t f42=(f3(x1,y1,x2,y2+sy,z1,z2)-x[4])/sy;
279         Double_t f43=(f3(x1,y1,x2,y2,z1,z2+sz)-x[4])/sz;
280
281         c[0]=sy1;
282         c[1]=0.;       c[2]=sz1;
283         c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f24*sy3*f24;
284         c[6]=f30*sy1;  c[7]=0.;       c[8]=f30*sy1*f20+f32*sy2*f22+f34*sy3*f24;
285                                       c[9]=f30*sy1*f30+f32*sy2*f32+f34*sy3*f34;
286         c[10]=f40*sy1; c[11]=f41*sz1; c[12]=f40*sy1*f20+f42*sy2*f22;
287         c[13]=f40*sy1*f30+f42*sy2*f32;
288         c[14]=f40*sy1*f40+f41*sz1*f41+f42*sy2*f42+f43*sz2*f43;
289
290         UInt_t index=kr1.GetIndex(is);
291         AliTPCseed *track=new AliTPCseed(index, x, c, x1, ns*alpha+shift);
292         Float_t l=sec->GetPadPitchWidth();
293         track->SetSampledEdx(kr1[is]->GetQ()/l,0);
294
295         Int_t rc=FindProlongation(*track,sec,ns,i2);
296         if (rc<0 || track->GetNumberOfClusters()<(i1-i2)/2) delete track;
297         else seeds.AddLast(track); 
298       }
299     }
300   }
301 }
302
303 //_____________________________________________________________________________
304 void AliTPCtracker::Clusters2Tracks(const AliTPCParam *par, TFile *of) {
305   //-----------------------------------------------------------------
306   // This is a track finder.
307   //-----------------------------------------------------------------
308   TDirectory *savedir=gDirectory; 
309
310   if (!of->IsOpen()) {
311      cerr<<"AliTPC::Clusters2Tracks(): output file not open !\n";
312      return;
313   }
314
315   AliTPCClustersArray carray;
316   carray.Setup(par);
317   carray.SetClusterType("AliTPCcluster");
318   carray.ConnectTree("Segment Tree");
319
320   of->cd();
321   TTree tracktree("TreeT","Tree with TPC tracks");
322   AliTPCtrack *iotrack=0;
323   tracktree.Branch("tracks","AliTPCtrack",&iotrack,32000,0);
324
325   AliTPCSector::SetParam(par);
326
327   const Int_t kNIS=par->GetNInnerSector()/2;
328   AliTPCSSector *ssec=new AliTPCSSector[kNIS];         
329   Int_t nlow=ssec->GetNRows();     
330
331   const Int_t kNOS=par->GetNOuterSector()/2;
332   AliTPCLSector *lsec=new AliTPCLSector[kNOS];
333   Int_t nup=lsec->GetNRows();
334     
335   //Load outer sectors
336   UInt_t index;
337   Int_t i,j;
338
339   j=Int_t(carray.GetTree()->GetEntries());
340   for (i=0; i<j; i++) {
341       AliSegmentID *s=carray.LoadEntry(i);
342       Int_t sec,row;
343       par->AdjustSectorRow(s->GetID(),sec,row);
344       if (sec<kNIS*2) continue;
345       AliTPCClustersRow *clrow=carray.GetRow(sec,row);
346       Int_t ncl=clrow->GetArray()->GetEntriesFast();
347       while (ncl--) {
348          AliTPCcluster *c=(AliTPCcluster*)(*clrow)[ncl];
349          index=(((sec<<8)+row)<<16)+ncl;
350          lsec[(sec-kNIS*2)%kNOS][row].InsertCluster(c,index);
351       }
352   }
353
354   //find track seeds
355   TObjArray seeds(20000);
356   Int_t nrows=nlow+nup;
357   Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
358   MakeSeeds(seeds, lsec, kNOS, nup-1, nup-1-gap);
359   MakeSeeds(seeds, lsec, kNOS, nup-1-shift, nup-1-shift-gap);    
360   seeds.Sort();
361
362   //tracking in outer sectors
363   Int_t nseed=seeds.GetEntriesFast();
364   for (i=0; i<nseed; i++) {
365     AliTPCseed *pt=(AliTPCseed*)seeds.UncheckedAt(i), &t=*pt;
366     Double_t alpha=t.GetAlpha();
367     if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
368     if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
369     Int_t ns=Int_t(alpha/lsec->GetAlpha())%kNOS;
370
371     if (FindProlongation(t,lsec,ns)) {
372        t.UseClusters(&carray);
373        continue;
374     }
375     delete seeds.RemoveAt(i);
376   }  
377
378   //unload outer sectors
379   for (i=0; i<kNOS; i++) {
380       for (j=0; j<nup; j++) {
381           if (carray.GetRow(i+kNIS*2,j)) carray.ClearRow(i+kNIS*2,j);
382           if (carray.GetRow(i+kNIS*2+kNOS,j)) carray.ClearRow(i+kNIS*2+kNOS,j);
383       }
384   }
385
386   //load inner sectors
387   j=Int_t(carray.GetTree()->GetEntries());
388   for (i=0; i<j; i++) {
389       AliSegmentID *s=carray.LoadEntry(i);
390       Int_t sec,row;
391       par->AdjustSectorRow(s->GetID(),sec,row);
392       if (sec>=kNIS*2) continue;
393       AliTPCClustersRow *clrow=carray.GetRow(sec,row);
394       Int_t ncl=clrow->GetArray()->GetEntriesFast();
395       while (ncl--) {
396          AliTPCcluster *c=(AliTPCcluster*)(*clrow)[ncl];
397          index=(((sec<<8)+row)<<16)+ncl;
398          ssec[sec%kNIS][row].InsertCluster(c,index);
399       }
400   }
401
402   //tracking in inner sectors
403   Int_t found=0;
404   for (i=0; i<nseed; i++) {
405     AliTPCseed *pt=(AliTPCseed*)seeds.UncheckedAt(i), &t=*pt;
406     if (!pt) continue;
407     Int_t nc=t.GetNumberOfClusters();
408
409     Double_t alpha=t.GetAlpha() - ssec->GetAlphaShift();
410     if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
411     if (alpha < 0.            ) alpha += 2.*TMath::Pi();
412     Int_t ns=Int_t(alpha/ssec->GetAlpha())%kNIS;
413
414     alpha=ns*ssec->GetAlpha() + ssec->GetAlphaShift() - t.GetAlpha();
415
416     if (t.Rotate(alpha)) {
417        if (FindProlongation(t,ssec,ns)) {
418           if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
419              t.CookdEdx();
420              //t.CookLabel(&carray);
421              iotrack=pt;
422              tracktree.Fill();
423              t.UseClusters(&carray,nc);
424              cerr<<found++<<'\r';
425           }
426        }
427     }
428     delete seeds.RemoveAt(i); 
429   }  
430   tracktree.Write();
431
432   //unload inner sectors
433   for (i=0; i<kNIS; i++) {
434       for (j=0; j<nlow; j++) {
435           if (carray.GetRow(i,j)) carray.ClearRow(i,j);
436           if (carray.GetRow(i+kNIS,j)) carray.ClearRow(i+kNIS,j);
437       }
438   }
439
440   cerr<<"Number of found tracks : "<<found<<endl;
441
442   delete[] ssec;
443   delete[] lsec;
444
445   savedir->cd();
446 }
447
448 //_________________________________________________________________________
449 void 
450 AliTPCtracker::AliTPCRow::InsertCluster(const AliTPCcluster* c, UInt_t index) {
451   //-----------------------------------------------------------------------
452   // Insert a cluster into this pad row in accordence with its y-coordinate
453   //-----------------------------------------------------------------------
454   if (fN==kMAXCLUSTER) {
455     cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
456   }
457   if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
458   Int_t i=Find(c->GetY());
459   memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCcluster*));
460   memmove(fIndex   +i+1 ,fIndex   +i,(fN-i)*sizeof(UInt_t));
461   fIndex[i]=index; fClusters[i]=c; fN++;
462 }
463
464 //___________________________________________________________________
465 Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const {
466   //-----------------------------------------------------------------------
467   // Return the index of the nearest cluster 
468   //-----------------------------------------------------------------------
469   if (y <= fClusters[0]->GetY()) return 0;
470   if (y > fClusters[fN-1]->GetY()) return fN;
471   Int_t b=0, e=fN-1, m=(b+e)/2;
472   for (; b<e; m=(b+e)/2) {
473     if (y > fClusters[m]->GetY()) b=m+1;
474     else e=m; 
475   }
476   return m;
477 }
478
479 //_____________________________________________________________________________
480 void AliTPCtracker::AliTPCseed::CookdEdx(Double_t low, Double_t up) {
481   //-----------------------------------------------------------------
482   // This funtion calculates dE/dX within the "low" and "up" cuts.
483   //-----------------------------------------------------------------
484   Int_t i;
485
486   Int_t swap;//stupid sorting
487   do {
488     swap=0;
489     for (i=0; i<fN-1; i++) {
490       if (fdEdx[i]<=fdEdx[i+1]) continue;
491       Float_t tmp=fdEdx[i]; fdEdx[i]=fdEdx[i+1]; fdEdx[i+1]=tmp;
492       swap++;
493     }
494   } while (swap);
495
496   Int_t nl=Int_t(low*fN), nu=Int_t(up*fN);
497   Float_t dedx=0;
498   for (i=nl; i<=nu; i++) dedx += fdEdx[i];
499   dedx /= (nu-nl+1);
500   SetdEdx(dedx);
501 }
502
503 //_____________________________________________________________________________
504 void AliTPCtracker::AliTPCseed::UseClusters(AliTPCClustersArray *ca, Int_t n) {
505   //-----------------------------------------------------------------
506   // This function marks clusters associated with this track.
507   //-----------------------------------------------------------------
508   Int_t sec,row,ncl;
509   for (Int_t i=n; i<fN; i++) {
510      GetCluster(i,sec,row,ncl);
511      AliTPCClustersRow *clrow=ca->GetRow(sec,row);
512      AliTPCcluster *c=(AliTPCcluster*)(*clrow)[ncl]; 
513      c->Use();   
514   }
515 }
516
517