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.32 2003/04/10 10:36:54 hristov
19 Code for unified TPC/TRD tracking (S.Radomski)
21 Revision 1.31 2003/03/19 17:14:11 hristov
22 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)
24 Revision 1.30 2003/02/28 16:13:32 hristov
27 Revision 1.29 2003/02/28 15:18:16 hristov
28 Corrections suggested by J.Chudoba
30 Revision 1.28 2003/02/27 16:15:52 hristov
31 Code for inward refitting (S.Radomski)
33 Revision 1.27 2003/02/25 16:47:58 hristov
34 allow back propagation for more than 1 event (J.Chudoba)
36 Revision 1.26 2003/02/19 08:49:46 hristov
37 Track time measurement (S.Radomski)
39 Revision 1.25 2003/01/28 16:43:35 hristov
40 Additional protection: to be discussed with the Root team (M.Ivanov)
42 Revision 1.24 2002/11/19 16:13:24 hristov
43 stdlib.h included to declare exit() on HP
45 Revision 1.23 2002/11/19 11:50:08 hristov
46 Removing CONTAINERS (Yu.Belikov)
48 Revision 1.19 2002/07/19 07:31:40 kowal2
49 Improvement in tracking by J. Belikov
51 Revision 1.18 2002/05/13 07:33:52 kowal2
52 Added protection in Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const
53 in the case of defined region of interests.
55 Revision 1.17 2002/03/18 17:59:13 kowal2
56 Chnges in the pad geometry - 3 pad lengths introduced.
58 Revision 1.16 2001/11/08 16:39:03 hristov
59 Additional protection (M.Masera)
61 Revision 1.15 2001/11/08 16:36:33 hristov
62 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)
64 Revision 1.14 2001/10/21 19:04:55 hristov
65 Several patches were done to adapt the barel reconstruction to the multi-event case. Some memory leaks were corrected. (Yu.Belikov)
67 Revision 1.13 2001/07/23 12:01:30 hristov
70 Revision 1.12 2001/07/20 14:32:44 kowal2
71 Processing of many events possible now
73 Revision 1.11 2001/05/23 08:50:10 hristov
76 Revision 1.10 2001/05/16 14:57:25 alibrary
77 New files for folders and Stack
79 Revision 1.9 2001/05/11 07:16:56 hristov
80 Fix needed on Sun and Alpha
82 Revision 1.8 2001/05/08 15:00:15 hristov
83 Corrections for tracking in arbitrary magnenetic field. Changes towards a concept of global Alice track. Back propagation of reconstructed tracks (Yu.Belikov)
85 Revision 1.5 2000/12/20 07:51:59 kowal2
86 Changes suggested by Alessandra and Paolo to avoid overlapped
87 data fields in encapsulated classes.
89 Revision 1.4 2000/11/02 07:27:16 kowal2
92 Revision 1.2 2000/06/30 12:07:50 kowal2
93 Updated from the TPC-PreRelease branch
95 Revision 1.1.2.1 2000/06/25 08:53:55 kowal2
96 Splitted from AliTPCtracking
100 //-------------------------------------------------------
101 // Implementation of the TPC tracker
103 // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
104 //-------------------------------------------------------
105 #include <TObjArray.h>
108 #include <Riostream.h>
112 #include "AliTPCtracker.h"
113 #include "AliTPCcluster.h"
114 #include "AliTPCParam.h"
115 #include "AliClusters.h"
117 #include "TVector2.h"
121 ClassImp(AliTPCtracker)
123 //_____________________________________________________________________________
124 AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
125 AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2)
127 //---------------------------------------------------------------------
128 // The main TPC tracker constructor
129 //---------------------------------------------------------------------
130 fInnerSec=new AliTPCSector[fkNIS];
131 fOuterSec=new AliTPCSector[fkNOS];
134 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
135 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
137 fParam = (AliTPCParam*) par;
149 //_____________________________________________________________________________
150 AliTPCtracker::~AliTPCtracker() {
151 //------------------------------------------------------------------
152 // TPC tracker destructor
153 //------------------------------------------------------------------
163 fBarrelFile->Close();
168 //_____________________________________________________________________________
170 void AliTPCtracker::SetBarrelTree(const char *mode) {
172 // Creates a tree for BarrelTracks
173 // mode = "back" or "refit"
178 if (!IsStoringBarrel()) return;
180 TDirectory *sav = gDirectory;
181 if (!fBarrelFile) fBarrelFile = new TFile("AliBarrelTracks.root", "UPDATE");
184 sprintf(buff, "BarrelTPC_%d_%s", GetEventNumber(), mode);
187 fBarrelTree = new TTree(buff, "Barrel TPC tracks");
189 if (!fBarrelArray) fBarrelArray = new TClonesArray("AliBarrelTrack", 4);
190 for(Int_t i=0; i<4; i++) new((*fBarrelArray)[i]) AliBarrelTrack();
192 fBarrelTree->Branch("tracks", &fBarrelArray);
196 //_____________________________________________________________________________
198 void AliTPCtracker::StoreBarrelTrack(AliTPCtrack *ps, Int_t refPlane, Int_t isIn) {
200 // Stores Track at a given reference plane
203 // isIn: 1 - backward, 2 - refit
206 if (!IsStoringBarrel()) return;
207 if (refPlane < 0 || refPlane > 4) return;
208 if (isIn > 2) return;
210 static Int_t nClusters;
212 static Double_t chi2;
215 Int_t newClusters, newWrong;
218 if ( (refPlane == 1 && isIn == kTrackBack) ||
219 (refPlane == 4 && isIn == kTrackRefit) ) {
221 fBarrelArray->Clear();
222 nClusters = nWrong = 0;
229 if (refPlane == 1) refX = fParam->GetInnerRadiusLow();
230 if (refPlane == 2) refX = fParam->GetInnerRadiusUp();
231 if (refPlane == 3) refX = fParam->GetOuterRadiusLow();
232 if (refPlane == 4) refX = fParam->GetOuterRadiusUp();
234 ps->PropagateTo(refX);
236 fBarrelTrack = (AliBarrelTrack*)(*fBarrelArray)[index++];
237 ps->GetBarrelTrack(fBarrelTrack);
239 newClusters = ps->GetNumberOfClusters() - nClusters;
240 newWrong = ps->GetNWrong() - nWrong;
241 newChi2 = ps->GetChi2() - chi2;
243 nClusters = ps->GetNumberOfClusters();
244 nWrong = ps->GetNWrong();
245 chi2 = ps->GetChi2();
247 fBarrelTrack->SetNClusters(newClusters, newChi2);
248 fBarrelTrack->SetNWrongClusters(newWrong);
249 fBarrelTrack->SetRefPlane(refPlane, isIn);
252 //_____________________________________________________________________________
253 Double_t SigmaY2(Double_t r, Double_t tgl, Double_t pt)
256 // Parametrised error of the cluster reconstruction (pad direction)
259 const Float_t kArphi=0.41818e-2;
260 const Float_t kBrphi=0.17460e-4;
261 const Float_t kCrphi=0.30993e-2;
262 const Float_t kDrphi=0.41061e-3;
264 pt=TMath::Abs(pt)*1000.;
267 Double_t s=kArphi - kBrphi*r*tgl + kCrphi*x*x + kDrphi*x;
268 if (s<0.4e-3) s=0.4e-3;
269 s*=1.3; //Iouri Belikov
274 //_____________________________________________________________________________
275 Double_t SigmaZ2(Double_t r, Double_t tgl)
278 // Parametrised error of the cluster reconstruction (drift direction)
281 const Float_t kAz=0.39614e-2;
282 const Float_t kBz=0.22443e-4;
283 const Float_t kCz=0.51504e-1;
287 Double_t s=kAz - kBz*r*tgl + kCz*tgl*tgl;
288 if (s<0.4e-3) s=0.4e-3;
289 s*=1.3; //Iouri Belikov
294 //_____________________________________________________________________________
295 Double_t f1(Double_t x1,Double_t y1,
296 Double_t x2,Double_t y2,
297 Double_t x3,Double_t y3)
299 //-----------------------------------------------------------------
300 // Initial approximation of the track curvature
301 //-----------------------------------------------------------------
302 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
303 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
304 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
305 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
306 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
308 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
310 return -xr*yr/sqrt(xr*xr+yr*yr);
314 //_____________________________________________________________________________
315 Double_t f2(Double_t x1,Double_t y1,
316 Double_t x2,Double_t y2,
317 Double_t x3,Double_t y3)
319 //-----------------------------------------------------------------
320 // Initial approximation of the track curvature times center of curvature
321 //-----------------------------------------------------------------
322 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
323 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
324 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
325 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
326 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
328 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
330 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
333 //_____________________________________________________________________________
334 Double_t f3(Double_t x1,Double_t y1,
335 Double_t x2,Double_t y2,
336 Double_t z1,Double_t z2)
338 //-----------------------------------------------------------------
339 // Initial approximation of the tangent of the track dip angle
340 //-----------------------------------------------------------------
341 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
344 Int_t AliTPCtracker::LoadClusters() {
345 return LoadClusters(gFile);
348 //_____________________________________________________________________________
349 Int_t AliTPCtracker::LoadClusters(const TFile *cf) {
350 //-----------------------------------------------------------------
351 // This function loads TPC clusters.
352 //-----------------------------------------------------------------
353 if (!((TFile*)cf)->IsOpen()) {
354 cerr<<"AliTPCtracker::LoadClusters : "<<
355 "file with clusters has not been open !\n";
360 sprintf(name,"TreeC_TPC_%d",GetEventNumber());
361 TTree *cTree=(TTree*)((TFile*)cf)->Get(name);
363 cerr<<"AliTPCtracker::LoadClusters : "<<
364 "can't get the tree with TPC clusters !\n";
368 TBranch *branch=cTree->GetBranch("Segment");
370 cerr<<"AliTPCtracker::LoadClusters : "<<
371 "can't get the segment branch !\n";
375 AliClusters carray, *addr=&carray;
376 carray.SetClass("AliTPCcluster");
378 branch->SetAddress(&addr);
380 Int_t nentr=(Int_t)cTree->GetEntries();
382 for (Int_t i=0; i<nentr; i++) {
385 Int_t ncl=carray.GetArray()->GetEntriesFast();
387 Int_t nir=fInnerSec->GetNRows(), nor=fOuterSec->GetNRows();
388 Int_t id=carray.GetID();
389 if ((id<0) || (id>2*(fkNIS*nir + fkNOS*nor))) {
390 cerr<<"AliTPCtracker::LoadClusters : "<<
394 Int_t outindex = 2*fkNIS*nir;
397 Int_t row = id - sec*nir;
399 AliTPCRow &padrow=fInnerSec[sec][row];
401 AliTPCcluster *c=(AliTPCcluster*)carray[ncl];
402 padrow.InsertCluster(c,sec,row);
407 Int_t row = id - sec*nor;
409 AliTPCRow &padrow=fOuterSec[sec][row];
411 AliTPCcluster *c=(AliTPCcluster*)carray[ncl];
412 padrow.InsertCluster(c,sec+fkNIS,row);
415 carray.GetArray()->Clear();
421 //_____________________________________________________________________________
422 void AliTPCtracker::UnloadClusters() {
423 //-----------------------------------------------------------------
424 // This function unloads TPC clusters.
425 //-----------------------------------------------------------------
427 for (i=0; i<fkNIS; i++) {
428 Int_t nr=fInnerSec->GetNRows();
429 for (Int_t n=0; n<nr; n++) fInnerSec[i][n].ResetClusters();
431 for (i=0; i<fkNOS; i++) {
432 Int_t nr=fOuterSec->GetNRows();
433 for (Int_t n=0; n<nr; n++) fOuterSec[i][n].ResetClusters();
437 //_____________________________________________________________________________
438 Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) {
439 //-----------------------------------------------------------------
440 // This function tries to find a track prolongation.
441 //-----------------------------------------------------------------
442 Double_t xt=t.GetX();
443 const Int_t kSKIP=(t.GetNumberOfClusters()<10) ? kRowsToSkip :
444 Int_t(0.5*fSectors->GetNRows());
445 Int_t tryAgain=kSKIP;
447 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
448 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
449 if (alpha < 0. ) alpha += 2.*TMath::Pi();
450 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
452 Int_t nrows=fSectors->GetRowNumber(xt)-1;
453 for (Int_t nr=nrows; nr>=rf; nr--) {
454 Double_t x=fSectors->GetX(nr), ymax=fSectors->GetMaxY(nr);
455 if (!t.PropagateTo(x)) return 0;
459 Double_t maxchi2=kMaxCHI2;
460 const AliTPCRow &krow=fSectors[s][nr];
461 Double_t pt=t.GetConvConst()/(100/0.299792458/0.2)/t.Get1Pt();
462 Double_t sy2=SigmaY2(t.GetX(),t.GetTgl(),pt);
463 Double_t sz2=SigmaZ2(t.GetX(),t.GetTgl());
464 Double_t road=4.*sqrt(t.GetSigmaY2() + sy2), y=t.GetY(), z=t.GetZ();
467 if (t.GetNumberOfClusters()>4)
468 cerr<<t.GetNumberOfClusters()
469 <<"FindProlongation warning: Too broad road !\n";
473 //if (fSectors == fInnerSec && (nr == 63 || nr == 0)) {
474 // cout << nr << "\t" << krow << endl;
478 for (Int_t i=krow.Find(y-road); i<krow; i++) {
479 AliTPCcluster *c=(AliTPCcluster*)(krow[i]);
480 if (c->GetY() > y+road) break;
481 if (c->IsUsed()) continue;
482 if ((c->GetZ()-z)*(c->GetZ()-z) > 16.*(t.GetSigmaZ2()+sz2)) continue;
483 Double_t chi2=t.GetPredictedChi2(c);
484 if (chi2 > maxchi2) continue;
487 index=krow.GetIndex(i);
491 Float_t l=fSectors->GetPadPitchWidth();
492 Float_t corr=1.; if (nr>63) corr=0.67; // new (third) pad response !
493 t.SetSampledEdx(cl->GetQ()/l*corr,t.GetNumberOfClusters());
494 if (!t.Update(cl,maxchi2,index)) {
495 if (!tryAgain--) return 0;
496 } else tryAgain=kSKIP;
498 if (tryAgain==0) break;
501 if (!t.Rotate(fSectors->GetAlpha())) return 0;
502 } else if (y <-ymax) {
504 if (!t.Rotate(-fSectors->GetAlpha())) return 0;
512 //_____________________________________________________________________________
514 Int_t AliTPCtracker::FollowRefitInward(AliTPCseed *seed, AliTPCtrack *track) {
516 // This function propagates seed inward TPC using old clusters
519 // Sylwester Radomski, GSI
523 Double_t alpha=seed->GetAlpha() - fSectors->GetAlphaShift();
524 TVector2::Phi_0_2pi(alpha);
525 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
527 Int_t idx=-1, sec=-1, row=-1;
528 Int_t nc = seed->GetNumber();
530 idx=track->GetClusterIndex(nc);
531 sec=(idx&0xff000000)>>24;
532 row=(idx&0x00ff0000)>>16;
534 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
535 else { if (sec < fkNIS) row=-1; }
537 Int_t nr=fSectors->GetNRows();
538 for (Int_t i=nr-1; i>=0; i--) {
541 //cout << i << "\t" << nc << "\t"<< row << "\t" << seed->Pt() << "\t" << track->Pt() << "\t\t";
543 Double_t x=fSectors->GetX(i);
544 if (!seed->PropagateTo(x)) return 0;
546 // Change sector and rotate seed if necessary
548 Double_t ymax=fSectors->GetMaxY(i);
549 Double_t y=seed->GetY();
553 if (!seed->Rotate(fSectors->GetAlpha())) return 0;
554 } else if (y <-ymax) {
556 if (!seed->Rotate(-fSectors->GetAlpha())) return 0;
559 // try to find a cluster
563 Double_t maxchi2 = kMaxCHI2;
567 //cout << row << endl;
568 // accept already found cluster
569 AliTPCcluster *c=(AliTPCcluster*)GetCluster(idx);
570 Double_t chi2 = seed->GetPredictedChi2(c);
576 //cout << c->GetY() << "\t" << seed->GetY() << "\t" << track->GetY();
578 if (--nc >= 0 /* track->GetNumberOfClusters()*/ ) {
579 idx=track->GetClusterIndex(nc);
580 sec=(idx&0xff000000)>>24;
581 row=(idx&0x00ff0000)>>16;
584 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
585 else { if (sec < fkNIS) row=-1; }
590 Float_t l=fSectors->GetPadPitchWidth();
591 Float_t corr=1.; if (i>63) corr=0.67; // new (third) pad response !
592 seed->SetSampledEdx(cl->GetQ()/l*corr,seed->GetNumberOfClusters());
593 seed->Update(cl,maxchi2,index);
601 //_____________________________________________________________________________
602 Int_t AliTPCtracker::FollowBackProlongation
603 (AliTPCseed& seed, const AliTPCtrack &track) {
604 //-----------------------------------------------------------------
605 // This function propagates tracks back through the TPC
606 //-----------------------------------------------------------------
607 Double_t alpha=seed.GetAlpha() - fSectors->GetAlphaShift();
608 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
609 if (alpha < 0. ) alpha += 2.*TMath::Pi();
610 Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
612 Int_t idx=-1, sec=-1, row=-1;
613 //Int_t nc=seed.GetLabel(); //index of the cluster to start with
614 Int_t nc=seed.GetNumber();
617 idx=track.GetClusterIndex(nc);
618 sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
620 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
621 else { if (sec < fkNIS) row=-1; }
623 Int_t nr=fSectors->GetNRows();
624 for (Int_t i=0; i<nr; i++) {
625 Double_t x=fSectors->GetX(i), ymax=fSectors->GetMaxY(i);
627 //cout << i << "\t" << nc << "\t" << row << "\t" << track.GetNumberOfClusters() << endl;
629 if (!seed.PropagateTo(x)) return 0;
631 Double_t y=seed.GetY();
634 if (!seed.Rotate(fSectors->GetAlpha())) return 0;
635 } else if (y <-ymax) {
637 if (!seed.Rotate(-fSectors->GetAlpha())) return 0;
642 Double_t maxchi2=kMaxCHI2;
643 Double_t pt=seed.GetConvConst()/(100/0.299792458/0.2)/seed.Get1Pt();
644 Double_t sy2=SigmaY2(seed.GetX(),seed.GetTgl(),pt);
645 Double_t sz2=SigmaZ2(seed.GetX(),seed.GetTgl());
646 Double_t road=4.*sqrt(seed.GetSigmaY2() + sy2), z=seed.GetZ();
648 cerr<<seed.GetNumberOfClusters()
649 <<"AliTPCtracker::FollowBackProlongation: Too broad road !\n";
653 Int_t accepted=seed.GetNumberOfClusters();
656 //if (fSectors == fInnerSec && row == 0)
657 //cout << "row == " << row << endl;
659 //try to accept already found cluster
660 AliTPCcluster *c=(AliTPCcluster*)GetCluster(idx);
662 if ((chi2=seed.GetPredictedChi2(c))<maxchi2 || accepted<27) {
663 index=idx; cl=c; maxchi2=chi2;
664 } //else cerr<<"AliTPCtracker::FollowBackProlongation: oulier !\n";
667 idx=track.GetClusterIndex(nc);
668 sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
670 if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
671 else { if (sec < fkNIS) row=-1; }
675 //try to fill the gap
676 const AliTPCRow &krow=fSectors[s][i];
679 for (Int_t i=krow.Find(y-road); i<krow; i++) {
680 AliTPCcluster *c=(AliTPCcluster*)(krow[i]);
681 if (c->GetY() > y+road) break;
682 if (c->IsUsed()) continue;
683 if ((c->GetZ()-z)*(c->GetZ()-z)>16.*(seed.GetSigmaZ2()+sz2)) continue;
684 Double_t chi2=seed.GetPredictedChi2(c);
685 if (chi2 > maxchi2) continue;
688 index=krow.GetIndex(i);
694 Float_t l=fSectors->GetPadPitchWidth();
695 Float_t corr=1.; if (i>63) corr=0.67; // new (third) pad response !
696 seed.SetSampledEdx(cl->GetQ()/l*corr,seed.GetNumberOfClusters());
697 seed.Update(cl,maxchi2,index);
708 //_____________________________________________________________________________
709 void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) {
710 //-----------------------------------------------------------------
711 // This function creates track seeds.
712 //-----------------------------------------------------------------
713 Double_t x[5], c[15];
715 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
716 Double_t cs=cos(alpha), sn=sin(alpha);
718 Double_t x1 =fSectors->GetX(i1);
719 Double_t xx2=fSectors->GetX(i2);
721 for (Int_t ns=0; ns<fN; ns++) {
722 Int_t nl=fSectors[(ns-1+fN)%fN][i2];
723 Int_t nm=fSectors[ns][i2];
724 Int_t nu=fSectors[(ns+1)%fN][i2];
725 const AliTPCRow& kr1=fSectors[ns][i1];
726 for (Int_t is=0; is < kr1; is++) {
727 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
728 for (Int_t js=0; js < nl+nm+nu; js++) {
729 const AliTPCcluster *kcl;
731 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
734 const AliTPCRow& kr2=fSectors[(ns-1+fN)%fN][i2];
736 y2=kcl->GetY(); z2=kcl->GetZ();
741 const AliTPCRow& kr2=fSectors[ns][i2];
743 x2=xx2; y2=kcl->GetY(); z2=kcl->GetZ();
745 const AliTPCRow& kr2=fSectors[(ns+1)%fN][i2];
747 y2=kcl->GetY(); z2=kcl->GetZ();
752 Double_t zz=z1 - (z1-z3)/(x1-x3)*(x1-x2);
753 if (TMath::Abs(zz-z2)>5.) continue;
755 Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
756 if (d==0.) {cerr<<"MakeSeeds warning: Straight seed !\n"; continue;}
760 x[4]=f1(x1,y1,x2,y2,x3,y3);
761 if (TMath::Abs(x[4]) >= 0.0066) continue;
762 x[2]=f2(x1,y1,x2,y2,x3,y3);
763 //if (TMath::Abs(x[4]*x1-x[2]) >= 0.99999) continue;
764 x[3]=f3(x1,y1,x2,y2,z1,z2);
765 if (TMath::Abs(x[3]) > 1.2) continue;
766 Double_t a=asin(x[2]);
767 Double_t zv=z1 - x[3]/x[4]*(a+asin(x[4]*x1-x[2]));
768 if (TMath::Abs(zv-z3)>10.) continue;
770 Double_t sy1=kr1[is]->GetSigmaY2(), sz1=kr1[is]->GetSigmaZ2();
771 Double_t sy2=kcl->GetSigmaY2(), sz2=kcl->GetSigmaZ2();
772 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
773 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
775 Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
776 Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
777 Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
778 Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
779 Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
780 Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
781 Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
782 Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
783 Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
784 Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
788 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
789 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
790 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
791 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
792 c[13]=f30*sy1*f40+f32*sy2*f42;
793 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
795 UInt_t index=kr1.GetIndex(is);
796 AliTPCseed *track=new AliTPCseed(index, x, c, x1, ns*alpha+shift);
797 Float_t l=fSectors->GetPadPitchWidth();
798 track->SetSampledEdx(kr1[is]->GetQ()/l,0);
800 Int_t rc=FollowProlongation(*track, i2);
801 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)/2) delete track;
802 else fSeeds->AddLast(track);
808 //_____________________________________________________________________________
809 Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
810 //-----------------------------------------------------------------
811 // This function reades track seeds.
812 //-----------------------------------------------------------------
813 TDirectory *savedir=gDirectory;
815 TFile *in=(TFile*)inp;
817 cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
822 TTree *seedTree=(TTree*)in->Get("Seeds");
824 cerr<<"AliTPCtracker::ReadSeeds(): ";
825 cerr<<"can't get a tree with track seeds !\n";
828 AliTPCtrack *seed=new AliTPCtrack;
829 seedTree->SetBranchAddress("tracks",&seed);
831 if (fSeeds==0) fSeeds=new TObjArray(15000);
833 Int_t n=(Int_t)seedTree->GetEntries();
834 for (Int_t i=0; i<n; i++) {
835 seedTree->GetEvent(i);
836 fSeeds->AddLast(new AliTPCseed(*seed,seed->GetAlpha()));
841 delete seedTree; //Thanks to Mariana Bondila
848 //_____________________________________________________________________________
849 Int_t AliTPCtracker::Clusters2Tracks(AliESD *event) {
850 //-----------------------------------------------------------------
851 // This is a track finder.
852 // The clusters must be already loaded !
853 //-----------------------------------------------------------------
856 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
857 Int_t nrows=nlow+nup;
859 Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
860 fSectors=fOuterSec; fN=fkNOS;
861 fSeeds=new TObjArray(15000);
862 MakeSeeds(nup-1, nup-1-gap);
863 MakeSeeds(nup-1-shift, nup-1-shift-gap);
867 Int_t nseed=fSeeds->GetEntriesFast();
868 for (Int_t i=0; i<nseed; i++) {
869 //tracking in the outer sectors
870 fSectors=fOuterSec; fN=fkNOS;
872 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
873 if (!FollowProlongation(t)) {
874 delete fSeeds->RemoveAt(i);
878 //tracking in the inner sectors
879 fSectors=fInnerSec; fN=fkNIS;
881 Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift();
882 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
883 if (alpha < 0. ) alpha += 2.*TMath::Pi();
884 Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS;
886 alpha=ns*fInnerSec->GetAlpha()+fInnerSec->GetAlphaShift()-t.GetAlpha();
888 if (t.Rotate(alpha)) {
889 if (FollowProlongation(t)) {
890 if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
892 CookLabel(pt,0.1); //For comparison only
893 pt->PropagateTo(fParam->GetInnerRadiusLow());
895 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
897 event->AddTrack(&iotrack);
903 delete fSeeds->RemoveAt(i);
906 cerr<<"Number of found tracks : "<<event->GetNumberOfTracks()<<endl;
908 fSeeds->Clear(); delete fSeeds; fSeeds=0;
913 //_____________________________________________________________________________
914 Int_t AliTPCtracker::Clusters2Tracks(const TFile *inp, TFile *out) {
915 //-----------------------------------------------------------------
916 // This is a track finder.
917 //-----------------------------------------------------------------
918 TDirectory *savedir=gDirectory;
921 TFile *in=(TFile*)inp;
923 cerr<<"AliTPCtracker::Clusters2Tracks(): input file is not open !\n";
928 if (!out->IsOpen()) {
929 cerr<<"AliTPCtracker::Clusters2Tracks(): output file is not open !\n";
938 sprintf(tname,"TreeT_TPC_%d",GetEventNumber());
939 TTree tracktree(tname,"Tree with TPC tracks");
940 AliTPCtrack *iotrack=0;
941 tracktree.Branch("tracks","AliTPCtrack",&iotrack,32000,3);
944 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
945 Int_t nrows=nlow+nup;
947 Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
948 fSectors=fOuterSec; fN=fkNOS;
949 fSeeds=new TObjArray(15000);
950 MakeSeeds(nup-1, nup-1-gap);
951 MakeSeeds(nup-1-shift, nup-1-shift-gap);
956 Int_t nseed=fSeeds->GetEntriesFast();
958 cout << fInnerSec->GetNRows() << " " << fOuterSec->GetNRows() << endl;
960 for (Int_t i=0; i<nseed; i++) {
961 //tracking in the outer sectors
962 fSectors=fOuterSec; fN=fkNOS;
964 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
965 if (!FollowProlongation(t)) {
966 delete fSeeds->RemoveAt(i);
970 //tracking in the inner sectors
971 fSectors=fInnerSec; fN=fkNIS;
973 Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift();
974 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
975 if (alpha < 0. ) alpha += 2.*TMath::Pi();
976 Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS;
978 alpha=ns*fInnerSec->GetAlpha()+fInnerSec->GetAlphaShift()-t.GetAlpha();
980 if (t.Rotate(alpha)) {
981 if (FollowProlongation(t)) {
982 if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
984 CookLabel(pt,0.1); //For comparison only
985 pt->PropagateTo(fParam->GetInnerRadiusLow());
990 // cerr<<found<<'\r';
994 delete fSeeds->RemoveAt(i);
999 cerr<<"Number of found tracks : "<<found<<endl;
1004 fSeeds->Clear(); delete fSeeds; fSeeds=0;
1008 //_____________________________________________________________________________
1010 Int_t AliTPCtracker::RefitInward(TFile *in, TFile *out) {
1012 // The function propagates tracks throught TPC inward
1013 // using already associated clusters.
1015 // in - file with back propagated tracks
1016 // outs - file with inward propagation
1018 // Sylwester Radomski, GSI
1022 if (!in->IsOpen()) {
1023 cout << "Input File not open !\n" << endl;
1027 if (!out->IsOpen()) {
1028 cout << "Output File not open !\n" << endl;
1032 TDirectory *savedir = gDirectory;
1035 // Connect to input tree
1037 TTree *inputTree = (TTree*)in->Get("seedsTPCtoTRD_0");
1038 TBranch *inBranch = inputTree->GetBranch("tracks");
1039 AliTPCtrack *inTrack = 0;
1040 inBranch->SetAddress(&inTrack);
1042 Int_t nTracks = (Int_t)inputTree->GetEntries();
1044 // Create output tree
1046 AliTPCtrack *outTrack = new AliTPCtrack();
1047 TTree *outputTree = new TTree("tracksTPC_0","Refited TPC tracks");
1048 outputTree->Branch("tracks", "AliTPCtrack", &outTrack, 32000, 3);
1050 // [SR, 01.04.2003] - Barrel tracks
1051 if (IsStoringBarrel()) SetBarrelTree("refit");
1055 for(Int_t t=0; t < nTracks; t++) {
1059 inputTree->GetEvent(t);
1060 inTrack->ResetCovariance();
1061 AliTPCseed *seed = new AliTPCseed(*inTrack, inTrack->GetAlpha());
1064 //cout << inTrack->GetNumberOfClusters() << endl;
1065 if (inTrack->GetNumberOfClusters() == 158) {
1066 cout << inTrack->GetNumberOfClusters() << endl;
1068 for(Int_t c=0; c<inTrack->GetNumberOfClusters(); c++) {
1069 Int_t idx = inTrack->GetClusterIndex(c);
1070 Int_t row=(idx&0x00ff0000)>>16;
1071 cout << c << " " << row << endl;
1076 if (IsStoringBarrel()) StoreBarrelTrack(seed, 4, 2);
1078 seed->SetNumber(inTrack->GetNumberOfClusters()-1);
1079 fSectors = fOuterSec;
1080 Int_t res = FollowRefitInward(seed, inTrack);
1082 Int_t nc = seed->GetNumberOfClusters();
1084 if (IsStoringBarrel()) StoreBarrelTrack(seed, 3, 2);
1085 if (IsStoringBarrel()) StoreBarrelTrack(seed, 2, 2);
1087 fSectors = fInnerSec;
1088 res = FollowRefitInward(seed, inTrack);
1089 UseClusters(seed, nc);
1091 if (IsStoringBarrel()) StoreBarrelTrack(seed, 1, 2);
1094 seed->PropagateTo(fParam->GetInnerRadiusLow());
1095 outTrack = (AliTPCtrack*)seed;
1096 outTrack->SetLabel(inTrack->GetLabel());
1101 if (IsStoringBarrel()) fBarrelTree->Fill();
1105 cout << "Refitted " << nRefited << " tracks." << endl;
1108 outputTree->Write();
1111 if (IsStoringBarrel()) {
1113 fBarrelTree->Write();
1114 fBarrelFile->Flush();
1116 delete fBarrelArray;
1120 if (inputTree) delete inputTree;
1121 if (outputTree) delete outputTree;
1129 //_____________________________________________________________________________
1130 Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
1131 //-----------------------------------------------------------------
1132 // This function propagates tracks back through the TPC.
1133 //-----------------------------------------------------------------
1134 return PropagateBack(inp, NULL, out);
1137 Int_t AliTPCtracker::PropagateBack(AliESD *event) {
1138 //-----------------------------------------------------------------
1139 // This function propagates tracks back through the TPC.
1140 // The clusters must be already loaded !
1141 //-----------------------------------------------------------------
1142 Int_t nentr=event->GetNumberOfTracks();
1143 Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
1146 for (Int_t i=0; i<nentr; i++) {
1147 AliESDtrack *esd=event->GetTrack(i);
1148 ULong_t status=esd->GetStatus();
1150 if ( (status & AliESDtrack::kTPCin ) == 0 ) continue;
1151 if ( (status & AliESDtrack::kTPCout) != 0 ) continue;
1153 const AliTPCtrack t(*esd);
1154 AliTPCseed s(t,t.GetAlpha());
1156 if (status==AliESDtrack::kTPCin) s.ResetCovariance();
1157 else if ( (status & AliESDtrack::kITSout) == 0 ) continue;
1159 Int_t nc=t.GetNumberOfClusters();
1160 s.SetLabel(nc-1); //set number of the cluster to start with
1163 fSectors=fInnerSec; fN=fkNIS;
1165 Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift();
1166 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1167 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1168 Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
1169 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
1170 alpha-=s.GetAlpha();
1172 if (!s.Rotate(alpha)) continue;
1173 if (!FollowBackProlongation(s,t)) continue;
1177 fSectors=fOuterSec; fN=fkNOS;
1179 alpha=s.GetAlpha() - fSectors->GetAlphaShift();
1180 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1181 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1182 ns=Int_t(alpha/fSectors->GetAlpha())%fN;
1184 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
1185 alpha-=s.GetAlpha();
1187 if (!s.Rotate(alpha)) continue;
1188 if (!FollowBackProlongation(s,t)) continue;
1190 Int_t nrows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
1191 if (s.GetNumberOfClusters() < Int_t(0.4*nrows)) continue;
1193 s.PropagateTo(fParam->GetOuterRadiusUp());
1195 CookLabel(&s,0.1); //For comparison only
1197 esd->UpdateTrackParams(&s,AliESDtrack::kTPCout);
1200 cerr<<"Number of back propagated tracks: "<<ntrk<<endl;
1205 //_____________________________________________________________________________
1206 Int_t AliTPCtracker::PropagateBack(const TFile *inp, const TFile *inp2, TFile *out) {
1207 //-----------------------------------------------------------------
1208 // This function propagates tracks back through the TPC.
1209 //-----------------------------------------------------------------
1210 fSeeds=new TObjArray(15000);
1212 TFile *in=(TFile*)inp;
1213 TFile *in2=(TFile*)inp2;
1214 TDirectory *savedir=gDirectory;
1216 if (!in->IsOpen()) {
1217 cerr<<"AliTPCtracker::PropagateBack(): ";
1218 cerr<<"file with TPC (or back propagated ITS) tracks is not open !\n";
1222 if (!out->IsOpen()) {
1223 cerr<<"AliTPCtracker::PropagateBack(): ";
1224 cerr<<"file for back propagated TPC tracks is not open !\n";
1232 sprintf(tName,"TreeT_ITSb_%d",GetEventNumber());
1233 TTree *bckTree=(TTree*)in->Get(tName);
1234 if (!bckTree && inp2) bckTree=(TTree*)in2->Get(tName);
1236 cerr<<"AliTPCtracker::PropagateBack() ";
1237 cerr<<"can't get a tree with back propagated ITS tracks !\n";
1240 AliTPCtrack *bckTrack=new AliTPCtrack;
1241 if (bckTree) bckTree->SetBranchAddress("tracks",&bckTrack);
1243 sprintf(tName,"TreeT_TPC_%d",GetEventNumber());
1244 TTree *tpcTree=(TTree*)in->Get(tName);
1246 cerr<<"AliTPCtracker::PropagateBack() ";
1247 cerr<<"can't get a tree with TPC tracks !\n";
1250 AliTPCtrack *tpcTrack=new AliTPCtrack;
1251 tpcTree->SetBranchAddress("tracks",&tpcTrack);
1253 // [SR, 01.04.2003] - Barrel tracks
1254 if (IsStoringBarrel()) SetBarrelTree("back");
1256 //*** Prepare an array of tracks to be back propagated
1257 Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
1258 Int_t nrows=nlow+nup;
1261 // Match ITS tracks with old TPC tracks
1262 // the tracks do not have to be sorted [SR, GSI, 18.02.2003]
1264 // the algorithm is linear and uses LUT for sorting
1265 // cost of the algorithm: 2 * number of tracks
1268 TObjArray tracks(15000);
1270 Int_t tpcN= (Int_t)tpcTree->GetEntries();
1271 Int_t bckN= (bckTree)? (Int_t)bckTree->GetEntries() : 0;
1274 const Int_t nLab = 200000; // limit on number of primaries (arbitrary)
1276 for(Int_t i=0; i<nLab; i++) lut[i] = -1;
1279 for(Int_t i=0; i<bckN; i++) {
1280 bckTree->GetEvent(i);
1281 Int_t lab = TMath::Abs(bckTrack->GetLabel());
1282 if (lab < nLab) lut[lab] = i;
1284 cerr << "AliTPCtracker: The size of the LUT is too small\n";
1289 for (Int_t i=0; i<tpcN; i++) {
1290 tpcTree->GetEvent(i);
1291 Double_t alpha=tpcTrack->GetAlpha();
1295 // No ITS - use TPC track only
1297 tpcTrack->ResetCovariance();
1298 AliTPCseed * seed = new AliTPCseed(*tpcTrack, tpcTrack->GetAlpha());
1300 fSeeds->AddLast(seed);
1301 tracks.AddLast(new AliTPCtrack(*tpcTrack));
1306 // discard not prolongated tracks (to be discussed)
1308 Int_t lab = TMath::Abs(tpcTrack->GetLabel());
1309 if (lab > nLab || lut[lab] < 0) continue;
1311 bckTree->GetEvent(lut[lab]);
1312 bckTrack->Rotate(alpha-bckTrack->GetAlpha());
1314 fSeeds->AddLast(new AliTPCseed(*bckTrack,bckTrack->GetAlpha()));
1315 tracks.AddLast(new AliTPCtrack(*tpcTrack));
1322 TObjArray tracks(15000);
1324 Int_t tpcN=(Int_t)tpcTree->GetEntries();
1325 Int_t bckN=(Int_t)bckTree->GetEntries();
1326 if (j<bckN) bckTree->GetEvent(j++);
1327 for (i=0; i<tpcN; i++) {
1328 tpcTree->GetEvent(i);
1329 Double_t alpha=tpcTrack->GetAlpha();
1331 TMath::Abs(tpcTrack->GetLabel())==TMath::Abs(bckTrack->GetLabel())) {
1332 if (!bckTrack->Rotate(alpha-bckTrack->GetAlpha())) continue;
1333 fSeeds->AddLast(new AliTPCseed(*bckTrack,bckTrack->GetAlpha()));
1334 bckTree->GetEvent(j++);
1336 tpcTrack->ResetCovariance();
1337 fSeeds->AddLast(new AliTPCseed(*tpcTrack,alpha));
1339 tracks.AddLast(new AliTPCtrack(*tpcTrack));
1345 // tree name seedsTPCtoTRD as expected by TRD and as
1346 // discussed and decided in Strasbourg (May 2002)
1347 // [SR, GSI, 18.02.2003]
1349 sprintf(tName,"seedsTPCtoTRD_%d",GetEventNumber());
1350 TTree backTree(tName,"Tree with back propagated TPC tracks");
1352 AliTPCtrack *otrack=0;
1353 backTree.Branch("tracks","AliTPCtrack",&otrack,32000,0);
1358 Int_t nseed=fSeeds->GetEntriesFast();
1360 // loop changed [SR, 01.04.2003]
1362 for (i=0; i<nseed; i++) {
1365 if (IsStoringBarrel()) fBarrelArray->Clear();
1367 AliTPCseed *ps=(AliTPCseed*)fSeeds->UncheckedAt(i), &s=*ps;
1368 const AliTPCtrack *pt=(AliTPCtrack*)tracks.UncheckedAt(i), &t=*pt;
1371 ps->ResetNRotation();
1373 if (IsStoringBarrel()) StoreBarrelTrack(ps, 1, 1);
1375 // Load outer sectors
1379 Int_t nc=t.GetNumberOfClusters();
1380 //s.SetLabel(nc-1); //set number of the cluster to start with
1383 if (FollowBackProlongation(s,t)) UseClusters(&s);
1385 fSeeds->RemoveAt(i);
1389 if (IsStoringBarrel()) StoreBarrelTrack(ps, 2, 1);
1390 if (IsStoringBarrel()) StoreBarrelTrack(ps, 3, 1);
1392 // Load outer sectors
1396 nc=s.GetNumberOfClusters();
1398 Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift();
1399 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1400 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1401 Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
1403 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
1404 alpha-=s.GetAlpha();
1406 if (s.Rotate(alpha)) {
1407 if (FollowBackProlongation(s,t)) {
1408 if (s.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
1410 s.SetLabel(t.GetLabel());
1413 // Propagate to outer reference plane for comparison reasons
1414 // reason for keeping fParam object [SR, GSI, 18.02.2003]
1416 ps->PropagateTo(fParam->GetOuterRadiusUp());
1420 if (IsStoringBarrel()) StoreBarrelTrack(ps, 4, 1);
1421 cerr<<found++<<'\r';
1426 if (IsStoringBarrel()) fBarrelTree->Fill();
1427 delete fSeeds->RemoveAt(i);
1435 if (IsStoringBarrel()) {
1437 fBarrelTree->Write();
1438 fBarrelFile->Flush();
1440 delete fBarrelArray;
1445 cerr<<"Number of seeds: "<<nseed<<endl;
1446 cerr<<"Number of back propagated ITS tracks: "<<bckN<<endl;
1447 cerr<<"Number of back propagated TPC tracks: "<<found<<endl;
1452 if (bckTree) delete bckTree; //Thanks to Mariana Bondila
1453 delete tpcTree; //Thanks to Mariana Bondila
1460 //_________________________________________________________________________
1461 AliCluster *AliTPCtracker::GetCluster(Int_t index) const {
1462 //--------------------------------------------------------------------
1463 // Return pointer to a given cluster
1464 //--------------------------------------------------------------------
1465 Int_t sec=(index&0xff000000)>>24;
1466 Int_t row=(index&0x00ff0000)>>16;
1467 Int_t ncl=(index&0x0000ffff)>>00;
1469 const AliTPCcluster *cl=0;
1472 cl=fInnerSec[sec][row].GetUnsortedCluster(ncl);
1475 cl=fOuterSec[sec][row].GetUnsortedCluster(ncl);
1478 return (AliCluster*)cl;
1481 //__________________________________________________________________________
1482 void AliTPCtracker::CookLabel(AliKalmanTrack *t, Float_t wrong) const {
1483 //--------------------------------------------------------------------
1484 //This function "cooks" a track label. If label<0, this track is fake.
1485 //--------------------------------------------------------------------
1486 Int_t noc=t->GetNumberOfClusters();
1487 Int_t *lb=new Int_t[noc];
1488 Int_t *mx=new Int_t[noc];
1489 AliCluster **clusters=new AliCluster*[noc];
1492 for (i=0; i<noc; i++) {
1494 Int_t index=t->GetClusterIndex(i);
1495 clusters[i]=GetCluster(index);
1498 Int_t lab=123456789;
1499 for (i=0; i<noc; i++) {
1500 AliCluster *c=clusters[i];
1501 lab=TMath::Abs(c->GetLabel(0));
1503 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
1509 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
1511 for (i=0; i<noc; i++) {
1512 AliCluster *c=clusters[i];
1513 if (TMath::Abs(c->GetLabel(1)) == lab ||
1514 TMath::Abs(c->GetLabel(2)) == lab ) max++;
1517 if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
1520 Int_t tail=Int_t(0.10*noc);
1522 for (i=1; i<=tail; i++) {
1523 AliCluster *c=clusters[noc-i];
1524 if (lab == TMath::Abs(c->GetLabel(0)) ||
1525 lab == TMath::Abs(c->GetLabel(1)) ||
1526 lab == TMath::Abs(c->GetLabel(2))) max++;
1528 if (max < Int_t(0.5*tail)) lab=-lab;
1538 //_________________________________________________________________________
1539 void AliTPCtracker::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
1540 //-----------------------------------------------------------------------
1541 // Setup inner sector
1542 //-----------------------------------------------------------------------
1544 fAlpha=par->GetInnerAngle();
1545 fAlphaShift=par->GetInnerAngleShift();
1546 fPadPitchWidth=par->GetInnerPadPitchWidth();
1547 f1PadPitchLength=par->GetInnerPadPitchLength();
1548 f2PadPitchLength=f1PadPitchLength;
1550 fN=par->GetNRowLow();
1551 fRow=new AliTPCRow[fN];
1552 for (Int_t i=0; i<fN; i++) fRow[i].SetX(par->GetPadRowRadiiLow(i));
1554 fAlpha=par->GetOuterAngle();
1555 fAlphaShift=par->GetOuterAngleShift();
1556 fPadPitchWidth=par->GetOuterPadPitchWidth();
1557 f1PadPitchLength=par->GetOuter1PadPitchLength();
1558 f2PadPitchLength=par->GetOuter2PadPitchLength();
1560 fN=par->GetNRowUp();
1561 fRow=new AliTPCRow[fN];
1562 for (Int_t i=0; i<fN; i++){
1563 fRow[i].SetX(par->GetPadRowRadiiUp(i));
1568 //_________________________________________________________________________
1569 void AliTPCtracker::
1570 AliTPCRow::InsertCluster(const AliTPCcluster* c, Int_t sec, Int_t row) {
1571 //-----------------------------------------------------------------------
1572 // Insert a cluster into this pad row in accordence with its y-coordinate
1573 //-----------------------------------------------------------------------
1574 if (fN==kMaxClusterPerRow) {
1575 cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
1578 Int_t index=(((sec<<8)+row)<<16)+fN;
1582 fClusterArray[0]=*c; fClusters[fN++]=fClusterArray;
1588 AliTPCcluster *buff=new AliTPCcluster[size];
1589 memcpy(buff,fClusterArray,fSize*sizeof(AliTPCcluster));
1590 for (Int_t i=0; i<fN; i++)
1591 fClusters[i]=buff+(fClusters[i]-fClusterArray);
1592 delete[] fClusterArray;
1597 Int_t i=Find(c->GetY());
1598 memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCcluster*));
1599 memmove(fIndex +i+1 ,fIndex +i,(fN-i)*sizeof(UInt_t));
1601 fClusters[i]=fClusterArray+fN; fClusterArray[fN++]=*c;
1604 //___________________________________________________________________
1605 Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const {
1606 //-----------------------------------------------------------------------
1607 // Return the index of the nearest cluster
1608 //-----------------------------------------------------------------------
1610 if (y <= fClusters[0]->GetY()) return 0;
1611 if (y > fClusters[fN-1]->GetY()) return fN;
1612 Int_t b=0, e=fN-1, m=(b+e)/2;
1613 for (; b<e; m=(b+e)/2) {
1614 if (y > fClusters[m]->GetY()) b=m+1;
1620 //_____________________________________________________________________________
1621 void AliTPCtracker::AliTPCseed::CookdEdx(Double_t low, Double_t up) {
1622 //-----------------------------------------------------------------
1623 // This funtion calculates dE/dX within the "low" and "up" cuts.
1624 //-----------------------------------------------------------------
1626 Int_t nc=GetNumberOfClusters();
1628 Int_t swap;//stupid sorting
1631 for (i=0; i<nc-1; i++) {
1632 if (fdEdxSample[i]<=fdEdxSample[i+1]) continue;
1633 Float_t tmp=fdEdxSample[i];
1634 fdEdxSample[i]=fdEdxSample[i+1]; fdEdxSample[i+1]=tmp;
1639 Int_t nl=Int_t(low*nc), nu=Int_t(up*nc);
1641 for (i=nl; i<=nu; i++) dedx += fdEdxSample[i];
1646 Double_t p=TMath::Sqrt((1.+ GetTgl()*GetTgl())/(Get1Pt()*Get1Pt()));
1648 Double_t log1=TMath::Log(p+0.45), log2=TMath::Log(p+0.12);
1650 if (dedx < 34 + 30/(p+0.45)/(p+0.45) + 24*log1) {SetMass(0.13957); return;}
1651 if (dedx < 34 + 30/(p+0.12)/(p+0.12) + 24*log2) {SetMass(0.49368); return;}
1652 SetMass(0.93827); return;
1656 if (dedx < 34 + 30/(p+0.12)/(p+0.12) + 24*log2) {SetMass(0.13957); return;}
1657 SetMass(0.93827); return;
1660 SetMass(0.13957); return;