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.9 2001/02/14 18:22:26 cblume
19 Change in the geometry of the padplane
21 Revision 1.8 2000/12/20 13:00:44 cblume
22 Modifications for the HP-compiler
24 Revision 1.7 2000/12/08 16:07:02 cblume
25 Update of the tracking by Sergei
27 Revision 1.6 2000/11/30 17:38:08 cblume
28 Changes to get in line with new STEER and EVGEN
30 Revision 1.5 2000/11/14 14:40:27 cblume
31 Correction for the Sun compiler (kTRUE and kFALSE)
33 Revision 1.4 2000/11/10 14:57:52 cblume
34 Changes in the geometry constants for the DEC compiler
36 Revision 1.3 2000/10/15 23:40:01 cblume
39 Revision 1.2 2000/10/06 16:49:46 cblume
42 Revision 1.1.2.2 2000/10/04 16:34:58 cblume
43 Replace include files by forward declarations
45 Revision 1.1.2.1 2000/09/22 14:47:52 cblume
59 #include "AliTRDgeometry.h"
60 #include "AliTRDrecPoint.h"
61 #include "AliTRDcluster.h"
62 #include "AliTRDtrack.h"
63 #include "AliTRDtrackingSector.h"
64 #include "AliTRDtimeBin.h"
66 #include "AliTRDtracker.h"
68 ClassImp(AliTRDtracker)
70 const Int_t AliTRDtracker::fSeedGap = 35;
71 const Int_t AliTRDtracker::fSeedStep = 5;
74 const Float_t AliTRDtracker::fMinClustersInTrack = 0.5;
75 const Float_t AliTRDtracker::fMinClustersInSeed = 0.5;
76 const Float_t AliTRDtracker::fSeedDepth = 0.5;
77 const Float_t AliTRDtracker::fSkipDepth = 0.2;
78 const Float_t AliTRDtracker::fMaxSeedDeltaZ = 30.;
79 const Float_t AliTRDtracker::fMaxSeedC = 0.01;
80 const Float_t AliTRDtracker::fMaxSeedTan = 1.2;
81 const Float_t AliTRDtracker::fMaxSeedVertexZ = 200.;
82 const Float_t AliTRDtracker::fLabelFraction = 0.5;
83 const Float_t AliTRDtracker::fWideRoad = 30.;
85 const Double_t AliTRDtracker::fMaxChi2 = 12.;
86 const Double_t AliTRDtracker::fSeedErrorSY = 0.1;
87 const Double_t AliTRDtracker::fSeedErrorSY3 = 2.5;
88 const Double_t AliTRDtracker::fSeedErrorSZ = 0.1;
90 //____________________________________________________________________
91 AliTRDtracker::AliTRDtracker()
94 // Default constructor
109 //____________________________________________________________________
110 AliTRDtracker::AliTRDtracker(const Text_t* name, const Text_t* title)
117 fClusters = new TObjArray(2000);
119 fSeeds = new TObjArray(20000);
121 fTracks = new TObjArray(10000);
125 //___________________________________________________________________
126 AliTRDtracker::~AliTRDtracker()
134 //___________________________________________________________________
135 void AliTRDtracker::Clusters2Tracks()
138 Int_t fTotalNofTimeBins = fGeom->GetTimeMax() * AliTRDgeometry::Nplan();
139 Int_t nSteps = (Int_t) (fTotalNofTimeBins * fSeedDepth)/fSeedStep;
141 for(Int_t i=0; i<nSteps; i++) {
142 printf("step %d out of %d \n", i+1, nSteps);
143 outer=fTotalNofTimeBins-1-i*fSeedStep; inner=outer-fSeedGap;
144 MakeSeeds(inner,outer);
149 //_____________________________________________________________________
150 Double_t AliTRDtracker::ExpectedSigmaY2(Double_t r, Double_t tgl, Double_t pt)
152 // Parametrised "expected" error of the cluster reconstruction in Y
158 //_____________________________________________________________________
159 Double_t AliTRDtracker::ExpectedSigmaZ2(Double_t r, Double_t tgl)
161 // Parametrised "expected" error of the cluster reconstruction in Z
163 // Take an example pad size for the time being, check back
165 Double_t s, pad = fGeom->GetRowPadSize(0,2,0);
170 //_____________________________________________________________________
171 inline Double_t f1trd(Double_t x1,Double_t y1,
172 Double_t x2,Double_t y2,
173 Double_t x3,Double_t y3)
175 // Initial approximation of the track curvature
176 // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
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));
184 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
186 return -xr*yr/sqrt(xr*xr+yr*yr);
189 //_____________________________________________________________________
190 inline Double_t f2trd(Double_t x1,Double_t y1,
191 Double_t x2,Double_t y2,
192 Double_t x3,Double_t y3)
194 // Initial approximation of the track curvature times center of curvature
195 // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
197 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
198 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
199 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
200 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
201 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
203 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
205 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
208 //_____________________________________________________________________
209 inline Double_t f3trd(Double_t x1,Double_t y1,
210 Double_t x2,Double_t y2,
211 Double_t z1,Double_t z2)
213 // Initial approximation of the tangent of the track dip angle
214 // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
216 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
220 //___________________________________________________________________
222 Int_t AliTRDtracker::FindProlongation(AliTRDtrack& t, AliTRDtrackingSector *sec,
225 // Starting from current position on track=t this function tries
226 // to extrapolate the track up to timeBin=rf and to confirm prolongation
227 // if a close cluster is found. *sec is a pointer to allocated
228 // array of sectors, in which the initial sector has index=s.
230 const Int_t TIME_BINS_TO_SKIP=Int_t(fSkipDepth*sec->GetNtimeBins());
231 Int_t try_again=TIME_BINS_TO_SKIP;
233 Double_t alpha=AliTRDgeometry::GetAlpha();
235 Int_t ns=Int_t(2*TMath::Pi()/alpha+0.5);
237 for (Int_t nr=sec->GetTimeBinNumber(t.GetX())-1; nr>=rf; nr--) {
238 Double_t x=sec->GetX(nr), ymax=sec->GetMaxY(nr);
239 if (!t.PropagateTo(x)) {
240 cerr<<"Can't propagate to x = "<<x<<endl;
247 Double_t max_chi2=fMaxChi2;
249 AliTRDtimeBin& time_bin=sec[s][nr];
250 Double_t sy2=ExpectedSigmaY2(t.GetX(),t.GetTgl(),t.GetPt());
251 Double_t sz2=ExpectedSigmaZ2(t.GetX(),t.GetTgl());
252 Double_t road=5.*sqrt(t.GetSigmaY2() + sy2), y=t.GetY(), z=t.GetZ();
254 if (road>fWideRoad) {
255 if (t.GetNclusters() > 4) {
256 cerr<<t.GetNclusters()<<" FindProlongation: Road is too wide !\n";
262 for (Int_t i=time_bin.Find(y-road); i<time_bin; i++) {
263 AliTRDcluster* c=(AliTRDcluster*)(time_bin[i]);
264 if (c->GetY() > y+road) break;
265 if (c->IsUsed() > 0) continue;
267 if((c->GetZ()-z)*(c->GetZ()-z) > 25. + sz2) continue;
269 Double_t chi2=t.GetPredictedChi2(c);
271 if (chi2 > max_chi2) continue;
274 index=time_bin.GetIndex(i);
279 // Float_t l=sec->GetPitch();
280 // t.SetSampledEdx(cl->fQ/l,Int_t(t));
282 t.Update(cl,max_chi2,index);
284 try_again=TIME_BINS_TO_SKIP;
286 if (try_again==0) break;
288 cerr<<"y > ymax: "<<y<<" > "<<ymax<<endl;
290 if (!t.Rotate(alpha)) {
291 cerr<<"Failed to rotate, alpha = "<<alpha<<endl;
294 } else if (y <-ymax) {
295 cerr<<"y < -ymax: "<<y<<" < "<<-ymax<<endl;
297 if (!t.Rotate(-alpha)) {
298 cerr<<"Failed to rotate, alpha = "<<alpha<<endl;
311 //_____________________________________________________________________________
312 void AliTRDtracker::GetEvent(const Char_t *hitfile, const Char_t *clusterfile)
314 // Opens a ROOT-file with TRD-clusters and reads in the cluster-tree
316 ReadClusters(fClusters, clusterfile);
318 // get geometry from the file with hits
320 TFile *fInputFile = (TFile*) gROOT->GetListOfFiles()->FindObject(hitfile);
322 printf("AliTRDtracker::Open -- ");
323 printf("Open the ALIROOT-file %s.\n",hitfile);
324 fInputFile = new TFile(hitfile);
327 printf("AliTRDtracker::Open -- ");
328 printf("%s is already open.\n",hitfile);
331 // Get AliRun object from file or create it if not on file
333 gAlice = (AliRun*) fInputFile->Get("gAlice");
335 printf("AliTRDtracker::GetEvent -- ");
336 printf("AliRun object found on file.\n");
339 printf("AliTRDtracker::GetEvent -- ");
340 printf("Could not find AliRun object.\n");
343 // Import the Trees for the event nEvent in the file
344 Int_t nparticles = gAlice->GetEvent(fEvent);
345 cerr<<"nparticles = "<<nparticles<<endl;
347 if (nparticles <= 0) {
348 printf("AliTRDtracker::GetEvent -- ");
349 printf("No entries in the trees for event %d.\n",fEvent);
352 AliTRD *TRD = (AliTRD*) gAlice->GetDetector("TRD");
353 fGeom = TRD->GetGeometry();
358 //_____________________________________________________________________________
359 void AliTRDtracker::SetUpSectors(AliTRDtrackingSector *sec)
361 // Fills clusters into TRD tracking_sectors
362 // Note that the numbering scheme for the TRD tracking_sectors
363 // differs from that of TRD sectors
365 for (Int_t i=0; i<AliTRDgeometry::Nsect(); i++) sec[i].SetUp();
367 // Sort clusters into AliTRDtimeBin's within AliTRDtrackSector's
369 cerr<<"MakeSeeds: sorting clusters"<<endl;
371 Int_t ncl=fClusters->GetEntriesFast();
374 printf("\r %d left",ncl);
375 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(ncl);
376 Int_t detector=c->GetDetector(), local_time_bin=c->GetLocalTimeBin();
377 Int_t sector=fGeom->GetSector(detector);
379 Int_t tracking_sector=sector;
380 if(sector > 0) tracking_sector = AliTRDgeometry::kNsect - sector;
382 Int_t tb=sec[sector].GetTimeBin(detector,local_time_bin);
384 sec[tracking_sector][tb].InsertCluster(c,index);
390 //_____________________________________________________________________________
391 void AliTRDtracker::MakeSeeds(Int_t inner, Int_t outer)
393 // Creates track seeds using clusters in timeBins=i1,i2
395 Int_t i2 = inner, i1 = outer;
397 if (!fClusters) return;
399 AliTRDtrackingSector fTrSec[AliTRDgeometry::kNsect];
400 SetUpSectors(fTrSec);
404 Double_t x[5], c[15];
405 Int_t max_sec=AliTRDgeometry::kNsect;
407 Double_t alpha=AliTRDgeometry::GetAlpha();
408 Double_t shift=AliTRDgeometry::GetAlpha()/2.;
409 Double_t cs=cos(alpha), sn=sin(alpha);
411 Double_t x1 =fTrSec[0].GetX(i1);
412 Double_t xx2=fTrSec[0].GetX(i2);
414 for (Int_t ns=0; ns<max_sec; ns++) {
416 Int_t nl=fTrSec[(ns-1+max_sec)%max_sec][i2];
417 Int_t nm=fTrSec[ns][i2];
418 Int_t nu=fTrSec[(ns+1)%max_sec][i2];
420 AliTRDtimeBin& r1=fTrSec[ns][i1];
422 for (Int_t is=0; is < r1; is++) {
423 Double_t y1=r1[is]->GetY(), z1=r1[is]->GetZ();
425 for (Int_t js=0; js < nl+nm+nu; js++) {
426 const AliTRDcluster *cl;
428 Double_t x3=0.,y3=0.;
431 AliTRDtimeBin& r2=fTrSec[(ns-1+max_sec)%max_sec][i2];
433 y2=cl->GetY(); z2=cl->GetZ();
440 AliTRDtimeBin& r2=fTrSec[ns][i2];
442 x2=xx2; y2=cl->GetY(); z2=cl->GetZ();
444 AliTRDtimeBin& r2=fTrSec[(ns+1)%max_sec][i2];
446 y2=cl->GetY(); z2=cl->GetZ();
453 Double_t zz=z1 - z1/x1*(x1-x2);
455 if (TMath::Abs(zz-z2)>fMaxSeedDeltaZ) continue;
457 Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
458 if (d==0.) {cerr<<"TRD MakeSeeds: Straight seed !\n"; continue;}
462 x[2]=f1trd(x1,y1,x2,y2,x3,y3);
464 if (TMath::Abs(x[2]) >= fMaxSeedC) continue;
466 x[3]=f2trd(x1,y1,x2,y2,x3,y3);
468 if (TMath::Abs(x[2]*x1-x[3]) >= 0.99999) continue;
470 x[4]=f3trd(x1,y1,x2,y2,z1,z2);
472 if (TMath::Abs(x[4]) > fMaxSeedTan) continue;
474 Double_t a=asin(x[3]);
475 Double_t zv=z1 - x[4]/x[2]*(a+asin(x[2]*x1-x[3]));
476 if (TMath::Abs(zv)>fMaxSeedVertexZ) continue;
478 Double_t sy1=r1[is]->GetSigmaY2(), sz1=r1[is]->GetSigmaZ2();
479 Double_t sy2=cl->GetSigmaY2(), sz2=cl->GetSigmaZ2();
480 Double_t sy3=fSeedErrorSY3, sy=fSeedErrorSY, sz=fSeedErrorSZ;
482 Double_t f20=(f1trd(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
483 Double_t f22=(f1trd(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
484 Double_t f24=(f1trd(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
485 Double_t f30=(f2trd(x1,y1+sy,x2,y2,x3,y3)-x[3])/sy;
486 Double_t f32=(f2trd(x1,y1,x2,y2+sy,x3,y3)-x[3])/sy;
487 Double_t f34=(f2trd(x1,y1,x2,y2,x3,y3+sy)-x[3])/sy;
488 Double_t f40=(f3trd(x1,y1+sy,x2,y2,z1,z2)-x[4])/sy;
489 Double_t f41=(f3trd(x1,y1,x2,y2,z1+sz,z2)-x[4])/sz;
490 Double_t f42=(f3trd(x1,y1,x2,y2+sy,z1,z2)-x[4])/sy;
491 Double_t f43=(f3trd(x1,y1,x2,y2,z1,z2+sz)-x[4])/sz;
495 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f24*sy3*f24;
496 c[6]=f30*sy1; c[7]=0.; c[8]=f30*sy1*f20+f32*sy2*f22+f34*sy3*f24;
497 c[9]=f30*sy1*f30+f32*sy2*f32+f34*sy3*f34;
498 c[10]=f40*sy1; c[11]=f41*sz1; c[12]=f40*sy1*f20+f42*sy2*f22;
499 c[13]=f40*sy1*f30+f42*sy2*f32;
500 c[14]=f40*sy1*f40+f41*sz1*f41+f42*sy2*f42+f43*sz2*f43;
502 UInt_t index=r1.GetIndex(is);
503 AliTRDtrack *track=new AliTRDtrack(index, x, c, x1, ns*alpha+shift);
505 Int_t rc=FindProlongation(*track,fTrSec,ns,i2);
508 (track->GetNclusters() < (i1-i2)*fMinClustersInSeed)) delete track;
510 fSeeds->AddLast(track); fNseeds++;
511 cerr<<"found seed "<<fNseeds<<endl;
520 //___________________________________________________________________
521 void AliTRDtracker::FindTracks()
523 if (!fClusters) return;
525 AliTRDtrackingSector fTrSec[AliTRDgeometry::kNsect];
526 SetUpSectors(fTrSec);
530 Int_t num_of_time_bins = fTrSec[0].GetNtimeBins();
531 Int_t nseed=fSeeds->GetEntriesFast();
534 for (Int_t i=0; i<nseed; i++) {
535 cerr<<"FindTracks: seed "<<i+1<<" out of "<<nseed<<endl;
537 AliTRDtrack& t=*((AliTRDtrack*)fSeeds->UncheckedAt(i));
539 nSeedClusters = t.GetNclusters();
540 Double_t alpha=t.GetAlpha();
542 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
543 if (alpha < 0. ) alpha += 2.*TMath::Pi();
544 Int_t ns=Int_t(alpha/AliTRDgeometry::GetAlpha())%AliTRDgeometry::kNsect;
546 if (FindProlongation(t,fTrSec,ns)) {
547 cerr<<"No of clusters in the track = "<<t.GetNclusters()<<endl;
548 if (t.GetNclusters() >= Int_t(fMinClustersInTrack*num_of_time_bins)) {
549 Int_t label = GetTrackLabel(t);
553 AliTRDtrack *pt = new AliTRDtrack(t);
554 fTracks->AddLast(pt); fNtracks++;
556 cerr<<"found track "<<fNtracks<<endl;
559 delete fSeeds->RemoveAt(i);
563 //__________________________________________________________________
564 void AliTRDtracker::UseClusters(AliTRDtrack t) {
565 Int_t ncl=t.GetNclusters();
566 for (Int_t i=0; i<ncl; i++) {
567 Int_t index = t.GetClusterIndex(i);
568 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
573 //__________________________________________________________________
574 Int_t AliTRDtracker::GetTrackLabel(AliTRDtrack t) {
576 Int_t label=123456789, index, i, j;
577 Int_t ncl=t.GetNclusters();
578 const Int_t range = AliTRDgeometry::kNplan * fGeom->GetTimeMax();
581 // Int_t s[range][2];
582 Int_t **s = new Int_t* [range];
583 for (i=0; i<range; i++) {
586 for (i=0; i<range; i++) {
592 for (i=0; i<ncl; i++) {
593 index=t.GetClusterIndex(i);
594 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
595 t0=c->GetTrackIndex(0);
596 t1=c->GetTrackIndex(1);
597 t2=c->GetTrackIndex(2);
600 for (i=0; i<ncl; i++) {
601 index=t.GetClusterIndex(i);
602 AliTRDcluster *c=(AliTRDcluster*)fClusters->UncheckedAt(index);
603 for (Int_t k=0; k<3; k++) {
604 label=c->GetTrackIndex(k);
605 label_added=kFALSE; j=0;
607 while ( (!label_added) && ( j < range ) ) {
608 if (s[j][0]==label || s[j][1]==0) {
622 for (i=0; i<range; i++) {
624 max=s[i][1]; label=s[i][0];
628 if(max > ncl*fLabelFraction) return label;
632 //___________________________________________________________________
634 Int_t AliTRDtracker::WriteTracks(const Char_t *filename) {
636 TDirectory *savedir=gDirectory;
638 TFile *out=TFile::Open(filename,"RECREATE");
640 TTree tracktree("TreeT","Tree with TRD tracks");
642 AliTRDtrack *iotrack=0;
643 tracktree.Branch("tracks","AliTRDtrack",&iotrack,32000,0);
645 Int_t ntracks=fTracks->GetEntriesFast();
647 for (Int_t i=0; i<ntracks; i++) {
648 AliTRDtrack *pt=(AliTRDtrack*)fTracks->UncheckedAt(i);
651 cerr<<"WriteTracks: put track "<<i<<" in the tree"<<endl;
659 cerr<<"WriteTracks: done"<<endl;
663 //_____________________________________________________________________________
664 void AliTRDtracker::ReadClusters(TObjArray *array, const Char_t *filename,
668 // Reads AliTRDclusters (option >= 0) or AliTRDrecPoints (option < 0)
669 // from the file. The names of the cluster tree and branches
670 // should match the ones used in AliTRDclusterizer::WriteClusters()
673 TDirectory *savedir=gDirectory;
675 TFile *file = TFile::Open(filename);
676 if (!file->IsOpen()) {printf("Can't open file %s !\n",filename); return;}
678 TTree *tree = (TTree*)file->Get("ClusterTree");
679 Int_t nentr = (Int_t) tree->GetEntries();
680 printf("found %d entries in %s.\n",nentr,tree->GetName());
683 TObjArray *ioArray = new TObjArray(400);
686 //branch = tree->GetBranch("RecPoints");
688 branch = tree->GetBranch("TRDrecPoints");
690 for (Int_t i=0; i<nentr; i++) {
691 branch->SetAddress(&ioArray);
693 Int_t npoints = ioArray->GetEntriesFast();
694 printf("Read %d rec. points from entry %d \n", npoints, i);
696 for(Int_t j=0; j<npoints; j++) {
697 AliTRDrecPoint *p=(AliTRDrecPoint*)ioArray->UncheckedAt(j);
699 ioArray->RemoveAt(j);
704 branch = tree->GetBranch("TRDcluster");
706 for (Int_t i=0; i<nentr; i++) {
707 branch->SetAddress(&ioArray);
709 Int_t npoints = ioArray->GetEntriesFast();
710 printf("Read %d clusters from entry %d \n", npoints, i);
712 for(Int_t j=0; j<npoints; j++) {
713 AliTRDcluster *c=(AliTRDcluster*)ioArray->UncheckedAt(j);
715 ioArray->RemoveAt(j);