1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.34 2003/05/22 13:57:48 hristov
19 First implementation of ESD classes (Yu.Belikov)
21 Revision 1.32 2003/04/10 10:36:54 hristov
22 Code for unified TPC/TRD tracking (S.Radomski)
24 Revision 1.31 2003/03/19 17:14:11 hristov
25 Load/UnloadClusters added to the base class and the derived classes changed correspondingly. Possibility to give 2 input files for ITS and TPC tracks in PropagateBack. TRD tracker uses fEventN from the base class (T.Kuhr)
27 Revision 1.30 2003/02/28 16:13:32 hristov
30 Revision 1.29 2003/02/28 15:18:16 hristov
31 Corrections suggested by J.Chudoba
33 Revision 1.28 2003/02/27 16:15:52 hristov
34 Code for inward refitting (S.Radomski)
36 Revision 1.27 2003/02/25 16:47:58 hristov
37 allow back propagation for more than 1 event (J.Chudoba)
39 Revision 1.26 2003/02/19 08:49:46 hristov
40 Track time measurement (S.Radomski)
42 Revision 1.25 2003/01/28 16:43:35 hristov
43 Additional protection: to be discussed with the Root team (M.Ivanov)
45 Revision 1.24 2002/11/19 16:13:24 hristov
46 stdlib.h included to declare exit() on HP
48 Revision 1.23 2002/11/19 11:50:08 hristov
49 Removing CONTAINERS (Yu.Belikov)
51 Revision 1.19 2002/07/19 07:31:40 kowal2
52 Improvement in tracking by J. Belikov
54 Revision 1.18 2002/05/13 07:33:52 kowal2
55 Added protection in Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const
56 in the case of defined region of interests.
58 Revision 1.17 2002/03/18 17:59:13 kowal2
59 Chnges in the pad geometry - 3 pad lengths introduced.
61 Revision 1.16 2001/11/08 16:39:03 hristov
62 Additional protection (M.Masera)
64 Revision 1.15 2001/11/08 16:36:33 hristov
65 Updated V2 stream of tracking (Yu.Belikov). The new long waited features are: 1) Possibility to pass the primary vertex position to the trackers (both for the TPC and the ITS) 2) Possibility to specify the number of tracking passes together with applying (or not applying) the vertex constraint (ITS only) 3) Possibility to make some use of partial PID provided by the TPC when doing tracking in the ITS (ITS only) 4) V0 reconstruction with a helix minimisation of the DCA. (new macros: AliV0FindVertices.C and AliV0Comparison.C) 4a) ( Consequence of the 4) ) All the efficiencies and resolutions are from now on calculated including *secondary*particles* too. (Don't be surprised by the drop in efficiency etc)
67 Revision 1.14 2001/10/21 19:04:55 hristov
68 Several patches were done to adapt the barel reconstruction to the multi-event case. Some memory leaks were corrected. (Yu.Belikov)
70 Revision 1.13 2001/07/23 12:01:30 hristov
73 Revision 1.12 2001/07/20 14:32:44 kowal2
74 Processing of many events possible now
76 Revision 1.11 2001/05/23 08:50:10 hristov
79 Revision 1.10 2001/05/16 14:57:25 alibrary
80 New files for folders and Stack
82 Revision 1.9 2001/05/11 07:16:56 hristov
83 Fix needed on Sun and Alpha
85 Revision 1.8 2001/05/08 15:00:15 hristov
86 Corrections for tracking in arbitrary magnenetic field. Changes towards a concept of global Alice track. Back propagation of reconstructed tracks (Yu.Belikov)
88 Revision 1.5 2000/12/20 07:51:59 kowal2
89 Changes suggested by Alessandra and Paolo to avoid overlapped
90 data fields in encapsulated classes.
92 Revision 1.4 2000/11/02 07:27:16 kowal2
95 Revision 1.2 2000/06/30 12:07:50 kowal2
96 Updated from the TPC-PreRelease branch
98 Revision 1.1.2.1 2000/06/25 08:53:55 kowal2
99 Splitted from AliTPCtracking
103 //-------------------------------------------------------
104 // Implementation of the TPC tracker
106 // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
107 //-------------------------------------------------------
108 #include <TObjArray.h>
111 #include <Riostream.h>
115 #include "AliTPCtracker.h"
116 #include "AliTPCcluster.h"
117 #include "AliTPCParam.h"
118 #include "AliClusters.h"
120 #include "TVector2.h"
124 ClassImp(AliTPCtracker)
126 //_____________________________________________________________________________
127 AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
128 AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2)
130 //---------------------------------------------------------------------
131 // The main TPC tracker constructor
132 //---------------------------------------------------------------------
133 fInnerSec=new AliTPCSector[fkNIS];
134 fOuterSec=new AliTPCSector[fkNOS];
137 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
138 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
140 fParam = (AliTPCParam*) par;
152 //_____________________________________________________________________________
153 AliTPCtracker::~AliTPCtracker() {
154 //------------------------------------------------------------------
155 // TPC tracker destructor
156 //------------------------------------------------------------------
166 fBarrelFile->Close();
171 //_____________________________________________________________________________
173 void AliTPCtracker::SetBarrelTree(const char *mode) {
175 // Creates a tree for BarrelTracks
176 // mode = "back" or "refit"
181 if (!IsStoringBarrel()) return;
183 TDirectory *sav = gDirectory;
184 if (!fBarrelFile) fBarrelFile = new TFile("AliBarrelTracks.root", "UPDATE");
187 sprintf(buff, "BarrelTPC_%d_%s", GetEventNumber(), mode);
190 fBarrelTree = new TTree(buff, "Barrel TPC tracks");
192 if (!fBarrelArray) fBarrelArray = new TClonesArray("AliBarrelTrack", 4);
193 for(Int_t i=0; i<4; i++) new((*fBarrelArray)[i]) AliBarrelTrack();
195 fBarrelTree->Branch("tracks", &fBarrelArray);
199 //_____________________________________________________________________________
201 void AliTPCtracker::StoreBarrelTrack(AliTPCtrack *ps, Int_t refPlane, Int_t isIn) {
203 // Stores Track at a given reference plane
206 // isIn: 1 - backward, 2 - refit
209 if (!IsStoringBarrel()) return;
210 if (refPlane < 0 || refPlane > 4) return;
211 if (isIn > 2) return;
213 static Int_t nClusters;
215 static Double_t chi2;
218 Int_t newClusters, newWrong;
221 if ( (refPlane == 1 && isIn == kTrackBack) ||
222 (refPlane == 4 && isIn == kTrackRefit) ) {
224 fBarrelArray->Clear();
225 nClusters = nWrong = 0;
232 if (refPlane == 1) refX = fParam->GetInnerRadiusLow();
233 if (refPlane == 2) refX = fParam->GetInnerRadiusUp();
234 if (refPlane == 3) refX = fParam->GetOuterRadiusLow();
235 if (refPlane == 4) refX = fParam->GetOuterRadiusUp();
237 ps->PropagateTo(refX);
239 fBarrelTrack = (AliBarrelTrack*)(*fBarrelArray)[index++];
240 ps->GetBarrelTrack(fBarrelTrack);
242 newClusters = ps->GetNumberOfClusters() - nClusters;
243 newWrong = ps->GetNWrong() - nWrong;
244 newChi2 = ps->GetChi2() - chi2;
246 nClusters = ps->GetNumberOfClusters();
247 nWrong = ps->GetNWrong();
248 chi2 = ps->GetChi2();
250 fBarrelTrack->SetNClusters(newClusters, newChi2);
251 fBarrelTrack->SetNWrongClusters(newWrong);
252 fBarrelTrack->SetRefPlane(refPlane, isIn);
255 //_____________________________________________________________________________
256 Double_t SigmaY2(Double_t r, Double_t tgl, Double_t pt)
259 // Parametrised error of the cluster reconstruction (pad direction)
262 const Float_t kArphi=0.41818e-2;
263 const Float_t kBrphi=0.17460e-4;
264 const Float_t kCrphi=0.30993e-2;
265 const Float_t kDrphi=0.41061e-3;
267 pt=TMath::Abs(pt)*1000.;
270 Double_t s=kArphi - kBrphi*r*tgl + kCrphi*x*x + kDrphi*x;
271 if (s<0.4e-3) s=0.4e-3;
272 s*=1.3; //Iouri Belikov
277 //_____________________________________________________________________________
278 Double_t SigmaZ2(Double_t r, Double_t tgl)
281 // Parametrised error of the cluster reconstruction (drift direction)
284 const Float_t kAz=0.39614e-2;
285 const Float_t kBz=0.22443e-4;
286 const Float_t kCz=0.51504e-1;
290 Double_t s=kAz - kBz*r*tgl + kCz*tgl*tgl;
291 if (s<0.4e-3) s=0.4e-3;
292 s*=1.3; //Iouri Belikov
297 //_____________________________________________________________________________
298 Double_t f1(Double_t x1,Double_t y1,
299 Double_t x2,Double_t y2,
300 Double_t x3,Double_t y3)
302 //-----------------------------------------------------------------
303 // Initial approximation of the track curvature
304 //-----------------------------------------------------------------
305 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
306 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
307 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
308 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
309 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
311 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
313 return -xr*yr/sqrt(xr*xr+yr*yr);
317 //_____________________________________________________________________________
318 Double_t f2(Double_t x1,Double_t y1,
319 Double_t x2,Double_t y2,
320 Double_t x3,Double_t y3)
322 //-----------------------------------------------------------------
323 // Initial approximation of the track curvature times center of curvature
324 //-----------------------------------------------------------------
325 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
326 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
327 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
328 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
329 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
331 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
333 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
336 //_____________________________________________________________________________
337 Double_t f3(Double_t x1,Double_t y1,
338 Double_t x2,Double_t y2,
339 Double_t z1,Double_t z2)
341 //-----------------------------------------------------------------
342 // Initial approximation of the tangent of the track dip angle
343 //-----------------------------------------------------------------
344 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
347 Int_t AliTPCtracker::LoadClusters() {
348 return LoadClusters(gFile);
351 //_____________________________________________________________________________
352 Int_t AliTPCtracker::LoadClusters(const TFile *cf) {
353 //-----------------------------------------------------------------
354 // This function loads TPC clusters.
355 //-----------------------------------------------------------------
356 if (!((TFile*)cf)->IsOpen()) {
357 cerr<<"AliTPCtracker::LoadClusters : "<<
358 "file with clusters has not been open !\n";
363 sprintf(name,"TreeC_TPC_%d",GetEventNumber());
364 TTree *cTree=(TTree*)((TFile*)cf)->Get(name);
366 cerr<<"AliTPCtracker::LoadClusters : "<<
367 "can't get the tree with TPC clusters !\n";
371 TBranch *branch=cTree->GetBranch("Segment");
373 cerr<<"AliTPCtracker::LoadClusters : "<<
374 "can't get the segment branch !\n";
378 AliClusters carray, *addr=&carray;
379 carray.SetClass("AliTPCcluster");
381 branch->SetAddress(&addr);
383 Int_t nentr=(Int_t)cTree->GetEntries();
385 for (Int_t i=0; i<nentr; i++) {
388 Int_t ncl=carray.GetArray()->GetEntriesFast();
390 Int_t nir=fInnerSec->GetNRows(), nor=fOuterSec->GetNRows();
391 Int_t id=carray.GetID();
392 if ((id<0) || (id>2*(fkNIS*nir + fkNOS*nor))) {
393 cerr<<"AliTPCtracker::LoadClusters : "<<
397 Int_t outindex = 2*fkNIS*nir;
400 Int_t row = id - sec*nir;
402 AliTPCRow &padrow=fInnerSec[sec][row];
404 AliTPCcluster *c=(AliTPCcluster*)carray[ncl];
405 padrow.InsertCluster(c,sec,row);
410 Int_t row = id - sec*nor;
412 AliTPCRow &padrow=fOuterSec[sec][row];
414 AliTPCcluster *c=(AliTPCcluster*)carray[ncl];
415 padrow.InsertCluster(c,sec+fkNIS,row);
418 carray.GetArray()->Clear();
424 //_____________________________________________________________________________
425 void AliTPCtracker::UnloadClusters() {
426 //-----------------------------------------------------------------
427 // This function unloads TPC clusters.
428 //-----------------------------------------------------------------
430 for (i=0; i<fkNIS; i++) {
431 Int_t nr=fInnerSec->GetNRows();
432 for (Int_t n=0; n<nr; n++) fInnerSec[i][n].ResetClusters();
434 for (i=0; i<fkNOS; i++) {
435 Int_t nr=fOuterSec->GetNRows();
436 for (Int_t n=0; n<nr; n++) fOuterSec[i][n].ResetClusters();
440 //_____________________________________________________________________________
441 Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) {
442 //-----------------------------------------------------------------
443 // This function tries to find a track prolongation.
444 //-----------------------------------------------------------------
445 Double_t xt=t.GetX();
446 const Int_t kSKIP=(t.GetNumberOfClusters()<10) ? kRowsToSkip :
447 Int_t(0.5*fSectors->GetNRows());
448 Int_t tryAgain=kSKIP;
450 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
451 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
452 if (alpha < 0. ) alpha += 2.*TMath::Pi();
453 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
455 Int_t nrows=fSectors->GetRowNumber(xt)-1;
456 for (Int_t nr=nrows; nr>=rf; nr--) {
457 Double_t x=fSectors->GetX(nr), ymax=fSectors->GetMaxY(nr);
458 if (!t.PropagateTo(x)) return 0;
462 Double_t maxchi2=kMaxCHI2;
463 const AliTPCRow &krow=fSectors[s][nr];
464 Double_t pt=t.GetConvConst()/(100/0.299792458/0.2)/t.Get1Pt();
465 Double_t sy2=SigmaY2(t.GetX(),t.GetTgl(),pt);
466 Double_t sz2=SigmaZ2(t.GetX(),t.GetTgl());
467 Double_t road=4.*sqrt(t.GetSigmaY2() + sy2), y=t.GetY(), z=t.GetZ();
470 if (t.GetNumberOfClusters()>4)
471 cerr<<t.GetNumberOfClusters()
472 <<"FindProlongation warning: Too broad road !\n";
476 //if (fSectors == fInnerSec && (nr == 63 || nr == 0)) {
477 // cout << nr << "\t" << krow << endl;
481 for (Int_t i=krow.Find(y-road); i<krow; i++) {
482 AliTPCcluster *c=(AliTPCcluster*)(krow[i]);
483 if (c->GetY() > y+road) break;
484 if (c->IsUsed()) continue;
485 if ((c->GetZ()-z)*(c->GetZ()-z) > 16.*(t.GetSigmaZ2()+sz2)) continue;
486 Double_t chi2=t.GetPredictedChi2(c);
487 if (chi2 > maxchi2) continue;
490 index=krow.GetIndex(i);
494 Float_t l=fSectors->GetPadPitchWidth();
495 Float_t corr=1.; if (nr>63) corr=0.67; // new (third) pad response !
496 t.SetSampledEdx(cl->GetQ()/l*corr,t.GetNumberOfClusters());
497 if (!t.Update(cl,maxchi2,index)) {
498 if (!tryAgain--) return 0;
499 } else tryAgain=kSKIP;
501 if (tryAgain==0) break;
504 if (!t.Rotate(fSectors->GetAlpha())) return 0;
505 } else if (y <-ymax) {
507 if (!t.Rotate(-fSectors->GetAlpha())) return 0;
515 //_____________________________________________________________________________
517 Int_t AliTPCtracker::FollowRefitInward(AliTPCseed *seed, AliTPCtrack *track) {
519 // This function propagates seed inward TPC using old clusters
522 // Sylwester Radomski, GSI
526 Double_t alpha=seed->GetAlpha() - fSectors->GetAlphaShift();
527 TVector2::Phi_0_2pi(alpha);
528 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
530 Int_t idx=-1, sec=-1, row=-1;
531 Int_t nc = seed->GetNumber();
533 idx=track->GetClusterIndex(nc);
534 sec=(idx&0xff000000)>>24;
535 row=(idx&0x00ff0000)>>16;
537 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
538 else { if (sec < fkNIS) row=-1; }
540 Int_t nr=fSectors->GetNRows();
541 for (Int_t i=nr-1; i>=0; i--) {
544 //cout << i << "\t" << nc << "\t"<< row << "\t" << seed->Pt() << "\t" << track->Pt() << "\t\t";
546 Double_t x=fSectors->GetX(i);
547 if (!seed->PropagateTo(x)) return 0;
549 // Change sector and rotate seed if necessary
551 Double_t ymax=fSectors->GetMaxY(i);
552 Double_t y=seed->GetY();
556 if (!seed->Rotate(fSectors->GetAlpha())) return 0;
557 } else if (y <-ymax) {
559 if (!seed->Rotate(-fSectors->GetAlpha())) return 0;
562 // try to find a cluster
566 Double_t maxchi2 = kMaxCHI2;
570 //cout << row << endl;
571 // accept already found cluster
572 AliTPCcluster *c=(AliTPCcluster*)GetCluster(idx);
573 Double_t chi2 = seed->GetPredictedChi2(c);
579 //cout << c->GetY() << "\t" << seed->GetY() << "\t" << track->GetY();
581 if (--nc >= 0 /* track->GetNumberOfClusters()*/ ) {
582 idx=track->GetClusterIndex(nc);
583 sec=(idx&0xff000000)>>24;
584 row=(idx&0x00ff0000)>>16;
587 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
588 else { if (sec < fkNIS) row=-1; }
593 Float_t l=fSectors->GetPadPitchWidth();
594 Float_t corr=1.; if (i>63) corr=0.67; // new (third) pad response !
595 seed->SetSampledEdx(cl->GetQ()/l*corr,seed->GetNumberOfClusters());
596 seed->Update(cl,maxchi2,index);
604 //_____________________________________________________________________________
605 Int_t AliTPCtracker::FollowBackProlongation
606 (AliTPCseed& seed, const AliTPCtrack &track) {
607 //-----------------------------------------------------------------
608 // This function propagates tracks back through the TPC
609 //-----------------------------------------------------------------
610 Double_t alpha=seed.GetAlpha() - fSectors->GetAlphaShift();
611 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
612 if (alpha < 0. ) alpha += 2.*TMath::Pi();
613 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
615 Int_t idx=-1, sec=-1, row=-1;
616 //Int_t nc=seed.GetLabel(); //index of the cluster to start with
617 Int_t nc=seed.GetNumber();
620 idx=track.GetClusterIndex(nc);
621 sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
623 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
624 else { if (sec < fkNIS) row=-1; }
626 Int_t nr=fSectors->GetNRows();
627 for (Int_t i=0; i<nr; i++) {
628 Double_t x=fSectors->GetX(i), ymax=fSectors->GetMaxY(i);
630 //cout << i << "\t" << nc << "\t" << row << "\t" << track.GetNumberOfClusters() << endl;
632 if (!seed.PropagateTo(x)) return 0;
634 Double_t y=seed.GetY();
637 if (!seed.Rotate(fSectors->GetAlpha())) return 0;
638 } else if (y <-ymax) {
640 if (!seed.Rotate(-fSectors->GetAlpha())) return 0;
645 Double_t maxchi2=kMaxCHI2;
646 Double_t pt=seed.GetConvConst()/(100/0.299792458/0.2)/seed.Get1Pt();
647 Double_t sy2=SigmaY2(seed.GetX(),seed.GetTgl(),pt);
648 Double_t sz2=SigmaZ2(seed.GetX(),seed.GetTgl());
649 Double_t road=4.*sqrt(seed.GetSigmaY2() + sy2), z=seed.GetZ();
651 cerr<<seed.GetNumberOfClusters()
652 <<"AliTPCtracker::FollowBackProlongation: Too broad road !\n";
656 Int_t accepted=seed.GetNumberOfClusters();
659 //if (fSectors == fInnerSec && row == 0)
660 //cout << "row == " << row << endl;
662 //try to accept already found cluster
663 AliTPCcluster *c=(AliTPCcluster*)GetCluster(idx);
665 if ((chi2=seed.GetPredictedChi2(c))<maxchi2 || accepted<27) {
666 index=idx; cl=c; maxchi2=chi2;
667 } //else cerr<<"AliTPCtracker::FollowBackProlongation: oulier !\n";
670 idx=track.GetClusterIndex(nc);
671 sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
673 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
674 else { if (sec < fkNIS) row=-1; }
678 //try to fill the gap
679 const AliTPCRow &krow=fSectors[s][i];
682 for (Int_t i=krow.Find(y-road); i<krow; i++) {
683 AliTPCcluster *c=(AliTPCcluster*)(krow[i]);
684 if (c->GetY() > y+road) break;
685 if (c->IsUsed()) continue;
686 if ((c->GetZ()-z)*(c->GetZ()-z)>16.*(seed.GetSigmaZ2()+sz2)) continue;
687 Double_t chi2=seed.GetPredictedChi2(c);
688 if (chi2 > maxchi2) continue;
691 index=krow.GetIndex(i);
697 Float_t l=fSectors->GetPadPitchWidth();
698 Float_t corr=1.; if (i>63) corr=0.67; // new (third) pad response !
699 seed.SetSampledEdx(cl->GetQ()/l*corr,seed.GetNumberOfClusters());
700 seed.Update(cl,maxchi2,index);
711 //_____________________________________________________________________________
712 void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) {
713 //-----------------------------------------------------------------
714 // This function creates track seeds.
715 //-----------------------------------------------------------------
716 Double_t x[5], c[15];
718 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
719 Double_t cs=cos(alpha), sn=sin(alpha);
721 Double_t x1 =fSectors->GetX(i1);
722 Double_t xx2=fSectors->GetX(i2);
724 for (Int_t ns=0; ns<fN; ns++) {
725 Int_t nl=fSectors[(ns-1+fN)%fN][i2];
726 Int_t nm=fSectors[ns][i2];
727 Int_t nu=fSectors[(ns+1)%fN][i2];
728 const AliTPCRow& kr1=fSectors[ns][i1];
729 for (Int_t is=0; is < kr1; is++) {
730 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
731 for (Int_t js=0; js < nl+nm+nu; js++) {
732 const AliTPCcluster *kcl;
734 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
737 const AliTPCRow& kr2=fSectors[(ns-1+fN)%fN][i2];
739 y2=kcl->GetY(); z2=kcl->GetZ();
744 const AliTPCRow& kr2=fSectors[ns][i2];
746 x2=xx2; y2=kcl->GetY(); z2=kcl->GetZ();
748 const AliTPCRow& kr2=fSectors[(ns+1)%fN][i2];
750 y2=kcl->GetY(); z2=kcl->GetZ();
755 Double_t zz=z1 - (z1-z3)/(x1-x3)*(x1-x2);
756 if (TMath::Abs(zz-z2)>5.) continue;
758 Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
759 if (d==0.) {cerr<<"MakeSeeds warning: Straight seed !\n"; continue;}
763 x[4]=f1(x1,y1,x2,y2,x3,y3);
764 if (TMath::Abs(x[4]) >= 0.0066) continue;
765 x[2]=f2(x1,y1,x2,y2,x3,y3);
766 //if (TMath::Abs(x[4]*x1-x[2]) >= 0.99999) continue;
767 x[3]=f3(x1,y1,x2,y2,z1,z2);
768 if (TMath::Abs(x[3]) > 1.2) continue;
769 Double_t a=asin(x[2]);
770 Double_t zv=z1 - x[3]/x[4]*(a+asin(x[4]*x1-x[2]));
771 if (TMath::Abs(zv-z3)>10.) continue;
773 Double_t sy1=kr1[is]->GetSigmaY2(), sz1=kr1[is]->GetSigmaZ2();
774 Double_t sy2=kcl->GetSigmaY2(), sz2=kcl->GetSigmaZ2();
775 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
776 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
778 Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
779 Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
780 Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
781 Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
782 Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
783 Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
784 Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
785 Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
786 Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
787 Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
791 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
792 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
793 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
794 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
795 c[13]=f30*sy1*f40+f32*sy2*f42;
796 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
798 UInt_t index=kr1.GetIndex(is);
799 AliTPCseed *track=new AliTPCseed(index, x, c, x1, ns*alpha+shift);
800 Float_t l=fSectors->GetPadPitchWidth();
801 track->SetSampledEdx(kr1[is]->GetQ()/l,0);
803 Int_t rc=FollowProlongation(*track, i2);
804 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)/2) delete track;
805 else fSeeds->AddLast(track);
811 //_____________________________________________________________________________
812 Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
813 //-----------------------------------------------------------------
814 // This function reades track seeds.
815 //-----------------------------------------------------------------
816 TDirectory *savedir=gDirectory;
818 TFile *in=(TFile*)inp;
820 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
825 TTree *seedTree=(TTree*)in->Get("Seeds");
827 cerr<<"AliTPCtracker::ReadSeeds(): ";
828 cerr<<"can't get a tree with track seeds !\n";
831 AliTPCtrack *seed=new AliTPCtrack;
832 seedTree->SetBranchAddress("tracks",&seed);
834 if (fSeeds==0) fSeeds=new TObjArray(15000);
836 Int_t n=(Int_t)seedTree->GetEntries();
837 for (Int_t i=0; i<n; i++) {
838 seedTree->GetEvent(i);
839 fSeeds->AddLast(new AliTPCseed(*seed,seed->GetAlpha()));
844 delete seedTree; //Thanks to Mariana Bondila
851 //_____________________________________________________________________________
852 Int_t AliTPCtracker::Clusters2Tracks(AliESD *event) {
853 //-----------------------------------------------------------------
854 // This is a track finder.
855 // The clusters must be already loaded !
856 //-----------------------------------------------------------------
859 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
860 Int_t nrows=nlow+nup;
862 Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
863 fSectors=fOuterSec; fN=fkNOS;
864 fSeeds=new TObjArray(15000);
865 MakeSeeds(nup-1, nup-1-gap);
866 MakeSeeds(nup-1-shift, nup-1-shift-gap);
870 Int_t nseed=fSeeds->GetEntriesFast();
871 for (Int_t i=0; i<nseed; i++) {
872 //tracking in the outer sectors
873 fSectors=fOuterSec; fN=fkNOS;
875 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
876 if (!FollowProlongation(t)) {
877 delete fSeeds->RemoveAt(i);
881 //tracking in the inner sectors
882 fSectors=fInnerSec; fN=fkNIS;
884 Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift();
885 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
886 if (alpha < 0. ) alpha += 2.*TMath::Pi();
887 Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS;
889 alpha=ns*fInnerSec->GetAlpha()+fInnerSec->GetAlphaShift()-t.GetAlpha();
891 if (t.Rotate(alpha)) {
892 if (FollowProlongation(t)) {
893 if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
895 CookLabel(pt,0.1); //For comparison only
896 pt->PropagateTo(fParam->GetInnerRadiusLow());
898 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
900 event->AddTrack(&iotrack);
906 delete fSeeds->RemoveAt(i);
909 cerr<<"Number of found tracks : "<<event->GetNumberOfTracks()<<endl;
911 fSeeds->Clear(); delete fSeeds; fSeeds=0;
916 //_____________________________________________________________________________
917 Int_t AliTPCtracker::Clusters2Tracks(const TFile *inp, TFile *out) {
918 //-----------------------------------------------------------------
919 // This is a track finder.
920 //-----------------------------------------------------------------
921 TDirectory *savedir=gDirectory;
924 TFile *in=(TFile*)inp;
926 cerr<<"AliTPCtracker::Clusters2Tracks(): input file is not open !\n";
931 if (!out->IsOpen()) {
932 cerr<<"AliTPCtracker::Clusters2Tracks(): output file is not open !\n";
941 sprintf(tname,"TreeT_TPC_%d",GetEventNumber());
942 TTree tracktree(tname,"Tree with TPC tracks");
943 AliTPCtrack *iotrack=0;
944 tracktree.Branch("tracks","AliTPCtrack",&iotrack,32000,3);
947 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
948 Int_t nrows=nlow+nup;
950 Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
951 fSectors=fOuterSec; fN=fkNOS;
952 fSeeds=new TObjArray(15000);
953 MakeSeeds(nup-1, nup-1-gap);
954 MakeSeeds(nup-1-shift, nup-1-shift-gap);
959 Int_t nseed=fSeeds->GetEntriesFast();
961 cout << fInnerSec->GetNRows() << " " << fOuterSec->GetNRows() << endl;
963 for (Int_t i=0; i<nseed; i++) {
964 //tracking in the outer sectors
965 fSectors=fOuterSec; fN=fkNOS;
967 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
968 if (!FollowProlongation(t)) {
969 delete fSeeds->RemoveAt(i);
973 //tracking in the inner sectors
974 fSectors=fInnerSec; fN=fkNIS;
976 Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift();
977 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
978 if (alpha < 0. ) alpha += 2.*TMath::Pi();
979 Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS;
981 alpha=ns*fInnerSec->GetAlpha()+fInnerSec->GetAlphaShift()-t.GetAlpha();
983 if (t.Rotate(alpha)) {
984 if (FollowProlongation(t)) {
985 if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
987 CookLabel(pt,0.1); //For comparison only
988 pt->PropagateTo(fParam->GetInnerRadiusLow());
993 // cerr<<found<<'\r';
997 delete fSeeds->RemoveAt(i);
1002 cerr<<"Number of found tracks : "<<found<<endl;
1007 fSeeds->Clear(); delete fSeeds; fSeeds=0;
1011 //_____________________________________________________________________________
1013 Int_t AliTPCtracker::RefitInward(TFile *in, TFile *out) {
1015 // The function propagates tracks throught TPC inward
1016 // using already associated clusters.
1018 // in - file with back propagated tracks
1019 // outs - file with inward propagation
1021 // Sylwester Radomski, GSI
1025 if (!in->IsOpen()) {
1026 cout << "Input File not open !\n" << endl;
1030 if (!out->IsOpen()) {
1031 cout << "Output File not open !\n" << endl;
1035 TDirectory *savedir = gDirectory;
1038 // Connect to input tree
1040 TTree *inputTree = (TTree*)in->Get("seedsTPCtoTRD_0");
1041 TBranch *inBranch = inputTree->GetBranch("tracks");
1042 AliTPCtrack *inTrack = 0;
1043 inBranch->SetAddress(&inTrack);
1045 Int_t nTracks = (Int_t)inputTree->GetEntries();
1047 // Create output tree
1049 AliTPCtrack *outTrack = new AliTPCtrack();
1050 TTree *outputTree = new TTree("tracksTPC_0","Refited TPC tracks");
1051 outputTree->Branch("tracks", "AliTPCtrack", &outTrack, 32000, 3);
1053 // [SR, 01.04.2003] - Barrel tracks
1054 if (IsStoringBarrel()) SetBarrelTree("refit");
1058 for(Int_t t=0; t < nTracks; t++) {
1062 inputTree->GetEvent(t);
1063 inTrack->ResetCovariance();
1064 AliTPCseed *seed = new AliTPCseed(*inTrack, inTrack->GetAlpha());
1067 //cout << inTrack->GetNumberOfClusters() << endl;
1068 if (inTrack->GetNumberOfClusters() == 158) {
1069 cout << inTrack->GetNumberOfClusters() << endl;
1071 for(Int_t c=0; c<inTrack->GetNumberOfClusters(); c++) {
1072 Int_t idx = inTrack->GetClusterIndex(c);
1073 Int_t row=(idx&0x00ff0000)>>16;
1074 cout << c << " " << row << endl;
1079 if (IsStoringBarrel()) StoreBarrelTrack(seed, 4, 2);
1081 seed->SetNumber(inTrack->GetNumberOfClusters()-1);
1082 fSectors = fOuterSec;
1083 Int_t res = FollowRefitInward(seed, inTrack);
1085 Int_t nc = seed->GetNumberOfClusters();
1087 if (IsStoringBarrel()) StoreBarrelTrack(seed, 3, 2);
1088 if (IsStoringBarrel()) StoreBarrelTrack(seed, 2, 2);
1090 fSectors = fInnerSec;
1091 res = FollowRefitInward(seed, inTrack);
1092 UseClusters(seed, nc);
1094 if (IsStoringBarrel()) StoreBarrelTrack(seed, 1, 2);
1097 seed->PropagateTo(fParam->GetInnerRadiusLow());
1098 outTrack = (AliTPCtrack*)seed;
1099 outTrack->SetLabel(inTrack->GetLabel());
1104 if (IsStoringBarrel()) fBarrelTree->Fill();
1108 cout << "Refitted " << nRefited << " tracks." << endl;
1111 outputTree->Write();
1114 if (IsStoringBarrel()) {
1116 fBarrelTree->Write();
1117 fBarrelFile->Flush();
1119 delete fBarrelArray;
1123 if (inputTree) delete inputTree;
1124 if (outputTree) delete outputTree;
1132 //_____________________________________________________________________________
1133 Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
1134 //-----------------------------------------------------------------
1135 // This function propagates tracks back through the TPC.
1136 //-----------------------------------------------------------------
1137 return PropagateBack(inp, NULL, out);
1140 Int_t AliTPCtracker::PropagateBack(AliESD *event) {
1141 //-----------------------------------------------------------------
1142 // This function propagates tracks back through the TPC.
1143 // The clusters must be already loaded !
1144 //-----------------------------------------------------------------
1145 Int_t nentr=event->GetNumberOfTracks();
1146 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
1149 for (Int_t i=0; i<nentr; i++) {
1150 AliESDtrack *esd=event->GetTrack(i);
1151 ULong_t status=esd->GetStatus();
1153 if ( (status & AliESDtrack::kTPCin ) == 0 ) continue;
1154 if ( (status & AliESDtrack::kTPCout) != 0 ) continue;
1156 const AliTPCtrack t(*esd);
1157 AliTPCseed s(t,t.GetAlpha());
1159 if (status==AliESDtrack::kTPCin) s.ResetCovariance();
1160 else if ( (status & AliESDtrack::kITSout) == 0 ) continue;
1162 Int_t nc=t.GetNumberOfClusters();
1163 s.SetNumber(nc); //set number of the cluster to start with
1166 fSectors=fInnerSec; fN=fkNIS;
1168 Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift();
1169 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1170 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1171 Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
1172 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
1173 alpha-=s.GetAlpha();
1175 if (!s.Rotate(alpha)) continue;
1176 if (!FollowBackProlongation(s,t)) continue;
1180 fSectors=fOuterSec; fN=fkNOS;
1182 alpha=s.GetAlpha() - fSectors->GetAlphaShift();
1183 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1184 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1185 ns=Int_t(alpha/fSectors->GetAlpha())%fN;
1187 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
1188 alpha-=s.GetAlpha();
1190 if (!s.Rotate(alpha)) continue;
1191 if (!FollowBackProlongation(s,t)) continue;
1193 Int_t nrows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
1194 if (s.GetNumberOfClusters() < Int_t(0.4*nrows)) continue;
1196 s.PropagateTo(fParam->GetOuterRadiusUp());
1198 CookLabel(&s,0.1); //For comparison only
1200 esd->UpdateTrackParams(&s,AliESDtrack::kTPCout);
1203 cerr<<"Number of back propagated tracks: "<<ntrk<<endl;
1208 //_____________________________________________________________________________
1209 Int_t AliTPCtracker::PropagateBack(const TFile *inp, const TFile *inp2, TFile *out) {
1210 //-----------------------------------------------------------------
1211 // This function propagates tracks back through the TPC.
1212 //-----------------------------------------------------------------
1213 fSeeds=new TObjArray(15000);
1215 TFile *in=(TFile*)inp;
1216 TFile *in2=(TFile*)inp2;
1217 TDirectory *savedir=gDirectory;
1219 if (!in->IsOpen()) {
1220 cerr<<"AliTPCtracker::PropagateBack(): ";
1221 cerr<<"file with TPC (or back propagated ITS) tracks is not open !\n";
1225 if (!out->IsOpen()) {
1226 cerr<<"AliTPCtracker::PropagateBack(): ";
1227 cerr<<"file for back propagated TPC tracks is not open !\n";
1235 sprintf(tName,"TreeT_ITSb_%d",GetEventNumber());
1236 TTree *bckTree=(TTree*)in->Get(tName);
1237 if (!bckTree && inp2) bckTree=(TTree*)in2->Get(tName);
1239 cerr<<"AliTPCtracker::PropagateBack() ";
1240 cerr<<"can't get a tree with back propagated ITS tracks !\n";
1243 AliTPCtrack *bckTrack=new AliTPCtrack;
1244 if (bckTree) bckTree->SetBranchAddress("tracks",&bckTrack);
1246 sprintf(tName,"TreeT_TPC_%d",GetEventNumber());
1247 TTree *tpcTree=(TTree*)in->Get(tName);
1249 cerr<<"AliTPCtracker::PropagateBack() ";
1250 cerr<<"can't get a tree with TPC tracks !\n";
1253 AliTPCtrack *tpcTrack=new AliTPCtrack;
1254 tpcTree->SetBranchAddress("tracks",&tpcTrack);
1256 // [SR, 01.04.2003] - Barrel tracks
1257 if (IsStoringBarrel()) SetBarrelTree("back");
1259 //*** Prepare an array of tracks to be back propagated
1260 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
1261 Int_t nrows=nlow+nup;
1264 // Match ITS tracks with old TPC tracks
1265 // the tracks do not have to be sorted [SR, GSI, 18.02.2003]
1267 // the algorithm is linear and uses LUT for sorting
1268 // cost of the algorithm: 2 * number of tracks
1271 TObjArray tracks(15000);
1273 Int_t tpcN= (Int_t)tpcTree->GetEntries();
1274 Int_t bckN= (bckTree)? (Int_t)bckTree->GetEntries() : 0;
1277 const Int_t nLab = 200000; // limit on number of primaries (arbitrary)
1279 for(Int_t i=0; i<nLab; i++) lut[i] = -1;
1282 for(Int_t i=0; i<bckN; i++) {
1283 bckTree->GetEvent(i);
1284 Int_t lab = TMath::Abs(bckTrack->GetLabel());
1285 if (lab < nLab) lut[lab] = i;
1287 cerr << "AliTPCtracker: The size of the LUT is too small\n";
1292 for (Int_t i=0; i<tpcN; i++) {
1293 tpcTree->GetEvent(i);
1294 Double_t alpha=tpcTrack->GetAlpha();
1298 // No ITS - use TPC track only
1300 tpcTrack->ResetCovariance();
1301 AliTPCseed * seed = new AliTPCseed(*tpcTrack, tpcTrack->GetAlpha());
1303 fSeeds->AddLast(seed);
1304 tracks.AddLast(new AliTPCtrack(*tpcTrack));
1309 // discard not prolongated tracks (to be discussed)
1311 Int_t lab = TMath::Abs(tpcTrack->GetLabel());
1312 if (lab > nLab || lut[lab] < 0) continue;
1314 bckTree->GetEvent(lut[lab]);
1315 bckTrack->Rotate(alpha-bckTrack->GetAlpha());
1317 fSeeds->AddLast(new AliTPCseed(*bckTrack,bckTrack->GetAlpha()));
1318 tracks.AddLast(new AliTPCtrack(*tpcTrack));
1325 TObjArray tracks(15000);
1327 Int_t tpcN=(Int_t)tpcTree->GetEntries();
1328 Int_t bckN=(Int_t)bckTree->GetEntries();
1329 if (j<bckN) bckTree->GetEvent(j++);
1330 for (i=0; i<tpcN; i++) {
1331 tpcTree->GetEvent(i);
1332 Double_t alpha=tpcTrack->GetAlpha();
1334 TMath::Abs(tpcTrack->GetLabel())==TMath::Abs(bckTrack->GetLabel())) {
1335 if (!bckTrack->Rotate(alpha-bckTrack->GetAlpha())) continue;
1336 fSeeds->AddLast(new AliTPCseed(*bckTrack,bckTrack->GetAlpha()));
1337 bckTree->GetEvent(j++);
1339 tpcTrack->ResetCovariance();
1340 fSeeds->AddLast(new AliTPCseed(*tpcTrack,alpha));
1342 tracks.AddLast(new AliTPCtrack(*tpcTrack));
1348 // tree name seedsTPCtoTRD as expected by TRD and as
1349 // discussed and decided in Strasbourg (May 2002)
1350 // [SR, GSI, 18.02.2003]
1352 sprintf(tName,"seedsTPCtoTRD_%d",GetEventNumber());
1353 TTree backTree(tName,"Tree with back propagated TPC tracks");
1355 AliTPCtrack *otrack=0;
1356 backTree.Branch("tracks","AliTPCtrack",&otrack,32000,0);
1361 Int_t nseed=fSeeds->GetEntriesFast();
1363 // loop changed [SR, 01.04.2003]
1365 for (i=0; i<nseed; i++) {
1368 if (IsStoringBarrel()) fBarrelArray->Clear();
1370 AliTPCseed *ps=(AliTPCseed*)fSeeds->UncheckedAt(i), &s=*ps;
1371 const AliTPCtrack *pt=(AliTPCtrack*)tracks.UncheckedAt(i), &t=*pt;
1374 ps->ResetNRotation();
1376 if (IsStoringBarrel()) StoreBarrelTrack(ps, 1, 1);
1378 // Load outer sectors
1382 Int_t nc=t.GetNumberOfClusters();
1383 //s.SetLabel(nc-1); //set number of the cluster to start with
1386 if (FollowBackProlongation(s,t)) UseClusters(&s);
1388 fSeeds->RemoveAt(i);
1392 if (IsStoringBarrel()) StoreBarrelTrack(ps, 2, 1);
1393 if (IsStoringBarrel()) StoreBarrelTrack(ps, 3, 1);
1395 // Load outer sectors
1399 nc=s.GetNumberOfClusters();
1401 Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift();
1402 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1403 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1404 Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
1406 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
1407 alpha-=s.GetAlpha();
1409 if (s.Rotate(alpha)) {
1410 if (FollowBackProlongation(s,t)) {
1411 if (s.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
1413 s.SetLabel(t.GetLabel());
1416 // Propagate to outer reference plane for comparison reasons
1417 // reason for keeping fParam object [SR, GSI, 18.02.2003]
1419 ps->PropagateTo(fParam->GetOuterRadiusUp());
1423 if (IsStoringBarrel()) StoreBarrelTrack(ps, 4, 1);
1424 cerr<<found++<<'\r';
1429 if (IsStoringBarrel()) fBarrelTree->Fill();
1430 delete fSeeds->RemoveAt(i);
1438 if (IsStoringBarrel()) {
1440 fBarrelTree->Write();
1441 fBarrelFile->Flush();
1443 delete fBarrelArray;
1448 cerr<<"Number of seeds: "<<nseed<<endl;
1449 cerr<<"Number of back propagated ITS tracks: "<<bckN<<endl;
1450 cerr<<"Number of back propagated TPC tracks: "<<found<<endl;
1455 if (bckTree) delete bckTree; //Thanks to Mariana Bondila
1456 delete tpcTree; //Thanks to Mariana Bondila
1463 //_________________________________________________________________________
1464 AliCluster *AliTPCtracker::GetCluster(Int_t index) const {
1465 //--------------------------------------------------------------------
1466 // Return pointer to a given cluster
1467 //--------------------------------------------------------------------
1468 Int_t sec=(index&0xff000000)>>24;
1469 Int_t row=(index&0x00ff0000)>>16;
1470 Int_t ncl=(index&0x0000ffff)>>00;
1472 const AliTPCcluster *cl=0;
1475 cl=fInnerSec[sec][row].GetUnsortedCluster(ncl);
1478 cl=fOuterSec[sec][row].GetUnsortedCluster(ncl);
1481 return (AliCluster*)cl;
1484 //__________________________________________________________________________
1485 void AliTPCtracker::CookLabel(AliKalmanTrack *t, Float_t wrong) const {
1486 //--------------------------------------------------------------------
1487 //This function "cooks" a track label. If label<0, this track is fake.
1488 //--------------------------------------------------------------------
1489 Int_t noc=t->GetNumberOfClusters();
1490 Int_t *lb=new Int_t[noc];
1491 Int_t *mx=new Int_t[noc];
1492 AliCluster **clusters=new AliCluster*[noc];
1495 for (i=0; i<noc; i++) {
1497 Int_t index=t->GetClusterIndex(i);
1498 clusters[i]=GetCluster(index);
1501 Int_t lab=123456789;
1502 for (i=0; i<noc; i++) {
1503 AliCluster *c=clusters[i];
1504 lab=TMath::Abs(c->GetLabel(0));
1506 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
1512 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
1514 for (i=0; i<noc; i++) {
1515 AliCluster *c=clusters[i];
1516 if (TMath::Abs(c->GetLabel(1)) == lab ||
1517 TMath::Abs(c->GetLabel(2)) == lab ) max++;
1520 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
1523 Int_t tail=Int_t(0.10*noc);
1525 for (i=1; i<=tail; i++) {
1526 AliCluster *c=clusters[noc-i];
1527 if (lab == TMath::Abs(c->GetLabel(0)) ||
1528 lab == TMath::Abs(c->GetLabel(1)) ||
1529 lab == TMath::Abs(c->GetLabel(2))) max++;
1531 if (max < Int_t(0.5*tail)) lab=-lab;
1541 //_________________________________________________________________________
1542 void AliTPCtracker::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
1543 //-----------------------------------------------------------------------
1544 // Setup inner sector
1545 //-----------------------------------------------------------------------
1547 fAlpha=par->GetInnerAngle();
1548 fAlphaShift=par->GetInnerAngleShift();
1549 fPadPitchWidth=par->GetInnerPadPitchWidth();
1550 f1PadPitchLength=par->GetInnerPadPitchLength();
1551 f2PadPitchLength=f1PadPitchLength;
1553 fN=par->GetNRowLow();
1554 fRow=new AliTPCRow[fN];
1555 for (Int_t i=0; i<fN; i++) fRow[i].SetX(par->GetPadRowRadiiLow(i));
1557 fAlpha=par->GetOuterAngle();
1558 fAlphaShift=par->GetOuterAngleShift();
1559 fPadPitchWidth=par->GetOuterPadPitchWidth();
1560 f1PadPitchLength=par->GetOuter1PadPitchLength();
1561 f2PadPitchLength=par->GetOuter2PadPitchLength();
1563 fN=par->GetNRowUp();
1564 fRow=new AliTPCRow[fN];
1565 for (Int_t i=0; i<fN; i++){
1566 fRow[i].SetX(par->GetPadRowRadiiUp(i));
1571 //_________________________________________________________________________
1572 void AliTPCtracker::
1573 AliTPCRow::InsertCluster(const AliTPCcluster* c, Int_t sec, Int_t row) {
1574 //-----------------------------------------------------------------------
1575 // Insert a cluster into this pad row in accordence with its y-coordinate
1576 //-----------------------------------------------------------------------
1577 if (fN==kMaxClusterPerRow) {
1578 cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
1581 Int_t index=(((sec<<8)+row)<<16)+fN;
1585 fClusterArray[0]=*c; fClusters[fN++]=fClusterArray;
1591 AliTPCcluster *buff=new AliTPCcluster[size];
1592 memcpy(buff,fClusterArray,fSize*sizeof(AliTPCcluster));
1593 for (Int_t i=0; i<fN; i++)
1594 fClusters[i]=buff+(fClusters[i]-fClusterArray);
1595 delete[] fClusterArray;
1600 Int_t i=Find(c->GetY());
1601 memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCcluster*));
1602 memmove(fIndex +i+1 ,fIndex +i,(fN-i)*sizeof(UInt_t));
1604 fClusters[i]=fClusterArray+fN; fClusterArray[fN++]=*c;
1607 //___________________________________________________________________
1608 Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const {
1609 //-----------------------------------------------------------------------
1610 // Return the index of the nearest cluster
1611 //-----------------------------------------------------------------------
1613 if (y <= fClusters[0]->GetY()) return 0;
1614 if (y > fClusters[fN-1]->GetY()) return fN;
1615 Int_t b=0, e=fN-1, m=(b+e)/2;
1616 for (; b<e; m=(b+e)/2) {
1617 if (y > fClusters[m]->GetY()) b=m+1;
1623 //_____________________________________________________________________________
1624 void AliTPCtracker::AliTPCseed::CookdEdx(Double_t low, Double_t up) {
1625 //-----------------------------------------------------------------
1626 // This funtion calculates dE/dX within the "low" and "up" cuts.
1627 //-----------------------------------------------------------------
1629 Int_t nc=GetNumberOfClusters();
1631 Int_t swap;//stupid sorting
1634 for (i=0; i<nc-1; i++) {
1635 if (fdEdxSample[i]<=fdEdxSample[i+1]) continue;
1636 Float_t tmp=fdEdxSample[i];
1637 fdEdxSample[i]=fdEdxSample[i+1]; fdEdxSample[i+1]=tmp;
1642 Int_t nl=Int_t(low*nc), nu=Int_t(up*nc);
1644 for (i=nl; i<=nu; i++) dedx += fdEdxSample[i];
1649 Double_t p=TMath::Sqrt((1.+ GetTgl()*GetTgl())/(Get1Pt()*Get1Pt()));
1651 Double_t log1=TMath::Log(p+0.45), log2=TMath::Log(p+0.12);
1653 if (dedx < 34 + 30/(p+0.45)/(p+0.45) + 24*log1) {SetMass(0.13957); return;}
1654 if (dedx < 34 + 30/(p+0.12)/(p+0.12) + 24*log2) {SetMass(0.49368); return;}
1655 SetMass(0.93827); return;
1659 if (dedx < 34 + 30/(p+0.12)/(p+0.12) + 24*log2) {SetMass(0.13957); return;}
1660 SetMass(0.93827); return;
1663 SetMass(0.13957); return;