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