1 //-------------------------------------------------------------------------
2 // Implementation of the ITS tracker class
3 // The pattern recongintion based on the "cooked covariance" approach
4 //-------------------------------------------------------------------------
7 #include <TClonesArray.h>
10 #include "AliESDEvent.h"
11 #include "AliITSUClusterPix.h"
12 #include "AliITSUGeomTGeo.h"
13 #include "AliITSUTrackerCooked.h"
14 #include "AliITSUTrackCooked.h"
16 ClassImp(AliITSUTrackerCooked)
18 //************************************************
19 // Constants hardcoded for the moment:
20 //************************************************
21 // seed "windows" in z and phi: MakeSeeds
22 const Double_t kzWin=0.33;
23 const Double_t kminPt=0.05;
24 // Maximal accepted impact parameters for the seeds
25 const Double_t kmaxDCAxy=3.;
26 const Double_t kmaxDCAz= 3.;
27 // Layers for the seeding
28 const Int_t kSeedingLayer1=6, kSeedingLayer2=4, kSeedingLayer3=5;
29 // Space point resolution
30 const Double_t kSigma2=0.0005*0.0005;
31 // Max accepted chi2 per cluster
32 const Double_t kmaxChi2PerCluster=10.;
33 // Tracking "road" from layer to layer
34 const Double_t kRoadY=0.7;
35 const Double_t kRoadZ=0.7;
36 // Minimal number of attached clusters
37 const Int_t kminNumberOfClusters=3;
39 //************************************************
41 //************************************************
43 // Precalculate cylidnrical (r,phi) for the clusters;
44 // use exact r's for the clusters
47 AliITSUTrackerCooked::AliITSUlayer
48 AliITSUTrackerCooked::fgLayers[AliITSUTrackerCooked::kNLayers];
50 AliITSUTrackerCooked::AliITSUTrackerCooked():
57 //--------------------------------------------------------------------
58 // This default constructor needs to be provided
59 //--------------------------------------------------------------------
61 klRadius[7]={2.34, 3.15, 3.93, 19.61, 24.55, 34.39, 39.34}; //tdr6
63 AliITSUGeomTGeo *gm = new AliITSUGeomTGeo(kTRUE,kTRUE);
64 AliITSUClusterPix::SetGeom(gm);
66 for (Int_t i=0; i<kNLayers; i++) fgLayers[i].SetR(klRadius[i]);
68 // Some default primary vertex
69 Double_t xyz[]={0.,0.,0.};
70 Double_t ers[]={2.,2.,2.};
76 void AliITSUTrackerCooked::ResetTrackToFollow(const AliITSUTrackCooked &t) {
77 //--------------------------------------------------------------------
78 // Prepare to follow a new track seed
79 //--------------------------------------------------------------------
80 delete fTrackToFollow;
81 fTrackToFollow = new AliITSUTrackCooked(t);
84 void AliITSUTrackerCooked::ResetBestTrack() {
85 //--------------------------------------------------------------------
86 // Replace the best track branch
87 //--------------------------------------------------------------------
89 fBestTrack = new AliITSUTrackCooked(*fTrackToFollow);
92 AliITSUTrackerCooked::~AliITSUTrackerCooked()
94 //--------------------------------------------------------------------
96 //--------------------------------------------------------------------
98 if (fSeeds) fSeeds->Delete(); delete fSeeds;
100 delete fTrackToFollow;
105 f1(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t x3, Double_t y3)
107 //-----------------------------------------------------------------
108 // Initial approximation of the track curvature
109 //-----------------------------------------------------------------
110 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
111 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
112 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
113 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
114 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
116 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=TMath::Abs(d/(d*y1-b));
118 Double_t crv=xr*yr/sqrt(xr*xr+yr*yr);
125 f2(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t x3, Double_t y3)
127 //-----------------------------------------------------------------
128 // Initial approximation of the x-coordinate of the center of curvature
129 //-----------------------------------------------------------------
131 Double_t k1=(y2-y1)/(x2-x1), k2=(y3-y2)/(x3-x2);
132 Double_t x0=0.5*(k1*k2*(y1-y3) + k2*(x1+x2) - k1*(x2+x3))/(k2-k1);
138 f3(Double_t x1, Double_t y1, Double_t x2, Double_t y2, Double_t z1, Double_t z2)
140 //-----------------------------------------------------------------
141 // Initial approximation of the tangent of the track dip angle
142 //-----------------------------------------------------------------
143 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
146 Bool_t AliITSUTrackerCooked::
147 AddCookedSeed(const Float_t r1[3], Int_t l1, Int_t i1,
148 const Float_t r2[3], Int_t l2, Int_t i2,
149 const AliCluster *c3,Int_t l3, Int_t i3)
151 //--------------------------------------------------------------------
152 // This is the main cooking function.
153 // Creates seed parameters out of provided clusters.
154 //--------------------------------------------------------------------
156 if (!c3->GetXAlphaRefPlane(x,a)) return kFALSE;
158 Double_t ca=TMath::Cos(a), sa=TMath::Sin(a);
159 Double_t x1 = r1[0]*ca + r1[1]*sa,
160 y1 =-r1[0]*sa + r1[1]*ca, z1 = r1[2];
161 Double_t x2 = r2[0]*ca + r2[1]*sa,
162 y2 =-r2[0]*sa + r2[1]*ca, z2 = r2[2];
163 Double_t x3 = x, y3 = c3->GetY(), z3 = c3->GetZ();
168 Double_t crv=f1(x1, y1, x2, y2, x3, y3); //curvature
169 Double_t x0 =f2(x1, y1, x2, y2, x3, y3); //x-coordinate of the center
170 Double_t tgl12=f3(x1, y1, x2, y2, z1, z2);
171 Double_t tgl23=f3(x2, y2, x3, y3, z2, z3);
173 Double_t sf=crv*(x-x0);
174 if (TMath::Abs(sf) >= kAlmost1) return kFALSE;
177 par[3]=0.5*(tgl12 + tgl23);
179 par[4]=(TMath::Abs(bz) < kAlmost0Field) ? kAlmost0 : crv/(bz*kB2C);
182 for (Int_t i=0; i<15; i++) cov[i]=0.;
185 cov[5] =0.007*0.007*10; //FIXME all these lines
186 cov[9] =0.007*0.007*10;
189 AliITSUTrackCooked *seed=new AliITSUTrackCooked();
190 seed->Set(Double_t(x), Double_t(a), par, cov);
193 seed->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
194 if (TMath::Abs(dz[0]) > kmaxDCAxy) {delete seed; return kFALSE;}
195 if (TMath::Abs(dz[1]) > kmaxDCAz ) {delete seed; return kFALSE;}
197 seed->SetClusterIndex(l1,i1);
198 seed->SetClusterIndex(l2,i2);
199 seed->SetClusterIndex(l3,i3);
201 fSeeds->AddLast(seed);
206 Int_t AliITSUTrackerCooked::MakeSeeds() {
207 //--------------------------------------------------------------------
208 // This is the main pattern recongition function.
209 // Creates seeds out of two clusters and another point.
210 //--------------------------------------------------------------------
211 if (fSeeds) {fSeeds->Delete(); delete fSeeds;}
212 fSeeds=new TObjArray(77777);
214 const Double_t zv=GetZ();
216 AliITSUlayer &layer1=fgLayers[kSeedingLayer1];
217 AliITSUlayer &layer2=fgLayers[kSeedingLayer2];
218 AliITSUlayer &layer3=fgLayers[kSeedingLayer3];
219 Double_t r1=layer1.GetR();
220 Double_t r2=layer2.GetR();
221 Double_t r3=layer3.GetR();
223 const Double_t maxC = TMath::Abs(GetBz()*kB2C/kminPt);
224 const Double_t kpWin = TMath::ASin(0.5*maxC*r1) - TMath::ASin(0.5*maxC*r2);
226 Int_t nClusters1=layer1.GetNumberOfClusters();
227 Int_t nClusters2=layer2.GetNumberOfClusters();
228 Int_t nClusters3=layer3.GetNumberOfClusters();
229 for (Int_t n1=0; n1<nClusters1; n1++) {
230 AliCluster *c1=layer1.GetCluster(n1);
232 //Int_t lab=c1->GetLabel(0);
234 Double_t z1=c1->GetZ();
235 Float_t xyz1[3]; c1->GetGlobalXYZ(xyz1);
236 Double_t phi1=TMath::ATan2(xyz1[1],xyz1[0]);
237 Double_t zr2=zv + r2/r1*(z1-zv);
238 Int_t start2=layer2.FindClusterIndex(zr2-kzWin);
239 for (Int_t n2=start2; n2<nClusters2; n2++) {
240 AliCluster *c2=layer2.GetCluster(n2);
242 //if (c2->GetLabel(0)!=lab) continue;
244 Double_t z2=c2->GetZ();
246 if (z2 > (zr2+kzWin)) break; //check in Z
247 Float_t xyz2[3]; c2->GetGlobalXYZ(xyz2);
248 Double_t phi2=TMath::ATan2(xyz2[1],xyz2[0]);
249 if (TMath::Abs(phi2-phi1) > kpWin) continue; //check in Phi
251 Double_t zr3=z1 + (r3-r1)/(r2-r1)*(z2-z1);
252 Double_t crv=f1(xyz1[0], xyz1[1], xyz2[0], xyz2[1], GetX(), GetY());
253 Double_t phir3 = phi1 + 0.5*crv*(r3 - r1);
255 Int_t start3=layer3.FindClusterIndex(zr3-kzWin/2);
256 for (Int_t n3=start3; n3<nClusters3; n3++) {
257 AliCluster *c3=layer3.GetCluster(n3);
259 //if (c3->GetLabel(0)!=lab) continue;
261 Double_t z3=c3->GetZ();
262 if (z3 > (zr3+kzWin/2)) break; //check in Z
264 Float_t xyz3[3]; c3->GetGlobalXYZ(xyz3);
265 Double_t phi3=TMath::ATan2(xyz3[1],xyz3[0]);
266 if (TMath::Abs(phir3-phi3) > kpWin/100) continue; //check in Phi
268 AliITSUClusterPix cc(*((AliITSUClusterPix*)c2));
270 AddCookedSeed(xyz1, kSeedingLayer1, n1,
271 xyz3, kSeedingLayer3, n3,
272 &cc, kSeedingLayer2, n2);
278 for (Int_t n1=0; n1<nClusters1; n1++) {
279 AliCluster *c1=layer1.GetCluster(n1);
280 ((AliITSUClusterPix*)c1)->GoToFrameTrk();
282 for (Int_t n2=0; n2<nClusters2; n2++) {
283 AliCluster *c2=layer2.GetCluster(n2);
284 ((AliITSUClusterPix*)c2)->GoToFrameTrk();
286 for (Int_t n3=0; n3<nClusters3; n3++) {
287 AliCluster *c3=layer3.GetCluster(n3);
288 ((AliITSUClusterPix*)c3)->GoToFrameTrk();
292 return fSeeds->GetEntriesFast();
295 Int_t AliITSUTrackerCooked::Clusters2Tracks(AliESDEvent *event) {
296 //--------------------------------------------------------------------
297 // This is the main tracking function
298 // The clusters must already be loaded
299 //--------------------------------------------------------------------
301 Int_t nSeeds=MakeSeeds();
303 // Possibly, icrement the seeds with additional clusters (Kalman)
305 // Possibly, (re)fit the found tracks
308 for (Int_t s=0; s<nSeeds; s++) {
309 const AliITSUTrackCooked *track=(AliITSUTrackCooked*)fSeeds->At(s);
310 ResetTrackToFollow(*track);
313 fgLayers[fI].ResetTrack(*track);
315 for (FollowProlongation(); fI<kSeedingLayer2; fI++) {
316 while (TakeNextProlongation()) FollowProlongation();
319 if (fBestTrack->GetNumberOfClusters() < kminNumberOfClusters) continue;
321 CookLabel(fBestTrack,0.); //For comparison only
322 Int_t label=fBestTrack->GetLabel();
323 if (label>0) ngood++;
326 iotrack.UpdateTrackParams(fBestTrack,AliESDtrack::kITSin);
327 iotrack.SetLabel(label);
328 event->AddTrack(&iotrack);
329 UseClusters(fBestTrack);
332 Info("Clusters2Tracks","Seeds: %d",nSeeds);
334 Info("Clusters2Tracks","Good tracks/seeds: %f",Float_t(ngood)/nSeeds);
336 if (fSeeds) {fSeeds->Delete(); delete fSeeds;}
342 void AliITSUTrackerCooked::FollowProlongation() {
343 //--------------------------------------------------------------------
344 // Push this track tree branch towards the primary vertex
345 //--------------------------------------------------------------------
348 AliITSUlayer &layer = fgLayers[fI]; //fI is the number of the next layer
349 Double_t r=layer.GetR();
351 //Find intersection (fTrackToFollow is still at the previous layer)
353 if (!fTrackToFollow->GetPhiZat(r,phi,z)) {
354 //Warning("FollowProlongation","failed to estimate track !\n");
358 //if (TMath::Abs(fTrackToFollow.GetZ()-GetZ()) > r+dz) return;
359 Double_t zMin = z - kRoadZ;
360 Double_t zMax = z + kRoadZ;
361 Double_t phiMin = phi - kRoadY/r;
362 Double_t phiMax = phi + kRoadY/r;
363 if (layer.SelectClusters(zMin, zMax, phiMin, phiMax)==0) return;
365 if (!TakeNextProlongation()) return;
369 //deal with the best track
370 Int_t ncl=fTrackToFollow->GetNumberOfClusters();
371 Int_t nclb=fBestTrack->GetNumberOfClusters();
374 Double_t chi2=fTrackToFollow->GetChi2();
375 if (chi2/ncl < kmaxChi2PerCluster) {
376 if (ncl > nclb || chi2 < fBestTrack->GetChi2()) {
384 Int_t AliITSUTrackerCooked::TakeNextProlongation() {
385 //--------------------------------------------------------------------
386 // Switch to the next track tree branch
387 //--------------------------------------------------------------------
388 AliITSUlayer &layer=fgLayers[fI];
390 const AliCluster *c=0; Int_t ci=-1;
391 const AliCluster *cc=0; Int_t cci=-1;
393 Double_t x=0., alpha=0.;
394 Double_t z=0., dz=0., y=0., dy=0., chi2=0.;
395 while ((c=layer.GetNextCluster(ci))!=0) {
396 if (c->IsClusterUsed()) continue;
397 Int_t id=c->GetVolumeId();
400 Float_t xr,ar; c->GetXAlphaRefPlane(xr, ar);
402 const AliITSUTrackCooked *t = fgLayers[fI+1].GetTrack();
403 ResetTrackToFollow(*t);
404 if (!fTrackToFollow->Propagate(alpha, x, GetBz())) {
405 //Warning("TakeNextProlongation","propagation failed !\n");
408 dz=7*TMath::Sqrt(fTrackToFollow->GetSigmaZ2() + kSigma2);
409 dy=7*TMath::Sqrt(fTrackToFollow->GetSigmaY2() + kSigma2);
410 z=fTrackToFollow->GetZ();
411 y=fTrackToFollow->GetY();
414 //if (TMath::Abs(fTrackToFollow.GetZ()-GetZ())>layer.GetR()+dz) continue;
416 if (TMath::Abs(z - c->GetZ()) > dz) continue;
417 if (TMath::Abs(y - c->GetY()) > dy) continue;
419 Double_t ch2=fTrackToFollow->GetPredictedChi2(c);
420 if (ch2 > kmaxChi2PerCluster) continue;
428 if (!fTrackToFollow->Update(cc,chi2,(fI<<28)+cci)) {
429 //Warning("TakeNextProlongation","filtering failed !\n");
432 Double_t xx0 = (fI > 2) ? 0.008 : 0.003; // Rough layer thickness
433 Double_t x0 = 9.36; // Radiation length of Si [cm]
434 Double_t rho = 2.33; // Density of Si [g/cm^3]
435 Double_t mass = fTrackToFollow->GetMass();
436 fTrackToFollow->CorrectForMeanMaterial(xx0, xx0*x0*rho, mass, kTRUE);
437 layer.ResetTrack(*fTrackToFollow);
442 Int_t AliITSUTrackerCooked::PropagateBack(AliESDEvent *event) {
443 //--------------------------------------------------------------------
444 // Here, we implement the Kalman smoother ?
445 // The clusters must already be loaded
446 //--------------------------------------------------------------------
447 Int_t n=event->GetNumberOfTracks();
450 for (Int_t i=0; i<n; i++) {
451 AliESDtrack *esdTrack=event->GetTrack(i);
453 if ((esdTrack->GetStatus()&AliESDtrack::kITSin)==0) continue;
455 AliITSUTrackCooked track(*esdTrack);
457 ResetTrackToFollow(track);
459 fTrackToFollow->ResetCovariance(10.); fTrackToFollow->ResetClusters();
460 if (RefitAt(40., fTrackToFollow, &track)) {
462 CookLabel(fTrackToFollow, 0.); //For comparison only
463 Int_t label=fTrackToFollow->GetLabel();
464 if (label>0) ngood++;
466 esdTrack->UpdateTrackParams(fTrackToFollow,AliESDtrack::kITSout);
467 //UseClusters(fTrackToFollow);
472 Info("PropagateBack","Back propagated tracks: %d",ntrk);
474 Info("PropagateBack","Good tracks/back propagated: %f",Float_t(ngood)/ntrk);
479 Bool_t AliITSUTrackerCooked::
480 RefitAt(Double_t xx, AliITSUTrackCooked *t, const AliITSUTrackCooked *c) {
481 //--------------------------------------------------------------------
482 // This function refits the track "t" at the position "x" using
483 // the clusters from "c"
484 //--------------------------------------------------------------------
485 Int_t index[kNLayers];
487 for (k=0; k<kNLayers; k++) index[k]=-1;
488 Int_t nc=c->GetNumberOfClusters();
489 for (k=0; k<nc; k++) {
490 Int_t idx=c->GetClusterIndex(k), nl=(idx&0xf0000000)>>28;
494 Int_t from, to, step;
495 if (xx > t->GetX()) {
499 from=kNLayers-1; to=-1;
503 for (Int_t i=from; i != to; i += step) {
506 const AliCluster *cl=GetCluster(idx);
507 Float_t xr,ar; cl->GetXAlphaRefPlane(xr, ar);
508 if (!t->Propagate(Double_t(ar), Double_t(xr), GetBz())) {
509 //Warning("RefitAt","propagation failed !\n");
512 Double_t chi2=t->GetPredictedChi2(cl);
513 if (chi2 < kmaxChi2PerCluster) t->Update(cl, chi2, idx);
515 Double_t r=fgLayers[i].GetR();
517 if (!t->GetPhiZat(r,phi,z)) {
518 //Warning("RefitAt","failed to estimate track !\n");
521 if (!t->Propagate(phi, r, GetBz())) {
522 //Warning("RefitAt","propagation failed !\n");
526 Double_t xx0 = (i > 2) ? 0.008 : 0.003; // Rough layer thickness
527 Double_t x0 = 9.36; // Radiation length of Si [cm]
528 Double_t rho = 2.33; // Density of Si [g/cm^3]
529 Double_t mass = t->GetMass();
530 t->CorrectForMeanMaterial(xx0, -step*xx0*x0*rho, mass, kTRUE);
533 if (!t->PropagateTo(xx,0.,0.)) return kFALSE;
537 Int_t AliITSUTrackerCooked::RefitInward(AliESDEvent *event) {
538 //--------------------------------------------------------------------
539 // Some final refit, after the outliers get removed by the smoother ?
540 // The clusters must be loaded
541 //--------------------------------------------------------------------
542 Int_t n=event->GetNumberOfTracks();
545 for (Int_t i=0; i<n; i++) {
546 AliESDtrack *esdTrack=event->GetTrack(i);
548 if ((esdTrack->GetStatus()&AliESDtrack::kITSout) == 0) continue;
550 AliITSUTrackCooked track(*esdTrack);
551 ResetTrackToFollow(track);
553 fTrackToFollow->ResetCovariance(10.); fTrackToFollow->ResetClusters();
554 if (!RefitAt(2.1, fTrackToFollow, &track)) continue;
555 //Cross the beam pipe
556 if (!fTrackToFollow->PropagateTo(1.8, 2.27e-3, 35.28*1.848)) continue;
558 CookLabel(fTrackToFollow, 0.); //For comparison only
559 Int_t label=fTrackToFollow->GetLabel();
560 if (label>0) ngood++;
562 esdTrack->UpdateTrackParams(fTrackToFollow,AliESDtrack::kITSrefit);
563 //esdTrack->RelateToVertex(event->GetVertex(),GetBz(),33.);
564 //UseClusters(fTrackToFollow);
568 Info("RefitInward","Refitted tracks: %d",ntrk);
570 Info("RefitInward","Good tracks/refitted: %f",Float_t(ngood)/ntrk);
575 Int_t AliITSUTrackerCooked::LoadClusters(TTree *cTree) {
576 //--------------------------------------------------------------------
577 // This function reads the ITSU clusters from the tree,
578 // sort them, distribute over the internal tracker arrays, etc
579 //--------------------------------------------------------------------
581 AliFatal("No cluster tree !");
585 //This TClonesArray is not the owner of the clusters
586 TClonesArray dummy("AliITSUClusterPix",kMaxClusterPerLayer), *clusters=&dummy;
588 for (Int_t i=0; i<kNLayers; i++) {
589 TBranch *br = cTree->GetBranch(Form("ITSRecPoints%d",i));
590 if (!br) AliFatal(Form("No cluster branch for layer %d",i));
591 br->SetAddress(&clusters);
597 fgLayers[i].InsertClusters(clusters,kTRUE);
600 fgLayers[i].InsertClusters(clusters,kFALSE);
609 void AliITSUTrackerCooked::UnloadClusters() {
610 //--------------------------------------------------------------------
611 // This function unloads ITSU clusters from the RAM
612 //--------------------------------------------------------------------
613 for (Int_t i=0; i<kNLayers; i++) fgLayers[i].DeleteClusters();
616 AliCluster *AliITSUTrackerCooked::GetCluster(Int_t index) const {
617 //--------------------------------------------------------------------
618 // Return pointer to a given cluster
619 //--------------------------------------------------------------------
620 Int_t l=(index & 0xf0000000) >> 28;
621 Int_t c=(index & 0x0fffffff) >> 00;
622 return fgLayers[l].GetCluster(c);
625 AliITSUTrackerCooked::AliITSUlayer::AliITSUlayer():
631 //--------------------------------------------------------------------
632 // This default constructor needs to be provided
633 //--------------------------------------------------------------------
634 for (Int_t i=0; i<kMaxClusterPerLayer; i++) fClusters[i]=0;
635 for (Int_t i=0; i<kMaxSelected; i++) fIndex[i]=-1;
638 AliITSUTrackerCooked::AliITSUlayer::~AliITSUlayer()
640 //--------------------------------------------------------------------
642 //--------------------------------------------------------------------
648 AliITSUTrackerCooked::AliITSUlayer::ResetTrack(const AliITSUTrackCooked &t) {
649 //--------------------------------------------------------------------
650 // Replace the track estimate at this layer
651 //--------------------------------------------------------------------
653 fTrack=new AliITSUTrackCooked(t);
656 void AliITSUTrackerCooked::
657 AliITSUlayer::InsertClusters(TClonesArray *clusters, Bool_t seedingLayer)
659 //--------------------------------------------------------------------
660 // Load clusters to this layer
661 //--------------------------------------------------------------------
662 Int_t ncl=clusters->GetEntriesFast();
664 for (Int_t i=0; i<ncl; i++) {
665 AliITSUClusterPix *c=(AliITSUClusterPix*)clusters->UncheckedAt(i);
667 Double_t x=c->GetX(), y=c->GetY();
668 r += TMath::Sqrt(x*x + y*y);
669 if (!seedingLayer) c->GoToFrameTrk();
670 //if (!c->Misalign()) AliWarning("Can't misalign this cluster !");
671 InsertCluster(new AliITSUClusterPix(*c));
676 void AliITSUTrackerCooked::AliITSUlayer::DeleteClusters()
678 //--------------------------------------------------------------------
679 // Load clusters to this layer
680 //--------------------------------------------------------------------
681 for (Int_t i=0; i<fN; i++) {delete fClusters[i]; fClusters[i]=0;}
686 AliITSUTrackerCooked::AliITSUlayer::InsertCluster(AliCluster *c) {
687 //--------------------------------------------------------------------
688 // This function inserts a cluster to this layer in increasing
689 // order of the cluster's fZ
690 //--------------------------------------------------------------------
691 if (fN>=kMaxClusterPerLayer) {
692 ::Error("InsertCluster","Too many clusters !\n");
695 if (fN==0) fClusters[0]=c;
697 Int_t i=FindClusterIndex(c->GetZ());
699 memmove(fClusters+i+1 ,fClusters+i,k*sizeof(AliCluster*));
707 AliITSUTrackerCooked::AliITSUlayer::FindClusterIndex(Double_t z) const {
708 //--------------------------------------------------------------------
709 // This function returns the index of the first
710 // with its fZ >= "z".
711 //--------------------------------------------------------------------
715 if (z <= fClusters[b]->GetZ()) return b;
718 if (z > fClusters[e]->GetZ()) return e+1;
721 for (; b<e; m=(b+e)/2) {
722 if (z > fClusters[m]->GetZ()) b=m+1;
728 Int_t AliITSUTrackerCooked::AliITSUlayer::
729 SelectClusters(Float_t zMin,Float_t zMax,Float_t phiMin, Float_t phiMax) {
730 //--------------------------------------------------------------------
731 // This function selects clusters within the "road"
732 //--------------------------------------------------------------------
734 Float_t x=0., alpha=0.;
735 for (Int_t i=FindClusterIndex(zMin); i<fN; i++) {
736 AliCluster *c=fClusters[i];
737 if (c->GetZ() > zMax) break;
738 if (c->IsClusterUsed()) continue;
739 UShort_t id=c->GetVolumeId();
742 c->GetXAlphaRefPlane(x,alpha); //FIXME
744 Double_t cPhi=alpha + c->GetY()/fR;
745 if (cPhi<0.) cPhi+=2.*TMath::Pi();
746 else if (cPhi >= 2.*TMath::Pi()) cPhi-=2.*TMath::Pi();
747 if (cPhi <= phiMin) continue;
748 if (cPhi > phiMax) continue;
750 if (fNsel==kMaxSelected) break;
755 const AliCluster *AliITSUTrackerCooked::AliITSUlayer::GetNextCluster(Int_t &ci){
756 //--------------------------------------------------------------------
757 // This function returns clusters within the "road"
758 //--------------------------------------------------------------------