]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/AliTPCtracker.cxx
Minor changes (R.Barbera)
[u/mrichter/AliRoot.git] / TPC / AliTPCtracker.cxx
CommitLineData
73042f01 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$
3d39dd8b 18Revision 1.8 2001/05/08 15:00:15 hristov
19Corrections for tracking in arbitrary magnenetic field. Changes towards a concept of global Alice track. Back propagation of reconstructed tracks (Yu.Belikov)
20
be9c5115 21Revision 1.5 2000/12/20 07:51:59 kowal2
22Changes suggested by Alessandra and Paolo to avoid overlapped
23data fields in encapsulated classes.
24
d4cf1daa 25Revision 1.4 2000/11/02 07:27:16 kowal2
26code corrections
27
98ab53f4 28Revision 1.2 2000/06/30 12:07:50 kowal2
29Updated from the TPC-PreRelease branch
30
73042f01 31Revision 1.1.2.1 2000/06/25 08:53:55 kowal2
32Splitted from AliTPCtracking
33
34*/
35
36//-------------------------------------------------------
37// Implementation of the TPC tracker
38//
39// Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
40//-------------------------------------------------------
41
73042f01 42#include <TObjArray.h>
43#include <TFile.h>
be5b9287 44#include <TTree.h>
45#include <iostream.h>
46
47#include "AliTPCtracker.h"
48#include "AliTPCcluster.h"
b9de75e1 49#include "AliTPCParam.h"
73042f01 50#include "AliTPCClustersRow.h"
51
b9de75e1 52//_____________________________________________________________________________
53AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
54fkNIS(par->GetNInnerSector()/2),
55fkNOS(par->GetNOuterSector()/2)
56{
57 //---------------------------------------------------------------------
58 // The main TPC tracker constructor
59 //---------------------------------------------------------------------
60 fInnerSec=new AliTPCSector[fkNIS];
61 fOuterSec=new AliTPCSector[fkNOS];
62
63 Int_t i;
64 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
65 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
66
67 fN=0; fSectors=0;
68
69 fClustersArray.Setup(par);
70 fClustersArray.SetClusterType("AliTPCcluster");
71 fClustersArray.ConnectTree("Segment Tree");
72
73 fSeeds=0;
74}
75
76//_____________________________________________________________________________
77AliTPCtracker::~AliTPCtracker() {
78 //------------------------------------------------------------------
79 // TPC tracker destructor
80 //------------------------------------------------------------------
81 delete[] fInnerSec;
82 delete[] fOuterSec;
83 delete fSeeds;
84}
73042f01 85
86//_____________________________________________________________________________
87Double_t SigmaY2(Double_t r, Double_t tgl, Double_t pt)
88{
89 //
90 // Parametrised error of the cluster reconstruction (pad direction)
91 //
92 // Sigma rphi
93 const Float_t kArphi=0.41818e-2;
94 const Float_t kBrphi=0.17460e-4;
95 const Float_t kCrphi=0.30993e-2;
96 const Float_t kDrphi=0.41061e-3;
97
98 pt=TMath::Abs(pt)*1000.;
99 Double_t x=r/pt;
100 tgl=TMath::Abs(tgl);
101 Double_t s=kArphi - kBrphi*r*tgl + kCrphi*x*x + kDrphi*x;
102 if (s<0.4e-3) s=0.4e-3;
103 s*=1.3; //Iouri Belikov
104
105 return s;
106}
107
108//_____________________________________________________________________________
109Double_t SigmaZ2(Double_t r, Double_t tgl)
110{
111 //
112 // Parametrised error of the cluster reconstruction (drift direction)
113 //
114 // Sigma z
115 const Float_t kAz=0.39614e-2;
116 const Float_t kBz=0.22443e-4;
117 const Float_t kCz=0.51504e-1;
118
119
120 tgl=TMath::Abs(tgl);
121 Double_t s=kAz - kBz*r*tgl + kCz*tgl*tgl;
122 if (s<0.4e-3) s=0.4e-3;
123 s*=1.3; //Iouri Belikov
124
125 return s;
126}
127
128//_____________________________________________________________________________
129inline Double_t f1(Double_t x1,Double_t y1,
130 Double_t x2,Double_t y2,
131 Double_t x3,Double_t y3)
132{
133 //-----------------------------------------------------------------
134 // Initial approximation of the track curvature
135 //-----------------------------------------------------------------
136 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
137 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
138 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
139 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
140 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
141
142 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
143
144 return -xr*yr/sqrt(xr*xr+yr*yr);
145}
146
147
148//_____________________________________________________________________________
149inline Double_t f2(Double_t x1,Double_t y1,
150 Double_t x2,Double_t y2,
151 Double_t x3,Double_t y3)
152{
153 //-----------------------------------------------------------------
154 // Initial approximation of the track curvature times center of curvature
155 //-----------------------------------------------------------------
156 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
157 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
158 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
159 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
160 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
161
162 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
163
164 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
165}
166
167//_____________________________________________________________________________
168inline Double_t f3(Double_t x1,Double_t y1,
169 Double_t x2,Double_t y2,
170 Double_t z1,Double_t z2)
171{
172 //-----------------------------------------------------------------
173 // Initial approximation of the tangent of the track dip angle
174 //-----------------------------------------------------------------
175 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
176}
177
178//_____________________________________________________________________________
b9de75e1 179void AliTPCtracker::LoadOuterSectors() {
180 //-----------------------------------------------------------------
181 // This function fills outer TPC sectors with clusters.
182 //-----------------------------------------------------------------
183 UInt_t index;
184 Int_t j=Int_t(fClustersArray.GetTree()->GetEntries());
185 for (Int_t i=0; i<j; i++) {
186 AliSegmentID *s=fClustersArray.LoadEntry(i);
187 Int_t sec,row;
188 AliTPCParam *par=(AliTPCParam*)fClustersArray.GetParam();
189 par->AdjustSectorRow(s->GetID(),sec,row);
190 if (sec<fkNIS*2) continue;
191 AliTPCClustersRow *clrow=fClustersArray.GetRow(sec,row);
192 Int_t ncl=clrow->GetArray()->GetEntriesFast();
193 while (ncl--) {
194 AliTPCcluster *c=(AliTPCcluster*)(*clrow)[ncl];
195 index=(((sec<<8)+row)<<16)+ncl;
196 fOuterSec[(sec-fkNIS*2)%fkNOS][row].InsertCluster(c,index);
197 }
198 }
199
200 fN=fkNOS;
201 fSectors=fOuterSec;
202}
203
204//_____________________________________________________________________________
205void AliTPCtracker::UnloadOuterSectors() {
206 //-----------------------------------------------------------------
207 // This function clears outer TPC sectors.
208 //-----------------------------------------------------------------
209 Int_t nup=fOuterSec->GetNRows();
210 for (Int_t i=0; i<fkNOS; i++) {
211 for (Int_t j=0; j<nup; j++) {
212 if (fClustersArray.GetRow(i+fkNIS*2,j))
213 fClustersArray.ClearRow(i+fkNIS*2,j);
214 if (fClustersArray.GetRow(i+fkNIS*2+fkNOS,j))
215 fClustersArray.ClearRow(i+fkNIS*2+fkNOS,j);
216 }
217 }
218
219 fN=0;
220 fSectors=0;
221}
222
223//_____________________________________________________________________________
224void AliTPCtracker::LoadInnerSectors() {
225 //-----------------------------------------------------------------
226 // This function fills inner TPC sectors with clusters.
227 //-----------------------------------------------------------------
228 UInt_t index;
229 Int_t j=Int_t(fClustersArray.GetTree()->GetEntries());
230 for (Int_t i=0; i<j; i++) {
231 AliSegmentID *s=fClustersArray.LoadEntry(i);
232 Int_t sec,row;
233 AliTPCParam *par=(AliTPCParam*)fClustersArray.GetParam();
234 par->AdjustSectorRow(s->GetID(),sec,row);
235 if (sec>=fkNIS*2) continue;
236 AliTPCClustersRow *clrow=fClustersArray.GetRow(sec,row);
237 Int_t ncl=clrow->GetArray()->GetEntriesFast();
238 while (ncl--) {
239 AliTPCcluster *c=(AliTPCcluster*)(*clrow)[ncl];
240 index=(((sec<<8)+row)<<16)+ncl;
241 fInnerSec[sec%fkNIS][row].InsertCluster(c,index);
242 }
243 }
244
245 fN=fkNIS;
246 fSectors=fInnerSec;
247}
248
249//_____________________________________________________________________________
250void AliTPCtracker::UnloadInnerSectors() {
251 //-----------------------------------------------------------------
252 // This function clears inner TPC sectors.
253 //-----------------------------------------------------------------
254 Int_t nlow=fInnerSec->GetNRows();
255 for (Int_t i=0; i<fkNIS; i++) {
256 for (Int_t j=0; j<nlow; j++) {
257 if (fClustersArray.GetRow(i,j)) fClustersArray.ClearRow(i,j);
258 if (fClustersArray.GetRow(i+fkNIS,j)) fClustersArray.ClearRow(i+fkNIS,j);
259 }
260 }
261
262 fN=0;
263 fSectors=0;
264}
265
266//_____________________________________________________________________________
267Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) {
73042f01 268 //-----------------------------------------------------------------
269 // This function tries to find a track prolongation.
270 //-----------------------------------------------------------------
b9de75e1 271 Double_t xt=t.GetX();
272 const Int_t kSKIP=(t.GetNumberOfClusters()<10) ? kRowsToSkip :
273 Int_t(0.5*fSectors->GetNRows());
73042f01 274 Int_t tryAgain=kSKIP;
73042f01 275
b9de75e1 276 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
277 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
278 if (alpha < 0. ) alpha += 2.*TMath::Pi();
279 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
280
281 for (Int_t nr=fSectors->GetRowNumber(xt)-1; nr>=rf; nr--) {
282 Double_t x=fSectors->GetX(nr), ymax=fSectors->GetMaxY(nr);
73042f01 283 if (!t.PropagateTo(x)) return 0;
284
285 AliTPCcluster *cl=0;
286 UInt_t index=0;
b9de75e1 287 Double_t maxchi2=kMaxCHI2;
288 const AliTPCRow &krow=fSectors[s][nr];
289 Double_t pt=t.GetConvConst()/(100/0.299792458/0.2)/t.Get1Pt();
290 Double_t sy2=SigmaY2(t.GetX(),t.GetTgl(),pt);
73042f01 291 Double_t sz2=SigmaZ2(t.GetX(),t.GetTgl());
292 Double_t road=4.*sqrt(t.GetSigmaY2() + sy2), y=t.GetY(), z=t.GetZ();
293
b9de75e1 294 if (road>kMaxROAD) {
73042f01 295 if (t.GetNumberOfClusters()>4)
296 cerr<<t.GetNumberOfClusters()
297 <<"FindProlongation warning: Too broad road !\n";
298 return 0;
299 }
300
301 if (krow) {
302 for (Int_t i=krow.Find(y-road); i<krow; i++) {
be5b9287 303 AliTPCcluster *c=(AliTPCcluster*)(krow[i]);
73042f01 304 if (c->GetY() > y+road) break;
305 if (c->IsUsed()) continue;
306 if ((c->GetZ()-z)*(c->GetZ()-z) > 16.*(t.GetSigmaZ2()+sz2)) continue;
307 Double_t chi2=t.GetPredictedChi2(c);
308 if (chi2 > maxchi2) continue;
309 maxchi2=chi2;
310 cl=c;
311 index=krow.GetIndex(i);
312 }
313 }
314 if (cl) {
b9de75e1 315 Float_t l=fSectors->GetPadPitchWidth();
73042f01 316 t.SetSampledEdx(cl->GetQ()/l,t.GetNumberOfClusters());
be9c5115 317 if (!t.Update(cl,maxchi2,index)) {
318 if (!tryAgain--) return 0;
319 } else tryAgain=kSKIP;
73042f01 320 } else {
321 if (tryAgain==0) break;
322 if (y > ymax) {
b9de75e1 323 s = (s+1) % fN;
324 if (!t.Rotate(fSectors->GetAlpha())) return 0;
73042f01 325 } else if (y <-ymax) {
b9de75e1 326 s = (s-1+fN) % fN;
327 if (!t.Rotate(-fSectors->GetAlpha())) return 0;
73042f01 328 }
329 tryAgain--;
330 }
331 }
332
333 return 1;
b9de75e1 334}
335
336//_____________________________________________________________________________
337Int_t AliTPCtracker::FollowBackProlongation
338(AliTPCseed& seed, const AliTPCtrack &track) {
339 //-----------------------------------------------------------------
340 // This function propagates tracks back through the TPC
341 //-----------------------------------------------------------------
342 Double_t alpha=seed.GetAlpha() - fSectors->GetAlphaShift();
343 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
344 if (alpha < 0. ) alpha += 2.*TMath::Pi();
345 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
346
347 Int_t idx=-1, sec=-1, row=-1;
348 Int_t nc=seed.GetLabel(); //index of the cluster to start with
349 if (nc--) {
350 idx=track.GetClusterIndex(nc);
351 sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
352 }
353 if (fSectors==fInnerSec) { if (sec >= 2*fkNIS) row=-1; }
354 else { if (sec < 2*fkNIS) row=-1; }
355
356 Int_t nr=fSectors->GetNRows();
357 for (Int_t i=0; i<nr; i++) {
358 Double_t x=fSectors->GetX(i), ymax=fSectors->GetMaxY(i);
359
360 if (!seed.PropagateTo(x)) return 0;
361
362 Double_t y=seed.GetY();
363 if (y > ymax) {
364 s = (s+1) % fN;
365 if (!seed.Rotate(fSectors->GetAlpha())) return 0;
366 } else if (y <-ymax) {
367 s = (s-1+fN) % fN;
368 if (!seed.Rotate(-fSectors->GetAlpha())) return 0;
369 }
370
371 AliTPCcluster *cl=0;
372 Int_t index=0;
373 Double_t maxchi2=kMaxCHI2;
374 Double_t pt=seed.GetConvConst()/(100/0.299792458/0.2)/seed.Get1Pt();
375 Double_t sy2=SigmaY2(seed.GetX(),seed.GetTgl(),pt);
376 Double_t sz2=SigmaZ2(seed.GetX(),seed.GetTgl());
377 Double_t road=4.*sqrt(seed.GetSigmaY2() + sy2), z=seed.GetZ();
378 if (road>kMaxROAD) {
379 cerr<<seed.GetNumberOfClusters()
380 <<"AliTPCtracker::FollowBackProlongation: Too broad road !\n";
381 return 0;
382 }
383
384
385 Int_t accepted=seed.GetNumberOfClusters();
386 if (row==i) {
387 //try to accept already found cluster
388 AliTPCcluster *c=(AliTPCcluster*)GetCluster(idx);
389 Double_t chi2;
390 if ((chi2=seed.GetPredictedChi2(c))<maxchi2 || accepted<27) {
391 index=idx; cl=c; maxchi2=chi2;
392 } //else cerr<<"AliTPCtracker::FollowBackProlongation: oulier !\n";
393
394 if (nc--) {
395 idx=track.GetClusterIndex(nc);
396 sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
397 }
398 if (fSectors==fInnerSec) { if (sec >= 2*fkNIS) row=-1; }
399 else { if (sec < 2*fkNIS) row=-1; }
73042f01 400
b9de75e1 401 }
402 if (!cl) {
403 //try to fill the gap
404 const AliTPCRow &krow=fSectors[s][i];
405 if (accepted>27)
406 if (krow) {
407 for (Int_t i=krow.Find(y-road); i<krow; i++) {
408 AliTPCcluster *c=(AliTPCcluster*)(krow[i]);
409 if (c->GetY() > y+road) break;
410 if (c->IsUsed()) continue;
411 if ((c->GetZ()-z)*(c->GetZ()-z)>16.*(seed.GetSigmaZ2()+sz2)) continue;
412 Double_t chi2=seed.GetPredictedChi2(c);
413 if (chi2 > maxchi2) continue;
414 maxchi2=chi2;
415 cl=c;
416 index=krow.GetIndex(i);
417 }
418 }
419 }
420
421 if (cl) {
422 Float_t l=fSectors->GetPadPitchWidth();
423 seed.SetSampledEdx(cl->GetQ()/l,seed.GetNumberOfClusters());
424 seed.Update(cl,maxchi2,index);
425 }
426
427 }
428
429 seed.SetLabel(nc);
430
431 return 1;
73042f01 432}
433
434//_____________________________________________________________________________
b9de75e1 435void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) {
73042f01 436 //-----------------------------------------------------------------
437 // This function creates track seeds.
438 //-----------------------------------------------------------------
b9de75e1 439 if (fSeeds==0) fSeeds=new TObjArray(15000);
440
73042f01 441 Double_t x[5], c[15];
442
b9de75e1 443 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
73042f01 444 Double_t cs=cos(alpha), sn=sin(alpha);
445
b9de75e1 446 Double_t x1 =fOuterSec->GetX(i1);
447 Double_t xx2=fOuterSec->GetX(i2);
73042f01 448
b9de75e1 449 for (Int_t ns=0; ns<fkNOS; ns++) {
450 Int_t nl=fOuterSec[(ns-1+fkNOS)%fkNOS][i2];
451 Int_t nm=fOuterSec[ns][i2];
452 Int_t nu=fOuterSec[(ns+1)%fkNOS][i2];
453 const AliTPCRow& kr1=fOuterSec[ns][i1];
73042f01 454 for (Int_t is=0; is < kr1; is++) {
455 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
456 for (Int_t js=0; js < nl+nm+nu; js++) {
457 const AliTPCcluster *kcl;
458 Double_t x2, y2, z2;
459 Double_t x3=0.,y3=0.;
460
461 if (js<nl) {
b9de75e1 462 const AliTPCRow& kr2=fOuterSec[(ns-1+fkNOS)%fkNOS][i2];
73042f01 463 kcl=kr2[js];
464 y2=kcl->GetY(); z2=kcl->GetZ();
465 x2= xx2*cs+y2*sn;
466 y2=-xx2*sn+y2*cs;
467 } else
468 if (js<nl+nm) {
b9de75e1 469 const AliTPCRow& kr2=fOuterSec[ns][i2];
73042f01 470 kcl=kr2[js-nl];
471 x2=xx2; y2=kcl->GetY(); z2=kcl->GetZ();
472 } else {
b9de75e1 473 const AliTPCRow& kr2=fOuterSec[(ns+1)%fkNOS][i2];
73042f01 474 kcl=kr2[js-nl-nm];
475 y2=kcl->GetY(); z2=kcl->GetZ();
476 x2=xx2*cs-y2*sn;
477 y2=xx2*sn+y2*cs;
478 }
479
480 Double_t zz=z1 - z1/x1*(x1-x2);
481 if (TMath::Abs(zz-z2)>5.) continue;
482
483 Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
484 if (d==0.) {cerr<<"MakeSeeds warning: Straight seed !\n"; continue;}
485
486 x[0]=y1;
487 x[1]=z1;
b9de75e1 488 x[4]=f1(x1,y1,x2,y2,x3,y3);
489 if (TMath::Abs(x[4]) >= 0.0066) continue;
be5b9287 490 x[2]=f2(x1,y1,x2,y2,x3,y3);
b9de75e1 491 //if (TMath::Abs(x[4]*x1-x[2]) >= 0.99999) continue;
492 x[3]=f3(x1,y1,x2,y2,z1,z2);
493 if (TMath::Abs(x[3]) > 1.2) continue;
be5b9287 494 Double_t a=asin(x[2]);
b9de75e1 495 Double_t zv=z1 - x[3]/x[4]*(a+asin(x[4]*x1-x[2]));
73042f01 496 if (TMath::Abs(zv)>10.) continue;
497
498 Double_t sy1=kr1[is]->GetSigmaY2(), sz1=kr1[is]->GetSigmaZ2();
499 Double_t sy2=kcl->GetSigmaY2(), sz2=kcl->GetSigmaZ2();
500 Double_t sy3=100*0.025, sy=0.1, sz=0.1;
501
b9de75e1 502 Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
503 Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
504 Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
be5b9287 505 Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
506 Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
b9de75e1 507 Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
508 Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
509 Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
510 Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
511 Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
73042f01 512
513 c[0]=sy1;
514 c[1]=0.; c[2]=sz1;
b9de75e1 515 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
516 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
517 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
518 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
519 c[13]=f30*sy1*f40+f32*sy2*f42;
520 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
73042f01 521
522 UInt_t index=kr1.GetIndex(is);
523 AliTPCseed *track=new AliTPCseed(index, x, c, x1, ns*alpha+shift);
b9de75e1 524 Float_t l=fOuterSec->GetPadPitchWidth();
73042f01 525 track->SetSampledEdx(kr1[is]->GetQ()/l,0);
526
b9de75e1 527 Int_t rc=FollowProlongation(*track, i2);
be9c5115 528 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)/2) delete track;
b9de75e1 529 else fSeeds->AddLast(track);
73042f01 530 }
531 }
532 }
533}
534
535//_____________________________________________________________________________
b9de75e1 536Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
73042f01 537 //-----------------------------------------------------------------
b9de75e1 538 // This function reades track seeds.
73042f01 539 //-----------------------------------------------------------------
540 TDirectory *savedir=gDirectory;
541
b9de75e1 542 TFile *in=(TFile*)inp;
543 if (!in->IsOpen()) {
544 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
be5b9287 545 return 1;
73042f01 546 }
547
b9de75e1 548 in->cd();
549 TTree *seedTree=(TTree*)in->Get("Seeds");
550 if (!seedTree) {
551 cerr<<"AliTPCtracker::ReadSeeds(): ";
552 cerr<<"can't get a tree with track seeds !\n";
553 return 2;
554 }
555 AliTPCtrack *seed=new AliTPCtrack;
556 seedTree->SetBranchAddress("tracks",&seed);
557
558 if (fSeeds==0) fSeeds=new TObjArray(15000);
73042f01 559
b9de75e1 560 Int_t n=(Int_t)seedTree->GetEntries();
561 for (Int_t i=0; i<n; i++) {
562 seedTree->GetEvent(i);
563 fSeeds->AddLast(new AliTPCseed(*seed,seed->GetAlpha()));
564 }
565
566 delete seed;
567 savedir->cd();
73042f01 568
b9de75e1 569 return 0;
570}
73042f01 571
b9de75e1 572//_____________________________________________________________________________
573Int_t AliTPCtracker::Clusters2Tracks(const TFile *inp, TFile *out) {
574 //-----------------------------------------------------------------
575 // This is a track finder.
576 //-----------------------------------------------------------------
577 TDirectory *savedir=gDirectory;
73042f01 578
b9de75e1 579 if (inp) {
580 TFile *in=(TFile*)inp;
581 if (!in->IsOpen()) {
582 cerr<<"AliTPCtracker::Clusters2Tracks(): input file is not open !\n";
583 return 1;
584 }
585 }
73042f01 586
b9de75e1 587 if (!out->IsOpen()) {
588 cerr<<"AliTPCtracker::Clusters2Tracks(): output file is not open !\n";
589 return 2;
73042f01 590 }
591
b9de75e1 592 out->cd();
593 TTree tracktree("TPCf","Tree with TPC tracks");
594 AliTPCtrack *iotrack=0;
595 tracktree.Branch("tracks","AliTPCtrack",&iotrack,32000,0);
596
597 LoadOuterSectors();
598
73042f01 599 //find track seeds
b9de75e1 600 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
73042f01 601 Int_t nrows=nlow+nup;
b9de75e1 602 if (fSeeds==0) {
603 Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
604 MakeSeeds(nup-1, nup-1-gap);
605 MakeSeeds(nup-1-shift, nup-1-shift-gap);
606 }
607 fSeeds->Sort();
73042f01 608
609 //tracking in outer sectors
b9de75e1 610 Int_t nseed=fSeeds->GetEntriesFast();
611 Int_t i;
73042f01 612 for (i=0; i<nseed; i++) {
b9de75e1 613 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
614 if (FollowProlongation(t)) {
615 UseClusters(&t);
73042f01 616 continue;
617 }
b9de75e1 618 delete fSeeds->RemoveAt(i);
73042f01 619 }
b9de75e1 620 UnloadOuterSectors();
73042f01 621
622 //tracking in inner sectors
b9de75e1 623 LoadInnerSectors();
73042f01 624 Int_t found=0;
625 for (i=0; i<nseed; i++) {
b9de75e1 626 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
73042f01 627 if (!pt) continue;
628 Int_t nc=t.GetNumberOfClusters();
629
b9de75e1 630 Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift();
73042f01 631 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
632 if (alpha < 0. ) alpha += 2.*TMath::Pi();
b9de75e1 633 Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS;
73042f01 634
b9de75e1 635 alpha=ns*fInnerSec->GetAlpha() + fInnerSec->GetAlphaShift() - t.GetAlpha();
73042f01 636
637 if (t.Rotate(alpha)) {
b9de75e1 638 if (FollowProlongation(t)) {
73042f01 639 if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
640 t.CookdEdx();
73042f01 641 iotrack=pt;
642 tracktree.Fill();
b9de75e1 643 UseClusters(&t,nc);
644 cerr<<found++<<'\r';
73042f01 645 }
646 }
647 }
b9de75e1 648 delete fSeeds->RemoveAt(i);
73042f01 649 }
b9de75e1 650 UnloadInnerSectors();
651
73042f01 652 tracktree.Write();
653
b9de75e1 654 cerr<<"Number of found tracks : "<<found<<endl;
655
656 savedir->cd();
657
658 return 0;
659}
660
661//_____________________________________________________________________________
662Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
663 //-----------------------------------------------------------------
664 // This function propagates tracks back through the TPC.
665 //-----------------------------------------------------------------
666 fSeeds=new TObjArray(15000);
667
668 TFile *in=(TFile*)inp;
669 TDirectory *savedir=gDirectory;
670
671 if (!in->IsOpen()) {
672 cerr<<"AliTPCtracker::PropagateBack(): ";
673 cerr<<"file with back propagated ITS tracks is not open !\n";
674 return 1;
73042f01 675 }
676
b9de75e1 677 if (!out->IsOpen()) {
678 cerr<<"AliTPCtracker::PropagateBack(): ";
679 cerr<<"file for back propagated TPC tracks is not open !\n";
680 return 2;
681 }
682
683 in->cd();
684 TTree *bckTree=(TTree*)in->Get("ITSb");
685 if (!bckTree) {
686 cerr<<"AliTPCtracker::PropagateBack() ";
687 cerr<<"can't get a tree with back propagated ITS tracks !\n";
688 return 3;
689 }
690 AliTPCtrack *bckTrack=new AliTPCtrack;
691 bckTree->SetBranchAddress("tracks",&bckTrack);
692
693 TTree *tpcTree=(TTree*)in->Get("TPCf");
694 if (!tpcTree) {
695 cerr<<"AliTPCtracker::PropagateBack() ";
696 cerr<<"can't get a tree with TPC tracks !\n";
697 return 4;
698 }
699 AliTPCtrack *tpcTrack=new AliTPCtrack;
700 tpcTree->SetBranchAddress("tracks",&tpcTrack);
701
702//*** Prepare an array of tracks to be back propagated
703 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
704 Int_t nrows=nlow+nup;
705
706 TObjArray tracks(15000);
707 Int_t i=0,j=0;
708 Int_t tpcN=(Int_t)tpcTree->GetEntries();
709 Int_t bckN=(Int_t)bckTree->GetEntries();
710 if (j<bckN) bckTree->GetEvent(j++);
711 for (i=0; i<tpcN; i++) {
712 tpcTree->GetEvent(i);
713 Double_t alpha=tpcTrack->GetAlpha();
714 if (j<bckN &&
715 TMath::Abs(tpcTrack->GetLabel())==TMath::Abs(bckTrack->GetLabel())) {
716 if (!bckTrack->Rotate(alpha-bckTrack->GetAlpha())) continue;
717 fSeeds->AddLast(new AliTPCseed(*bckTrack,bckTrack->GetAlpha()));
718 bckTree->GetEvent(j++);
719 } else {
720 tpcTrack->ResetCovariance();
721 fSeeds->AddLast(new AliTPCseed(*tpcTrack,alpha));
722 }
723 tracks.AddLast(new AliTPCtrack(*tpcTrack));
724 }
725
726 out->cd();
727 TTree backTree("TPCb","Tree with back propagated TPC tracks");
728 AliTPCtrack *otrack=0;
729 backTree.Branch("tracks","AliTPCtrack",&otrack,32000,0);
730
731//*** Back propagation through inner sectors
732 LoadInnerSectors();
733 Int_t nseed=fSeeds->GetEntriesFast();
734 for (i=0; i<nseed; i++) {
735 AliTPCseed *ps=(AliTPCseed*)fSeeds->UncheckedAt(i), &s=*ps;
736 const AliTPCtrack *pt=(AliTPCtrack*)tracks.UncheckedAt(i), &t=*pt;
73042f01 737
b9de75e1 738 Int_t nc=t.GetNumberOfClusters();
739 s.SetLabel(nc-1); //set number of the cluster to start with
73042f01 740
b9de75e1 741 if (FollowBackProlongation(s,t)) {
742 UseClusters(&s);
743 continue;
744 }
745 delete fSeeds->RemoveAt(i);
746 }
747 UnloadInnerSectors();
748
749//*** Back propagation through outer sectors
750 LoadOuterSectors();
751 Int_t found=0;
752 for (i=0; i<nseed; i++) {
753 AliTPCseed *ps=(AliTPCseed*)fSeeds->UncheckedAt(i), &s=*ps;
754 if (!ps) continue;
755 Int_t nc=s.GetNumberOfClusters();
756 const AliTPCtrack *pt=(AliTPCtrack*)tracks.UncheckedAt(i), &t=*pt;
757
758 Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift();
759 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
760 if (alpha < 0. ) alpha += 2.*TMath::Pi();
761 Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
762
763 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
764 alpha-=s.GetAlpha();
765
766 if (s.Rotate(alpha)) {
767 if (FollowBackProlongation(s,t)) {
768 if (s.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
769 s.CookdEdx();
770 s.SetLabel(t.GetLabel());
771 UseClusters(&s,nc);
772 otrack=ps;
773 backTree.Fill();
774 cerr<<found++<<'\r';
775 continue;
776 }
777 }
778 }
779 delete fSeeds->RemoveAt(i);
780 }
781 UnloadOuterSectors();
782
783 backTree.Write();
73042f01 784 savedir->cd();
b9de75e1 785 cerr<<"Number of seeds: "<<nseed<<endl;
786 cerr<<"Number of back propagated ITS tracks: "<<bckN<<endl;
787 cerr<<"Number of back propagated TPC tracks: "<<found<<endl;
788
789 delete bckTrack;
790 delete tpcTrack;
be5b9287 791
792 return 0;
73042f01 793}
794
b9de75e1 795//_________________________________________________________________________
796AliCluster *AliTPCtracker::GetCluster(Int_t index) const {
797 //--------------------------------------------------------------------
798 // Return pointer to a given cluster
799 //--------------------------------------------------------------------
800 Int_t sec=(index&0xff000000)>>24;
801 Int_t row=(index&0x00ff0000)>>16;
802 Int_t ncl=(index&0x0000ffff)>>00;
803
3d39dd8b 804 AliTPCClustersRow *clrow=((AliTPCtracker*)this)->fClustersArray.GetRow(sec,row);;
b9de75e1 805 return (AliCluster*)(*clrow)[ncl];
806}
807
808//__________________________________________________________________________
809void AliTPCtracker::CookLabel(AliKalmanTrack *t, Float_t wrong) const {
810 //--------------------------------------------------------------------
811 //This function "cooks" a track label. If label<0, this track is fake.
812 //--------------------------------------------------------------------
813 Int_t noc=t->GetNumberOfClusters();
814 Int_t *lb=new Int_t[noc];
815 Int_t *mx=new Int_t[noc];
816 AliCluster **clusters=new AliCluster*[noc];
817
818 Int_t i;
819 for (i=0; i<noc; i++) {
820 lb[i]=mx[i]=0;
821 Int_t index=t->GetClusterIndex(i);
822 clusters[i]=GetCluster(index);
823 }
824
825 Int_t lab=123456789;
826 for (i=0; i<noc; i++) {
827 AliCluster *c=clusters[i];
828 lab=TMath::Abs(c->GetLabel(0));
829 Int_t j;
830 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
831 lb[j]=lab;
832 (mx[j])++;
833 }
834
835 Int_t max=0;
836 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
837
838 for (i=0; i<noc; i++) {
839 AliCluster *c=clusters[i];
840 if (TMath::Abs(c->GetLabel(1)) == lab ||
841 TMath::Abs(c->GetLabel(2)) == lab ) max++;
842 }
843
844 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
845
846 else {
847 Int_t tail=Int_t(0.10*noc);
848 max=0;
849 for (i=1; i<=tail; i++) {
850 AliCluster *c=clusters[noc-i];
851 if (lab == TMath::Abs(c->GetLabel(0)) ||
852 lab == TMath::Abs(c->GetLabel(1)) ||
853 lab == TMath::Abs(c->GetLabel(2))) max++;
854 }
855 if (max < Int_t(0.5*tail)) lab=-lab;
856 }
857
858 t->SetLabel(lab);
859
860 delete[] lb;
861 delete[] mx;
862 delete[] clusters;
863}
864
865//_________________________________________________________________________
866void AliTPCtracker::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
867 //-----------------------------------------------------------------------
868 // Setup inner sector
869 //-----------------------------------------------------------------------
870 if (f==0) {
871 fAlpha=par->GetInnerAngle();
872 fAlphaShift=par->GetInnerAngleShift();
873 fPadPitchWidth=par->GetInnerPadPitchWidth();
874 fPadPitchLength=par->GetInnerPadPitchLength();
875
876 fN=par->GetNRowLow();
877 fRow=new AliTPCRow[fN];
878 for (Int_t i=0; i<fN; i++) fRow[i].SetX(par->GetPadRowRadiiLow(i));
879 } else {
880 fAlpha=par->GetOuterAngle();
881 fAlphaShift=par->GetOuterAngleShift();
882 fPadPitchWidth=par->GetOuterPadPitchWidth();
883 fPadPitchLength=par->GetOuterPadPitchLength();
884
885 fN=par->GetNRowUp();
886 fRow=new AliTPCRow[fN];
887 for (Int_t i=0; i<fN; i++) fRow[i].SetX(par->GetPadRowRadiiUp(i));
888 }
889}
890
73042f01 891//_________________________________________________________________________
892void
893AliTPCtracker::AliTPCRow::InsertCluster(const AliTPCcluster* c, UInt_t index) {
894 //-----------------------------------------------------------------------
895 // Insert a cluster into this pad row in accordence with its y-coordinate
896 //-----------------------------------------------------------------------
b9de75e1 897 if (fN==kMaxClusterPerRow) {
73042f01 898 cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
899 }
900 if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
901 Int_t i=Find(c->GetY());
902 memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCcluster*));
903 memmove(fIndex +i+1 ,fIndex +i,(fN-i)*sizeof(UInt_t));
904 fIndex[i]=index; fClusters[i]=c; fN++;
905}
906
907//___________________________________________________________________
908Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const {
909 //-----------------------------------------------------------------------
910 // Return the index of the nearest cluster
911 //-----------------------------------------------------------------------
912 if (y <= fClusters[0]->GetY()) return 0;
913 if (y > fClusters[fN-1]->GetY()) return fN;
914 Int_t b=0, e=fN-1, m=(b+e)/2;
915 for (; b<e; m=(b+e)/2) {
916 if (y > fClusters[m]->GetY()) b=m+1;
917 else e=m;
918 }
919 return m;
920}
921
922//_____________________________________________________________________________
923void AliTPCtracker::AliTPCseed::CookdEdx(Double_t low, Double_t up) {
924 //-----------------------------------------------------------------
925 // This funtion calculates dE/dX within the "low" and "up" cuts.
926 //-----------------------------------------------------------------
927 Int_t i;
be9c5115 928 Int_t nc=GetNumberOfClusters();
73042f01 929
930 Int_t swap;//stupid sorting
931 do {
932 swap=0;
be9c5115 933 for (i=0; i<nc-1; i++) {
d4cf1daa 934 if (fdEdxSample[i]<=fdEdxSample[i+1]) continue;
935 Float_t tmp=fdEdxSample[i];
936 fdEdxSample[i]=fdEdxSample[i+1]; fdEdxSample[i+1]=tmp;
73042f01 937 swap++;
938 }
939 } while (swap);
940
be9c5115 941 Int_t nl=Int_t(low*nc), nu=Int_t(up*nc);
73042f01 942 Float_t dedx=0;
d4cf1daa 943 for (i=nl; i<=nu; i++) dedx += fdEdxSample[i];
73042f01 944 dedx /= (nu-nl+1);
945 SetdEdx(dedx);
946}
947
73042f01 948
949