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