006b5f7f |
1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * |
3 | * * |
4 | * Author: The ALICE Off-line Project. * |
5 | * Contributors are mentioned in the code where appropriate. * |
6 | * * |
7 | * Permission to use, copy, modify and distribute this software and its * |
8 | * documentation strictly for non-commercial purposes is hereby granted * |
9 | * without fee, provided that the above copyright notice appears in all * |
10 | * copies and that both the copyright notice and this permission notice * |
11 | * appear in the supporting documentation. The authors make no claims * |
12 | * about the suitability of this software for any purpose. It is * |
13 | * provided "as is" without express or implied warranty. * |
14 | **************************************************************************/ |
15 | |
16 | //------------------------------------------------------------------------- |
17 | // Implementation of the ITS tracker class |
18856a77 |
18 | // It reads AliITSclusterV2 clusters and creates AliITStrackV2 tracks |
19 | // and fills with them the ESD |
006b5f7f |
20 | // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch |
a9a2d814 |
21 | // dEdx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch |
006b5f7f |
22 | //------------------------------------------------------------------------- |
1f9a65c4 |
23 | |
006b5f7f |
24 | #include <TFile.h> |
25 | #include <TTree.h> |
26 | #include <TRandom.h> |
006b5f7f |
27 | |
28 | #include "AliITSgeom.h" |
29 | #include "AliITSRecPoint.h" |
517b130f |
30 | #include "AliTPCtrack.h" |
c630aafd |
31 | #include "AliESD.h" |
006b5f7f |
32 | #include "AliITSclusterV2.h" |
33 | #include "AliITStrackerV2.h" |
34 | |
8676d691 |
35 | ClassImp(AliITStrackerV2) |
006b5f7f |
36 | |
18856a77 |
37 | AliITStrackerV2::AliITSlayer AliITStrackerV2::fgLayers[kMaxLayer]; // ITS layers |
006b5f7f |
38 | |
c630aafd |
39 | AliITStrackerV2::AliITStrackerV2(const AliITSgeom *geom) : AliTracker() { |
006b5f7f |
40 | //-------------------------------------------------------------------- |
61ab8ea8 |
41 | //This is the AliITStrackerV2 constructor |
006b5f7f |
42 | //-------------------------------------------------------------------- |
006b5f7f |
43 | AliITSgeom *g=(AliITSgeom*)geom; |
44 | |
45 | Float_t x,y,z; |
46 | Int_t i; |
c630aafd |
47 | for (i=1; i<kMaxLayer+1; i++) { |
006b5f7f |
48 | Int_t nlad=g->GetNladders(i); |
49 | Int_t ndet=g->GetNdetectors(i); |
50 | |
51 | g->GetTrans(i,1,1,x,y,z); |
52 | Double_t r=TMath::Sqrt(x*x + y*y); |
53 | Double_t poff=TMath::ATan2(y,x); |
54 | Double_t zoff=z; |
55 | |
56 | g->GetTrans(i,1,2,x,y,z); |
57 | r += TMath::Sqrt(x*x + y*y); |
58 | g->GetTrans(i,2,1,x,y,z); |
59 | r += TMath::Sqrt(x*x + y*y); |
60 | g->GetTrans(i,2,2,x,y,z); |
61 | r += TMath::Sqrt(x*x + y*y); |
62 | r*=0.25; |
63 | |
18856a77 |
64 | new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet); |
006b5f7f |
65 | |
66 | for (Int_t j=1; j<nlad+1; j++) { |
67 | for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors |
68 | Float_t x,y,zshift; g->GetTrans(i,j,k,x,y,zshift); |
69 | Double_t rot[9]; g->GetRotMatrix(i,j,k,rot); |
70 | |
f363d377 |
71 | Double_t phi=TMath::ATan2(rot[1],rot[0])+TMath::Pi(); |
72 | phi+=TMath::Pi()/2; |
73 | if (i==1) phi+=TMath::Pi(); |
74 | Double_t cp=TMath::Cos(phi), sp=TMath::Sin(phi); |
75 | Double_t r=x*cp+y*sp; |
006b5f7f |
76 | |
18856a77 |
77 | AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1); |
006b5f7f |
78 | new(&det) AliITSdetector(r,phi); |
79 | } |
80 | } |
c630aafd |
81 | |
006b5f7f |
82 | } |
83 | |
61ab8ea8 |
84 | fI=kMaxLayer; |
743a19f2 |
85 | |
61ab8ea8 |
86 | fPass=0; |
87 | fConstraint[0]=1; fConstraint[1]=0; |
8676d691 |
88 | |
89 | Double_t xyz[]={kXV,kYV,kZV}, ers[]={kSigmaXV,kSigmaYV,kSigmaZV}; |
90 | SetVertex(xyz,ers); |
c0dd5278 |
91 | |
92 | for (Int_t i=0; i<kMaxLayer; i++) fLayersNotToSkip[i]=kLayersNotToSkip[i]; |
93 | fLastLayerToTrackTo=kLastLayerToTrackTo; |
94 | |
95 | } |
96 | |
97 | void AliITStrackerV2::SetLayersNotToSkip(Int_t *l) { |
98 | //-------------------------------------------------------------------- |
99 | //This function set masks of the layers which must be not skipped |
100 | //-------------------------------------------------------------------- |
101 | for (Int_t i=0; i<kMaxLayer; i++) fLayersNotToSkip[i]=l[i]; |
61ab8ea8 |
102 | } |
006b5f7f |
103 | |
c630aafd |
104 | Int_t AliITStrackerV2::LoadClusters(TTree *cTree) { |
61ab8ea8 |
105 | //-------------------------------------------------------------------- |
106 | //This function loads ITS clusters |
107 | //-------------------------------------------------------------------- |
61ab8ea8 |
108 | TBranch *branch=cTree->GetBranch("Clusters"); |
109 | if (!branch) { |
c630aafd |
110 | Error("LoadClusters"," can't get the branch !\n"); |
8676d691 |
111 | return 1; |
61ab8ea8 |
112 | } |
006b5f7f |
113 | |
61ab8ea8 |
114 | TClonesArray dummy("AliITSclusterV2",10000), *clusters=&dummy; |
115 | branch->SetAddress(&clusters); |
006b5f7f |
116 | |
61ab8ea8 |
117 | Int_t j=0; |
118 | for (Int_t i=0; i<kMaxLayer; i++) { |
18856a77 |
119 | Int_t ndet=fgLayers[i].GetNdetectors(); |
120 | Int_t jmax = j + fgLayers[i].GetNladders()*ndet; |
61ab8ea8 |
121 | for (; j<jmax; j++) { |
122 | if (!cTree->GetEvent(j)) continue; |
123 | Int_t ncl=clusters->GetEntriesFast(); |
124 | while (ncl--) { |
125 | AliITSclusterV2 *c=(AliITSclusterV2*)clusters->UncheckedAt(ncl); |
18856a77 |
126 | fgLayers[i].InsertCluster(new AliITSclusterV2(*c)); |
61ab8ea8 |
127 | } |
128 | clusters->Delete(); |
129 | } |
18856a77 |
130 | fgLayers[i].ResetRoad(); //road defined by the cluster density |
006b5f7f |
131 | } |
c630aafd |
132 | |
8676d691 |
133 | return 0; |
61ab8ea8 |
134 | } |
006b5f7f |
135 | |
61ab8ea8 |
136 | void AliITStrackerV2::UnloadClusters() { |
137 | //-------------------------------------------------------------------- |
138 | //This function unloads ITS clusters |
139 | //-------------------------------------------------------------------- |
18856a77 |
140 | for (Int_t i=0; i<kMaxLayer; i++) fgLayers[i].ResetClusters(); |
006b5f7f |
141 | } |
142 | |
880f41b9 |
143 | static Int_t CorrectForDeadZoneMaterial(AliITStrackV2 *t) { |
144 | //-------------------------------------------------------------------- |
145 | // Correction for the material between the TPC and the ITS |
146 | // (should it belong to the TPC code ?) |
147 | //-------------------------------------------------------------------- |
148 | Double_t riw=80., diw=0.0053, x0iw=30; // TPC inner wall ? |
149 | Double_t rcd=61., dcd=0.0053, x0cd=30; // TPC "central drum" ? |
150 | Double_t yr=12.8, dr=0.03; // rods ? |
151 | Double_t zm=0.2, dm=0.40; // membrane |
152 | //Double_t rr=52., dr=0.19, x0r=24., yyr=7.77; //rails |
153 | Double_t rs=50., ds=0.001; // something belonging to the ITS (screen ?) |
154 | |
155 | if (t->GetX() > riw) { |
156 | if (!t->PropagateTo(riw,diw,x0iw)) return 1; |
157 | if (TMath::Abs(t->GetY())>yr) t->CorrectForMaterial(dr); |
158 | if (TMath::Abs(t->GetZ())<zm) t->CorrectForMaterial(dm); |
159 | if (!t->PropagateTo(rcd,dcd,x0cd)) return 1; |
160 | //Double_t x,y,z; t->GetGlobalXYZat(rr,x,y,z); |
161 | //if (TMath::Abs(y)<yyr) t->PropagateTo(rr,dr,x0r); |
162 | if (!t->PropagateTo(rs,ds)) return 1; |
163 | } else if (t->GetX() < rs) { |
164 | if (!t->PropagateTo(rs,-ds)) return 1; |
165 | //Double_t x,y,z; t->GetGlobalXYZat(rr,x,y,z); |
166 | //if (TMath::Abs(y)<yyr) t->PropagateTo(rr,-dr,x0r); |
167 | if (!t->PropagateTo(rcd,-dcd,x0cd)) return 1; |
168 | if (!t->PropagateTo(riw,-diw,x0iw)) return 1; |
169 | } else { |
170 | ::Error("CorrectForDeadZoneMaterial","track is already in the dead zone !"); |
171 | return 1; |
172 | } |
173 | |
174 | return 0; |
175 | } |
176 | |
c630aafd |
177 | Int_t AliITStrackerV2::Clusters2Tracks(AliESD *event) { |
006b5f7f |
178 | //-------------------------------------------------------------------- |
c630aafd |
179 | // This functions reconstructs ITS tracks |
180 | // The clusters must be already loaded ! |
006b5f7f |
181 | //-------------------------------------------------------------------- |
c630aafd |
182 | TObjArray itsTracks(15000); |
006b5f7f |
183 | |
c630aafd |
184 | {/* Read ESD tracks */ |
185 | Int_t nentr=event->GetNumberOfTracks(); |
186 | Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr); |
187 | while (nentr--) { |
188 | AliESDtrack *esd=event->GetTrack(nentr); |
189 | |
190 | if (esd->GetStatus() != AliESDtrack::kTPCin) continue; |
191 | |
192 | AliITStrackV2 *t=0; |
193 | try { |
194 | t=new AliITStrackV2(*esd); |
195 | } catch (const Char_t *msg) { |
196 | Warning("Clusters2Tracks",msg); |
197 | delete t; |
198 | continue; |
199 | } |
200 | if (TMath::Abs(t->GetD())>4) continue; |
006b5f7f |
201 | |
c630aafd |
202 | if (CorrectForDeadZoneMaterial(t)!=0) { |
203 | Warning("Clusters2Tracks", |
204 | "failed to correct for the material in the dead zone !\n"); |
205 | delete t; |
206 | continue; |
207 | } |
208 | itsTracks.AddLast(t); |
209 | } |
210 | } /* End Read ESD tracks */ |
211 | |
212 | itsTracks.Sort(); |
213 | Int_t nentr=itsTracks.GetEntriesFast(); |
214 | |
215 | Int_t ntrk=0; |
216 | for (fPass=0; fPass<2; fPass++) { |
217 | Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue; |
218 | for (Int_t i=0; i<nentr; i++) { |
219 | AliITStrackV2 *t=(AliITStrackV2*)itsTracks.UncheckedAt(i); |
220 | if (t==0) continue; //this track has been already tracked |
221 | Int_t tpcLabel=t->GetLabel(); //save the TPC track label |
222 | |
223 | ResetTrackToFollow(*t); |
224 | ResetBestTrack(); |
225 | |
226 | for (FollowProlongation(); fI<kMaxLayer; fI++) { |
227 | while (TakeNextProlongation()) FollowProlongation(); |
228 | } |
229 | |
230 | if (fBestTrack.GetNumberOfClusters() == 0) continue; |
231 | |
232 | if (fConstraint[fPass]) { |
233 | ResetTrackToFollow(*t); |
234 | if (!RefitAt(3.7, &fTrackToFollow, &fBestTrack)) continue; |
235 | ResetBestTrack(); |
236 | } |
237 | |
238 | fBestTrack.SetLabel(tpcLabel); |
239 | fBestTrack.CookdEdx(); |
240 | CookLabel(&fBestTrack,0.); //For comparison only |
241 | fBestTrack.UpdateESDtrack(AliESDtrack::kITSin); |
242 | UseClusters(&fBestTrack); |
243 | delete itsTracks.RemoveAt(i); |
244 | ntrk++; |
245 | } |
246 | } |
247 | |
248 | itsTracks.Delete(); |
249 | |
250 | Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk); |
251 | |
252 | return 0; |
253 | } |
254 | |
255 | Int_t AliITStrackerV2::Clusters2Tracks(TTree *tpcTree, TTree *itsTree) { |
256 | //-------------------------------------------------------------------- |
257 | // This functions reconstructs ITS tracks |
258 | // The clusters must be already loaded ! |
259 | //-------------------------------------------------------------------- |
a7554aa9 |
260 | Int_t nentr=0; TObjArray itsTracks(15000); |
7f6ddf58 |
261 | |
df02fd67 |
262 | Warning("Clusters2Tracks(TTree *, TTree *)", |
263 | "Will be removed soon ! Use Clusters2Tracks(AliESD *) instead."); |
264 | |
7f6ddf58 |
265 | {/* Read TPC tracks */ |
7f6ddf58 |
266 | AliTPCtrack *itrack=new AliTPCtrack; |
c630aafd |
267 | TBranch *branch=tpcTree->GetBranch("tracks"); |
268 | if (!branch) { |
269 | Error("Clusters2Tracks","Can't get the branch !"); |
270 | return 1; |
271 | } |
7f6ddf58 |
272 | tpcTree->SetBranchAddress("tracks",&itrack); |
273 | nentr=(Int_t)tpcTree->GetEntries(); |
c630aafd |
274 | |
880f41b9 |
275 | Info("Clusters2Tracks","Number of TPC tracks: %d\n",nentr); |
276 | |
7f6ddf58 |
277 | for (Int_t i=0; i<nentr; i++) { |
278 | tpcTree->GetEvent(i); |
4ab260d6 |
279 | AliITStrackV2 *t=0; |
280 | try { |
281 | t=new AliITStrackV2(*itrack); |
282 | } catch (const Char_t *msg) { |
8676d691 |
283 | Warning("Clusters2Tracks",msg); |
4ab260d6 |
284 | delete t; |
285 | continue; |
286 | } |
a9a2d814 |
287 | if (TMath::Abs(t->GetD())>4) continue; |
288 | |
880f41b9 |
289 | if (CorrectForDeadZoneMaterial(t)!=0) { |
290 | Warning("Clusters2Tracks", |
291 | "failed to correct for the material in the dead zone !\n"); |
292 | continue; |
293 | } |
a9a2d814 |
294 | |
295 | itsTracks.AddLast(t); |
7f6ddf58 |
296 | } |
7f6ddf58 |
297 | delete itrack; |
006b5f7f |
298 | } |
7f6ddf58 |
299 | itsTracks.Sort(); |
880f41b9 |
300 | nentr=itsTracks.GetEntriesFast(); |
006b5f7f |
301 | |
7f6ddf58 |
302 | |
006b5f7f |
303 | AliITStrackV2 *otrack=&fBestTrack; |
c630aafd |
304 | TBranch *branch=itsTree->GetBranch("tracks"); |
305 | if (!branch) itsTree->Branch("tracks","AliITStrackV2",&otrack,32000,3); |
306 | else branch->SetAddress(&otrack); |
006b5f7f |
307 | |
7f6ddf58 |
308 | for (fPass=0; fPass<2; fPass++) { |
309 | Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue; |
310 | for (Int_t i=0; i<nentr; i++) { |
7f6ddf58 |
311 | AliITStrackV2 *t=(AliITStrackV2*)itsTracks.UncheckedAt(i); |
312 | if (t==0) continue; //this track has been already tracked |
313 | Int_t tpcLabel=t->GetLabel(); //save the TPC track label |
a9a2d814 |
314 | |
4ab260d6 |
315 | ResetTrackToFollow(*t); |
7f6ddf58 |
316 | ResetBestTrack(); |
006b5f7f |
317 | |
c630aafd |
318 | for (FollowProlongation(); fI<kMaxLayer; fI++) { |
319 | while (TakeNextProlongation()) FollowProlongation(); |
320 | } |
006b5f7f |
321 | |
c0dd5278 |
322 | if (fBestTrack.GetNumberOfClusters() == 0) continue; |
8676d691 |
323 | |
324 | if (fConstraint[fPass]) { |
c630aafd |
325 | ResetTrackToFollow(*t); |
326 | if (!RefitAt(3.7, &fTrackToFollow, &fBestTrack)) continue; |
327 | ResetBestTrack(); |
8676d691 |
328 | } |
4ab260d6 |
329 | |
8676d691 |
330 | fBestTrack.SetLabel(tpcLabel); |
331 | fBestTrack.CookdEdx(); |
332 | CookLabel(&fBestTrack,0.); //For comparison only |
c630aafd |
333 | itsTree->Fill(); |
8676d691 |
334 | UseClusters(&fBestTrack); |
335 | delete itsTracks.RemoveAt(i); |
7f6ddf58 |
336 | } |
006b5f7f |
337 | } |
006b5f7f |
338 | |
c630aafd |
339 | nentr=(Int_t)itsTree->GetEntries(); |
880f41b9 |
340 | Info("Clusters2Tracks","Number of prolonged tracks: %d\n",nentr); |
8676d691 |
341 | |
7f6ddf58 |
342 | itsTracks.Delete(); |
61ab8ea8 |
343 | |
c630aafd |
344 | return 0; |
345 | } |
346 | |
347 | Int_t AliITStrackerV2::PropagateBack(AliESD *event) { |
348 | //-------------------------------------------------------------------- |
349 | // This functions propagates reconstructed ITS tracks back |
350 | // The clusters must be loaded ! |
351 | //-------------------------------------------------------------------- |
352 | Int_t nentr=event->GetNumberOfTracks(); |
353 | Info("PropagateBack", "Number of ESD tracks: %d\n", nentr); |
354 | |
355 | Int_t ntrk=0; |
356 | for (Int_t i=0; i<nentr; i++) { |
357 | AliESDtrack *esd=event->GetTrack(i); |
358 | |
359 | if (esd->GetStatus()!=(AliESDtrack::kTPCin|AliESDtrack::kITSin)) continue; |
360 | |
361 | AliITStrackV2 *t=0; |
362 | try { |
363 | t=new AliITStrackV2(*esd); |
364 | } catch (const Char_t *msg) { |
365 | Warning("PropagateBack",msg); |
366 | delete t; |
367 | continue; |
368 | } |
369 | |
370 | ResetTrackToFollow(*t); |
371 | |
372 | // propagete to vertex [SR, GSI 17.02.2003] |
a9459f9c |
373 | // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov |
374 | if (fTrackToFollow.PropagateTo(3.,0.0028,65.19)) { |
375 | if (fTrackToFollow.PropagateToVertex()) { |
376 | fTrackToFollow.StartTimeIntegral(); |
377 | } |
378 | fTrackToFollow.PropagateTo(3.,-0.0028,65.19); |
379 | } |
c630aafd |
380 | |
381 | fTrackToFollow.ResetCovariance(); fTrackToFollow.ResetClusters(); |
382 | if (RefitAt(49.,&fTrackToFollow,t)) { |
383 | if (CorrectForDeadZoneMaterial(&fTrackToFollow)!=0) { |
384 | Warning("PropagateBack", |
385 | "failed to correct for the material in the dead zone !\n"); |
386 | delete t; |
387 | continue; |
388 | } |
389 | fTrackToFollow.SetLabel(t->GetLabel()); |
390 | fTrackToFollow.CookdEdx(); |
391 | CookLabel(&fTrackToFollow,0.); //For comparison only |
392 | fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout); |
393 | UseClusters(&fTrackToFollow); |
394 | ntrk++; |
395 | } |
396 | delete t; |
397 | } |
398 | |
399 | Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk); |
61ab8ea8 |
400 | |
83d73500 |
401 | return 0; |
402 | } |
403 | |
c630aafd |
404 | Int_t AliITStrackerV2::RefitInward(AliESD *event) { |
83d73500 |
405 | //-------------------------------------------------------------------- |
406 | // This functions refits ITS tracks using the |
407 | // "inward propagated" TPC tracks |
c630aafd |
408 | // The clusters must be loaded ! |
83d73500 |
409 | //-------------------------------------------------------------------- |
c630aafd |
410 | Int_t nentr=event->GetNumberOfTracks(); |
411 | Info("RefitInward", "Number of ESD tracks: %d\n", nentr); |
412 | |
413 | Int_t ntrk=0; |
414 | for (Int_t i=0; i<nentr; i++) { |
415 | AliESDtrack *esd=event->GetTrack(i); |
416 | |
417 | ULong_t flags = AliESDtrack::kITSin | AliESDtrack::kTPCrefit; |
418 | |
419 | if ( (esd->GetStatus() & flags) != flags ) continue; |
420 | if ( esd->GetStatus() & AliESDtrack::kITSrefit) continue; |
421 | |
422 | AliITStrackV2 *t=0; |
423 | try { |
424 | t=new AliITStrackV2(*esd); |
425 | } catch (const Char_t *msg) { |
426 | Warning("RefitInward",msg); |
427 | delete t; |
428 | continue; |
429 | } |
430 | |
431 | if (CorrectForDeadZoneMaterial(t)!=0) { |
432 | Warning("RefitInward", |
433 | "failed to correct for the material in the dead zone !\n"); |
434 | delete t; |
435 | continue; |
436 | } |
437 | |
438 | ResetTrackToFollow(*t); |
439 | fTrackToFollow.ResetClusters(); |
440 | |
441 | //Refitting... |
442 | if (RefitAt(3.7, &fTrackToFollow, t)) { |
443 | fTrackToFollow.SetLabel(t->GetLabel()); |
444 | fTrackToFollow.CookdEdx(); |
445 | CookLabel(&fTrackToFollow,0.); //For comparison only |
18856a77 |
446 | |
df02fd67 |
447 | if (fTrackToFollow.PropagateTo(3.,0.0028,65.19)) //The beam pipe |
448 | if (fTrackToFollow.PropagateToVertex()) { |
449 | fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit); |
450 | UseClusters(&fTrackToFollow); |
451 | ntrk++; |
452 | } |
c630aafd |
453 | } |
454 | delete t; |
455 | } |
456 | |
457 | Info("RefitInward","Number of refitted tracks: %d\n",ntrk); |
83d73500 |
458 | |
c630aafd |
459 | return 0; |
460 | } |
83d73500 |
461 | |
006b5f7f |
462 | AliCluster *AliITStrackerV2::GetCluster(Int_t index) const { |
463 | //-------------------------------------------------------------------- |
464 | // Return pointer to a given cluster |
465 | //-------------------------------------------------------------------- |
466 | Int_t l=(index & 0xf0000000) >> 28; |
467 | Int_t c=(index & 0x0fffffff) >> 00; |
18856a77 |
468 | return fgLayers[l].GetCluster(c); |
006b5f7f |
469 | } |
470 | |
471 | |
472 | void AliITStrackerV2::FollowProlongation() { |
473 | //-------------------------------------------------------------------- |
474 | //This function finds a track prolongation |
475 | //-------------------------------------------------------------------- |
c0dd5278 |
476 | while (fI>fLastLayerToTrackTo) { |
a9a2d814 |
477 | Int_t i=fI-1; |
8676d691 |
478 | |
18856a77 |
479 | AliITSlayer &layer=fgLayers[i]; |
a9a2d814 |
480 | AliITStrackV2 &track=fTracks[i]; |
006b5f7f |
481 | |
14825d5a |
482 | Double_t r=layer.GetR(); |
61ab8ea8 |
483 | |
a9a2d814 |
484 | if (i==3 || i==1) { |
18856a77 |
485 | Double_t rs=0.5*(fgLayers[i+1].GetR() + r); |
61ab8ea8 |
486 | Double_t d=0.0034, x0=38.6; |
487 | if (i==1) {rs=9.; d=0.0097; x0=42;} |
488 | if (!fTrackToFollow.PropagateTo(rs,d,x0)) { |
8676d691 |
489 | //Warning("FollowProlongation","propagation failed !\n"); |
c0dd5278 |
490 | return; |
a9a2d814 |
491 | } |
006b5f7f |
492 | } |
493 | |
494 | //find intersection |
495 | Double_t x,y,z; |
14825d5a |
496 | if (!fTrackToFollow.GetGlobalXYZat(r,x,y,z)) { |
8676d691 |
497 | //Warning("FollowProlongation","failed to estimate track !\n"); |
c0dd5278 |
498 | return; |
006b5f7f |
499 | } |
500 | Double_t phi=TMath::ATan2(y,x); |
f363d377 |
501 | |
006b5f7f |
502 | Int_t idet=layer.FindDetectorIndex(phi,z); |
503 | if (idet<0) { |
8676d691 |
504 | //Warning("FollowProlongation","failed to find a detector !\n"); |
c0dd5278 |
505 | return; |
006b5f7f |
506 | } |
507 | |
508 | //propagate to the intersection |
509 | const AliITSdetector &det=layer.GetDetector(idet); |
14825d5a |
510 | phi=det.GetPhi(); |
a9a2d814 |
511 | if (!fTrackToFollow.Propagate(phi,det.GetR())) { |
8676d691 |
512 | //Warning("FollowProlongation","propagation failed !\n"); |
c0dd5278 |
513 | return; |
006b5f7f |
514 | } |
515 | fTrackToFollow.SetDetectorIndex(idet); |
516 | |
517 | //Select possible prolongations and store the current track estimation |
518 | track.~AliITStrackV2(); new(&track) AliITStrackV2(fTrackToFollow); |
8676d691 |
519 | Double_t dz=7*TMath::Sqrt(track.GetSigmaZ2() + kSigmaZ2[i]); |
520 | Double_t dy=7*TMath::Sqrt(track.GetSigmaY2() + kSigmaY2[i]); |
521 | Double_t road=layer.GetRoad(); |
522 | if (dz*dy>road*road) { |
523 | Double_t dd=TMath::Sqrt(dz*dy), scz=dz/dd, scy=dy/dd; |
524 | dz=road*scz; dy=road*scy; |
525 | } |
b87bd7cd |
526 | |
527 | //Double_t dz=4*TMath::Sqrt(track.GetSigmaZ2() + kSigmaZ2[i]); |
14825d5a |
528 | if (dz < 0.5*TMath::Abs(track.GetTgl())) dz=0.5*TMath::Abs(track.GetTgl()); |
7f6ddf58 |
529 | if (dz > kMaxRoad) { |
8676d691 |
530 | //Warning("FollowProlongation","too broad road in Z !\n"); |
c0dd5278 |
531 | return; |
006b5f7f |
532 | } |
a9a2d814 |
533 | |
c0dd5278 |
534 | if (TMath::Abs(fTrackToFollow.GetZ()-GetZ()) > r+dz) return; |
a9a2d814 |
535 | |
b87bd7cd |
536 | //Double_t dy=4*TMath::Sqrt(track.GetSigmaY2() + kSigmaY2[i]); |
14825d5a |
537 | if (dy < 0.5*TMath::Abs(track.GetSnp())) dy=0.5*TMath::Abs(track.GetSnp()); |
7f6ddf58 |
538 | if (dy > kMaxRoad) { |
8676d691 |
539 | //Warning("FollowProlongation","too broad road in Y !\n"); |
c0dd5278 |
540 | return; |
006b5f7f |
541 | } |
a9a2d814 |
542 | |
7f6ddf58 |
543 | Double_t zmin=track.GetZ() - dz; |
006b5f7f |
544 | Double_t zmax=track.GetZ() + dz; |
14825d5a |
545 | Double_t ymin=track.GetY() + r*phi - dy; |
546 | Double_t ymax=track.GetY() + r*phi + dy; |
a9a2d814 |
547 | layer.SelectClusters(zmin,zmax,ymin,ymax); |
548 | fI--; |
006b5f7f |
549 | |
006b5f7f |
550 | //take another prolongation |
c0dd5278 |
551 | if (!TakeNextProlongation()) |
552 | if (fLayersNotToSkip[fI]) return; |
006b5f7f |
553 | |
554 | } |
555 | |
556 | //deal with the best track |
557 | Int_t ncl=fTrackToFollow.GetNumberOfClusters(); |
558 | Int_t nclb=fBestTrack.GetNumberOfClusters(); |
559 | if (ncl) |
560 | if (ncl >= nclb) { |
561 | Double_t chi2=fTrackToFollow.GetChi2(); |
562 | if (chi2/ncl < kChi2PerCluster) { |
563 | if (ncl > nclb || chi2 < fBestTrack.GetChi2()) { |
564 | ResetBestTrack(); |
565 | } |
566 | } |
567 | } |
568 | |
006b5f7f |
569 | } |
570 | |
006b5f7f |
571 | Int_t AliITStrackerV2::TakeNextProlongation() { |
572 | //-------------------------------------------------------------------- |
a9a2d814 |
573 | // This function takes another track prolongation |
574 | // |
575 | // dEdx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch |
006b5f7f |
576 | //-------------------------------------------------------------------- |
18856a77 |
577 | AliITSlayer &layer=fgLayers[fI]; |
4ab260d6 |
578 | ResetTrackToFollow(fTracks[fI]); |
006b5f7f |
579 | |
b87bd7cd |
580 | Double_t dz=7*TMath::Sqrt(fTrackToFollow.GetSigmaZ2() + kSigmaZ2[fI]); |
581 | Double_t dy=7*TMath::Sqrt(fTrackToFollow.GetSigmaY2() + kSigmaY2[fI]); |
8676d691 |
582 | Double_t road=layer.GetRoad(); |
583 | if (dz*dy>road*road) { |
584 | Double_t dd=TMath::Sqrt(dz*dy), scz=dz/dd, scy=dy/dd; |
585 | dz=road*scz; dy=road*scy; |
586 | } |
006b5f7f |
587 | |
588 | const AliITSclusterV2 *c=0; Int_t ci=-1; |
589 | Double_t chi2=12345.; |
590 | while ((c=layer.GetNextCluster(ci))!=0) { |
006b5f7f |
591 | Int_t idet=c->GetDetectorIndex(); |
592 | |
4ab260d6 |
593 | if (fTrackToFollow.GetDetectorIndex()!=idet) { |
006b5f7f |
594 | const AliITSdetector &det=layer.GetDetector(idet); |
4ab260d6 |
595 | ResetTrackToFollow(fTracks[fI]); |
596 | if (!fTrackToFollow.Propagate(det.GetPhi(),det.GetR())) { |
8676d691 |
597 | //Warning("TakeNextProlongation","propagation failed !\n"); |
006b5f7f |
598 | continue; |
599 | } |
4ab260d6 |
600 | fTrackToFollow.SetDetectorIndex(idet); |
601 | if (TMath::Abs(fTrackToFollow.GetZ()-GetZ())>layer.GetR()+dz) continue; |
006b5f7f |
602 | } |
603 | |
4ab260d6 |
604 | if (TMath::Abs(fTrackToFollow.GetZ() - c->GetZ()) > dz) continue; |
605 | if (TMath::Abs(fTrackToFollow.GetY() - c->GetY()) > dy) continue; |
006b5f7f |
606 | |
4ab260d6 |
607 | chi2=fTrackToFollow.GetPredictedChi2(c); if (chi2<kMaxChi2) break; |
006b5f7f |
608 | } |
609 | |
006b5f7f |
610 | if (chi2>=kMaxChi2) return 0; |
611 | if (!c) return 0; |
612 | |
006b5f7f |
613 | if (!fTrackToFollow.Update(c,chi2,(fI<<28)+ci)) { |
8676d691 |
614 | //Warning("TakeNextProlongation","filtering failed !\n"); |
006b5f7f |
615 | return 0; |
616 | } |
23efe5f1 |
617 | |
4ab260d6 |
618 | if (fTrackToFollow.GetNumberOfClusters()>1) |
619 | if (TMath::Abs(fTrackToFollow.GetD())>4) return 0; |
620 | |
a9a2d814 |
621 | fTrackToFollow. |
622 | SetSampledEdx(c->GetQ(),fTrackToFollow.GetNumberOfClusters()-1); //b.b. |
623 | |
624 | { |
880f41b9 |
625 | Double_t x0; |
61ab8ea8 |
626 | Double_t d=layer.GetThickness(fTrackToFollow.GetY(),fTrackToFollow.GetZ(),x0); |
880f41b9 |
627 | fTrackToFollow.CorrectForMaterial(d,x0); |
a9a2d814 |
628 | } |
4ab260d6 |
629 | |
a9a2d814 |
630 | if (fConstraint[fPass]) { |
4ab260d6 |
631 | Double_t d=GetEffectiveThickness(0,0); //Think of this !!!! |
8676d691 |
632 | Double_t xyz[]={GetX(),GetY(),GetZ()}; |
633 | Double_t ers[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()}; |
634 | fTrackToFollow.Improve(d,xyz,ers); |
a9a2d814 |
635 | } |
006b5f7f |
636 | |
006b5f7f |
637 | return 1; |
638 | } |
639 | |
640 | |
006b5f7f |
641 | AliITStrackerV2::AliITSlayer::AliITSlayer() { |
642 | //-------------------------------------------------------------------- |
643 | //default AliITSlayer constructor |
644 | //-------------------------------------------------------------------- |
645 | fN=0; |
646 | fDetectors=0; |
647 | } |
648 | |
649 | AliITStrackerV2::AliITSlayer:: |
650 | AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd) { |
651 | //-------------------------------------------------------------------- |
652 | //main AliITSlayer constructor |
653 | //-------------------------------------------------------------------- |
654 | fR=r; fPhiOffset=p; fZOffset=z; |
655 | fNladders=nl; fNdetectors=nd; |
656 | fDetectors=new AliITSdetector[fNladders*fNdetectors]; |
657 | |
658 | fN=0; |
659 | fI=0; |
b87bd7cd |
660 | |
661 | fRoad=2*fR*TMath::Sqrt(3.14/1.);//assuming that there's only one cluster |
006b5f7f |
662 | } |
663 | |
664 | AliITStrackerV2::AliITSlayer::~AliITSlayer() { |
665 | //-------------------------------------------------------------------- |
666 | // AliITSlayer destructor |
667 | //-------------------------------------------------------------------- |
668 | delete[] fDetectors; |
669 | for (Int_t i=0; i<fN; i++) delete fClusters[i]; |
670 | } |
671 | |
61ab8ea8 |
672 | void AliITStrackerV2::AliITSlayer::ResetClusters() { |
673 | //-------------------------------------------------------------------- |
674 | // This function removes loaded clusters |
675 | //-------------------------------------------------------------------- |
676 | for (Int_t i=0; i<fN; i++) delete fClusters[i]; |
677 | fN=0; |
678 | fI=0; |
679 | } |
680 | |
b87bd7cd |
681 | void AliITStrackerV2::AliITSlayer::ResetRoad() { |
682 | //-------------------------------------------------------------------- |
683 | // This function calculates the road defined by the cluster density |
684 | //-------------------------------------------------------------------- |
685 | Int_t n=0; |
686 | for (Int_t i=0; i<fN; i++) { |
687 | if (TMath::Abs(fClusters[i]->GetZ())<fR) n++; |
688 | } |
689 | if (n>1) fRoad=2*fR*TMath::Sqrt(3.14/n); |
690 | } |
691 | |
006b5f7f |
692 | Int_t AliITStrackerV2::AliITSlayer::InsertCluster(AliITSclusterV2 *c) { |
693 | //-------------------------------------------------------------------- |
694 | //This function adds a cluster to this layer |
695 | //-------------------------------------------------------------------- |
696 | if (fN==kMaxClusterPerLayer) { |
8676d691 |
697 | ::Error("InsertCluster","Too many clusters !\n"); |
698 | return 1; |
006b5f7f |
699 | } |
700 | |
701 | if (fN==0) {fClusters[fN++]=c; return 0;} |
702 | Int_t i=FindClusterIndex(c->GetZ()); |
703 | memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliITSclusterV2*)); |
704 | fClusters[i]=c; fN++; |
705 | |
706 | return 0; |
707 | } |
708 | |
709 | Int_t AliITStrackerV2::AliITSlayer::FindClusterIndex(Double_t z) const { |
710 | //-------------------------------------------------------------------- |
711 | // This function returns the index of the nearest cluster |
712 | //-------------------------------------------------------------------- |
713 | if (fN==0) return 0; |
714 | if (z <= fClusters[0]->GetZ()) return 0; |
715 | if (z > fClusters[fN-1]->GetZ()) return fN; |
716 | Int_t b=0, e=fN-1, m=(b+e)/2; |
717 | for (; b<e; m=(b+e)/2) { |
718 | if (z > fClusters[m]->GetZ()) b=m+1; |
719 | else e=m; |
720 | } |
721 | return m; |
722 | } |
723 | |
724 | void AliITStrackerV2::AliITSlayer:: |
725 | SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) { |
726 | //-------------------------------------------------------------------- |
727 | // This function sets the "window" |
728 | //-------------------------------------------------------------------- |
729 | fI=FindClusterIndex(zmin); fZmax=zmax; |
14825d5a |
730 | Double_t circle=2*TMath::Pi()*fR; |
731 | if (ymax>circle) { ymax-=circle; ymin-=circle; } |
006b5f7f |
732 | fYmin=ymin; fYmax=ymax; |
733 | } |
734 | |
735 | const AliITSclusterV2 *AliITStrackerV2::AliITSlayer::GetNextCluster(Int_t &ci){ |
736 | //-------------------------------------------------------------------- |
737 | // This function returns clusters within the "window" |
738 | //-------------------------------------------------------------------- |
739 | const AliITSclusterV2 *cluster=0; |
740 | for (Int_t i=fI; i<fN; i++) { |
741 | const AliITSclusterV2 *c=fClusters[i]; |
742 | if (c->GetZ() > fZmax) break; |
743 | if (c->IsUsed()) continue; |
744 | const AliITSdetector &det=GetDetector(c->GetDetectorIndex()); |
745 | Double_t y=fR*det.GetPhi() + c->GetY(); |
746 | |
747 | if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi(); |
748 | if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi(); |
749 | |
750 | if (y<fYmin) continue; |
751 | if (y>fYmax) continue; |
752 | cluster=c; ci=i; |
753 | fI=i+1; |
754 | break; |
755 | } |
7f6ddf58 |
756 | |
006b5f7f |
757 | return cluster; |
758 | } |
759 | |
760 | Int_t AliITStrackerV2::AliITSlayer:: |
761 | FindDetectorIndex(Double_t phi, Double_t z) const { |
762 | //-------------------------------------------------------------------- |
763 | //This function finds the detector crossed by the track |
764 | //-------------------------------------------------------------------- |
f363d377 |
765 | Double_t dphi=-(phi-fPhiOffset); |
006b5f7f |
766 | if (dphi < 0) dphi += 2*TMath::Pi(); |
767 | else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi(); |
768 | Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5); |
3e3e8427 |
769 | if (np>=fNladders) np-=fNladders; |
770 | if (np<0) np+=fNladders; |
006b5f7f |
771 | |
772 | Double_t dz=fZOffset-z; |
773 | Int_t nz=Int_t(dz*(fNdetectors-1)*0.5/fZOffset+0.5); |
3e3e8427 |
774 | if (nz>=fNdetectors) return -1; |
775 | if (nz<0) return -1; |
006b5f7f |
776 | |
006b5f7f |
777 | return np*fNdetectors + nz; |
778 | } |
779 | |
780 | Double_t |
61ab8ea8 |
781 | AliITStrackerV2::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0) |
782 | const { |
a9a2d814 |
783 | //-------------------------------------------------------------------- |
784 | //This function returns the layer thickness at this point (units X0) |
785 | //-------------------------------------------------------------------- |
786 | Double_t d=0.0085; |
61ab8ea8 |
787 | x0=21.82; |
a9a2d814 |
788 | |
789 | if (43<fR&&fR<45) { //SSD2 |
61ab8ea8 |
790 | Double_t dd=0.0034; |
791 | d=dd; |
792 | if (TMath::Abs(y-0.00)>3.40) d+=dd; |
793 | if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);} |
794 | if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);} |
a9a2d814 |
795 | for (Int_t i=0; i<12; i++) { |
61ab8ea8 |
796 | if (TMath::Abs(z-3.9*(i+0.5))<0.15) { |
797 | if (TMath::Abs(y-0.00)>3.40) d+=dd; |
798 | d+=0.0034; |
799 | break; |
800 | } |
801 | if (TMath::Abs(z+3.9*(i+0.5))<0.15) { |
802 | if (TMath::Abs(y-0.00)>3.40) d+=dd; |
803 | d+=0.0034; |
804 | break; |
805 | } |
806 | if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;} |
807 | if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;} |
a9a2d814 |
808 | } |
809 | } else |
810 | if (37<fR&&fR<41) { //SSD1 |
61ab8ea8 |
811 | Double_t dd=0.0034; |
812 | d=dd; |
813 | if (TMath::Abs(y-0.00)>3.40) d+=dd; |
814 | if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);} |
815 | if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);} |
a9a2d814 |
816 | for (Int_t i=0; i<11; i++) { |
61ab8ea8 |
817 | if (TMath::Abs(z-3.9*i)<0.15) { |
818 | if (TMath::Abs(y-0.00)>3.40) d+=dd; |
819 | d+=dd; |
820 | break; |
821 | } |
822 | if (TMath::Abs(z+3.9*i)<0.15) { |
823 | if (TMath::Abs(y-0.00)>3.40) d+=dd; |
824 | d+=dd; |
825 | break; |
826 | } |
827 | if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;} |
828 | if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;} |
a9a2d814 |
829 | } |
830 | } else |
831 | if (13<fR&&fR<26) { //SDD |
61ab8ea8 |
832 | Double_t dd=0.0033; |
833 | d=dd; |
834 | if (TMath::Abs(y-0.00)>3.30) d+=dd; |
835 | |
836 | if (TMath::Abs(y-1.80)<0.55) { |
837 | d+=0.016; |
838 | for (Int_t j=0; j<20; j++) { |
839 | if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;} |
840 | if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;} |
841 | } |
842 | } |
843 | if (TMath::Abs(y+1.80)<0.55) { |
844 | d+=0.016; |
845 | for (Int_t j=0; j<20; j++) { |
846 | if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;} |
847 | if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;} |
848 | } |
849 | } |
850 | |
851 | for (Int_t i=0; i<4; i++) { |
852 | if (TMath::Abs(z-7.3*i)<0.60) { |
853 | d+=dd; |
854 | if (TMath::Abs(y-0.00)>3.30) d+=dd; |
855 | break; |
856 | } |
857 | if (TMath::Abs(z+7.3*i)<0.60) { |
858 | d+=dd; |
859 | if (TMath::Abs(y-0.00)>3.30) d+=dd; |
860 | break; |
861 | } |
a9a2d814 |
862 | } |
863 | } else |
864 | if (6<fR&&fR<8) { //SPD2 |
61ab8ea8 |
865 | Double_t dd=0.0063; x0=21.5; |
866 | d=dd; |
867 | if (TMath::Abs(y-3.08)>0.5) d+=dd; |
868 | //if (TMath::Abs(y-3.08)>0.45) d+=dd; |
869 | if (TMath::Abs(y-3.03)<0.10) {d+=0.014;} |
a9a2d814 |
870 | } else |
871 | if (3<fR&&fR<5) { //SPD1 |
61ab8ea8 |
872 | Double_t dd=0.0063; x0=21.5; |
873 | d=dd; |
874 | if (TMath::Abs(y+0.21)>0.6) d+=dd; |
875 | //if (TMath::Abs(y+0.21)>0.45) d+=dd; |
876 | if (TMath::Abs(y+0.10)<0.10) {d+=0.014;} |
a9a2d814 |
877 | } |
878 | |
a9a2d814 |
879 | return d; |
880 | } |
006b5f7f |
881 | |
a9a2d814 |
882 | Double_t AliITStrackerV2::GetEffectiveThickness(Double_t y,Double_t z) const |
006b5f7f |
883 | { |
884 | //-------------------------------------------------------------------- |
a9a2d814 |
885 | //Returns the thickness between the current layer and the vertex (units X0) |
006b5f7f |
886 | //-------------------------------------------------------------------- |
61ab8ea8 |
887 | Double_t d=0.0028*3*3; //beam pipe |
888 | Double_t x0=0; |
006b5f7f |
889 | |
18856a77 |
890 | Double_t xn=fgLayers[fI].GetR(); |
006b5f7f |
891 | for (Int_t i=0; i<fI; i++) { |
18856a77 |
892 | Double_t xi=fgLayers[i].GetR(); |
893 | d+=fgLayers[i].GetThickness(y,z,x0)*xi*xi; |
006b5f7f |
894 | } |
895 | |
896 | if (fI>1) { |
61ab8ea8 |
897 | Double_t xi=9.; |
898 | d+=0.0097*xi*xi; |
006b5f7f |
899 | } |
900 | |
901 | if (fI>3) { |
18856a77 |
902 | Double_t xi=0.5*(fgLayers[3].GetR()+fgLayers[4].GetR()); |
61ab8ea8 |
903 | d+=0.0034*xi*xi; |
006b5f7f |
904 | } |
61ab8ea8 |
905 | |
006b5f7f |
906 | return d/(xn*xn); |
907 | } |
908 | |
006b5f7f |
909 | Int_t AliITStrackerV2::AliITSlayer::InRoad() const { |
910 | //-------------------------------------------------------------------- |
911 | // This function returns number of clusters within the "window" |
912 | //-------------------------------------------------------------------- |
913 | Int_t ncl=0; |
914 | for (Int_t i=fI; i<fN; i++) { |
915 | const AliITSclusterV2 *c=fClusters[i]; |
916 | if (c->GetZ() > fZmax) break; |
a9a2d814 |
917 | if (c->IsUsed()) continue; |
006b5f7f |
918 | const AliITSdetector &det=GetDetector(c->GetDetectorIndex()); |
919 | Double_t y=fR*det.GetPhi() + c->GetY(); |
920 | |
921 | if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi(); |
922 | if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi(); |
923 | |
924 | if (y<fYmin) continue; |
925 | if (y>fYmax) continue; |
926 | ncl++; |
927 | } |
928 | return ncl; |
929 | } |
930 | |
880f41b9 |
931 | Bool_t |
c630aafd |
932 | AliITStrackerV2::RefitAt(Double_t xx,AliITStrackV2 *t,const AliITStrackV2 *c) { |
4ab260d6 |
933 | //-------------------------------------------------------------------- |
c630aafd |
934 | // This function refits the track "t" at the position "x" using |
935 | // the clusters from "c" |
4ab260d6 |
936 | //-------------------------------------------------------------------- |
880f41b9 |
937 | Int_t index[kMaxLayer]; |
938 | Int_t k; |
939 | for (k=0; k<kMaxLayer; k++) index[k]=-1; |
c630aafd |
940 | Int_t nc=c->GetNumberOfClusters(); |
880f41b9 |
941 | for (k=0; k<nc; k++) { |
c630aafd |
942 | Int_t idx=c->GetClusterIndex(k),nl=(idx&0xf0000000)>>28; |
880f41b9 |
943 | index[nl]=idx; |
944 | } |
880f41b9 |
945 | |
4ab260d6 |
946 | Int_t from, to, step; |
ee34184f |
947 | if (xx > t->GetX()) { |
4ab260d6 |
948 | from=0; to=kMaxLayer; |
949 | step=+1; |
950 | } else { |
951 | from=kMaxLayer-1; to=-1; |
952 | step=-1; |
953 | } |
954 | |
955 | for (Int_t i=from; i != to; i += step) { |
18856a77 |
956 | AliITSlayer &layer=fgLayers[i]; |
4ab260d6 |
957 | Double_t r=layer.GetR(); |
958 | |
959 | { |
960 | Double_t hI=i-0.5*step; |
880f41b9 |
961 | if (TMath::Abs(hI-1.5)<0.01 || TMath::Abs(hI-3.5)<0.01) { |
18856a77 |
962 | Double_t rs=0.5*(fgLayers[i-step].GetR() + r); |
61ab8ea8 |
963 | Double_t d=0.0034, x0=38.6; |
880f41b9 |
964 | if (TMath::Abs(hI-1.5)<0.01) {rs=9.; d=0.0097; x0=42;} |
965 | if (!t->PropagateTo(rs,-step*d,x0)) { |
4ab260d6 |
966 | return kFALSE; |
967 | } |
968 | } |
969 | } |
970 | |
880f41b9 |
971 | // remember old position [SR, GSI 18.02.2003] |
972 | Double_t oldX=0., oldY=0., oldZ=0.; |
973 | if (t->IsStartedTimeIntegral() && step==1) { |
974 | t->GetGlobalXYZat(t->GetX(),oldX,oldY,oldZ); |
975 | } |
976 | // |
977 | |
4ab260d6 |
978 | Double_t x,y,z; |
979 | if (!t->GetGlobalXYZat(r,x,y,z)) { |
980 | return kFALSE; |
981 | } |
982 | Double_t phi=TMath::ATan2(y,x); |
983 | Int_t idet=layer.FindDetectorIndex(phi,z); |
984 | if (idet<0) { |
985 | return kFALSE; |
986 | } |
987 | const AliITSdetector &det=layer.GetDetector(idet); |
988 | phi=det.GetPhi(); |
989 | if (!t->Propagate(phi,det.GetR())) { |
990 | return kFALSE; |
991 | } |
992 | t->SetDetectorIndex(idet); |
993 | |
994 | const AliITSclusterV2 *cl=0; |
995 | Double_t maxchi2=kMaxChi2; |
996 | |
997 | Int_t idx=index[i]; |
998 | if (idx>0) { |
999 | const AliITSclusterV2 *c=(AliITSclusterV2 *)GetCluster(idx); |
1000 | if (idet != c->GetDetectorIndex()) { |
1001 | idet=c->GetDetectorIndex(); |
1002 | const AliITSdetector &det=layer.GetDetector(idet); |
1003 | if (!t->Propagate(det.GetPhi(),det.GetR())) { |
1004 | return kFALSE; |
1005 | } |
1006 | t->SetDetectorIndex(idet); |
1007 | } |
1008 | Double_t chi2=t->GetPredictedChi2(c); |
c630aafd |
1009 | if (chi2<maxchi2) { |
1010 | cl=c; |
1011 | maxchi2=chi2; |
1012 | } else { |
1013 | return kFALSE; |
1014 | } |
4ab260d6 |
1015 | } |
4ab260d6 |
1016 | /* |
1017 | if (cl==0) |
1018 | if (t->GetNumberOfClusters()>2) { |
1019 | Double_t dz=4*TMath::Sqrt(t->GetSigmaZ2()+kSigmaZ2[i]); |
1020 | Double_t dy=4*TMath::Sqrt(t->GetSigmaY2()+kSigmaY2[i]); |
1021 | Double_t zmin=t->GetZ() - dz; |
1022 | Double_t zmax=t->GetZ() + dz; |
1023 | Double_t ymin=t->GetY() + phi*r - dy; |
1024 | Double_t ymax=t->GetY() + phi*r + dy; |
1025 | layer.SelectClusters(zmin,zmax,ymin,ymax); |
1026 | |
1027 | const AliITSclusterV2 *c=0; Int_t ci=-1; |
1028 | while ((c=layer.GetNextCluster(ci))!=0) { |
1029 | if (idet != c->GetDetectorIndex()) continue; |
1030 | Double_t chi2=t->GetPredictedChi2(c); |
1031 | if (chi2<maxchi2) { cl=c; maxchi2=chi2; idx=ci; } |
1032 | } |
1033 | } |
1034 | */ |
4ab260d6 |
1035 | if (cl) { |
1036 | if (!t->Update(cl,maxchi2,idx)) { |
1037 | return kFALSE; |
1038 | } |
880f41b9 |
1039 | t->SetSampledEdx(cl->GetQ(),t->GetNumberOfClusters()-1); |
4ab260d6 |
1040 | } |
1041 | |
1042 | { |
61ab8ea8 |
1043 | Double_t x0; |
1044 | Double_t d=layer.GetThickness(t->GetY(),t->GetZ(),x0); |
1045 | t->CorrectForMaterial(-step*d,x0); |
4ab260d6 |
1046 | } |
880f41b9 |
1047 | |
1048 | // track time update [SR, GSI 17.02.2003] |
1049 | if (t->IsStartedTimeIntegral() && step==1) { |
1050 | Double_t newX, newY, newZ; |
1051 | t->GetGlobalXYZat(t->GetX(),newX,newY,newZ); |
1052 | Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) + |
1053 | (oldZ-newZ)*(oldZ-newZ); |
1054 | t->AddTimeStep(TMath::Sqrt(dL2)); |
1055 | } |
1056 | // |
4ab260d6 |
1057 | |
1058 | } |
1059 | |
ee34184f |
1060 | if (!t->PropagateTo(xx,0.,0.)) return kFALSE; |
4ab260d6 |
1061 | return kTRUE; |
1062 | } |
1063 | |
b87bd7cd |
1064 | void AliITStrackerV2::UseClusters(const AliKalmanTrack *t, Int_t from) const { |
1065 | //-------------------------------------------------------------------- |
1066 | // This function marks clusters assigned to the track |
1067 | //-------------------------------------------------------------------- |
1068 | AliTracker::UseClusters(t,from); |
880f41b9 |
1069 | |
b87bd7cd |
1070 | AliITSclusterV2 *c=(AliITSclusterV2 *)GetCluster(t->GetClusterIndex(0)); |
1071 | //if (c->GetQ()>2) c->Use(); |
1072 | if (c->GetSigmaZ2()>0.1) c->Use(); |
1073 | c=(AliITSclusterV2 *)GetCluster(t->GetClusterIndex(1)); |
1074 | //if (c->GetQ()>2) c->Use(); |
1075 | if (c->GetSigmaZ2()>0.1) c->Use(); |
880f41b9 |
1076 | |
b87bd7cd |
1077 | } |