]>
Commit | Line | Data |
---|---|---|
73042f01 | 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 | ||
0fa7dfa7 | 16 | /* $Id$ */ |
73042f01 | 17 | |
18 | //------------------------------------------------------- | |
19 | // Implementation of the TPC tracker | |
20 | // | |
21 | // Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch | |
22 | //------------------------------------------------------- | |
73042f01 | 23 | #include <TObjArray.h> |
c630aafd | 24 | #include <TError.h> |
73042f01 | 25 | #include <TFile.h> |
be5b9287 | 26 | #include <TTree.h> |
c630aafd | 27 | |
28 | #include "AliESD.h" | |
be5b9287 | 29 | |
30 | #include "AliTPCtracker.h" | |
31 | #include "AliTPCcluster.h" | |
b9de75e1 | 32 | #include "AliTPCParam.h" |
c630aafd | 33 | #include "AliClusters.h" |
34 | ||
7138dcae | 35 | extern Double_t SigmaY2(Double_t, Double_t, Double_t); |
36 | extern Double_t SigmaZ2(Double_t, Double_t); | |
37 | ||
c630aafd | 38 | ClassImp(AliTPCtracker) |
83d73500 | 39 | |
b9de75e1 | 40 | //_____________________________________________________________________________ |
c630aafd | 41 | AliTPCtracker::AliTPCtracker(const AliTPCParam *par): |
42 | AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2) | |
b9de75e1 | 43 | { |
44 | //--------------------------------------------------------------------- | |
45 | // The main TPC tracker constructor | |
46 | //--------------------------------------------------------------------- | |
47 | fInnerSec=new AliTPCSector[fkNIS]; | |
48 | fOuterSec=new AliTPCSector[fkNOS]; | |
49 | ||
50 | Int_t i; | |
51 | for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0); | |
52 | for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1); | |
53 | ||
c630aafd | 54 | fParam = (AliTPCParam*) par; |
55 | fSeeds=0; | |
88cb7938 | 56 | |
c630aafd | 57 | // [SR 17.03.2003] |
58 | ||
59 | fBarrelFile = 0; | |
60 | fBarrelTree = 0; | |
61 | fBarrelArray = 0; | |
62 | fBarrelTrack = 0; | |
9c9d2487 | 63 | |
b9de75e1 | 64 | } |
65 | ||
66 | //_____________________________________________________________________________ | |
67 | AliTPCtracker::~AliTPCtracker() { | |
68 | //------------------------------------------------------------------ | |
69 | // TPC tracker destructor | |
70 | //------------------------------------------------------------------ | |
71 | delete[] fInnerSec; | |
72 | delete[] fOuterSec; | |
1c8d9aad | 73 | if (fSeeds) { |
74 | fSeeds->Delete(); | |
75 | delete fSeeds; | |
76 | } | |
c630aafd | 77 | |
78 | // [SR, 01.04.2003] | |
79 | if (fBarrelFile) { | |
80 | fBarrelFile->Close(); | |
81 | delete fBarrelFile; | |
82 | } | |
83 | } | |
84 | ||
85 | //_____________________________________________________________________________ | |
86 | ||
87 | void AliTPCtracker::SetBarrelTree(const char *mode) { | |
88 | // | |
89 | // Creates a tree for BarrelTracks | |
90 | // mode = "back" or "refit" | |
91 | // | |
92 | // [SR, 01.04.2003] | |
93 | // | |
94 | ||
95 | if (!IsStoringBarrel()) return; | |
96 | ||
97 | TDirectory *sav = gDirectory; | |
98 | if (!fBarrelFile) fBarrelFile = new TFile("AliBarrelTracks.root", "UPDATE"); | |
99 | ||
100 | char buff[40]; | |
101 | sprintf(buff, "BarrelTPC_%d_%s", GetEventNumber(), mode); | |
102 | ||
103 | fBarrelFile->cd(); | |
104 | fBarrelTree = new TTree(buff, "Barrel TPC tracks"); | |
105 | ||
106 | if (!fBarrelArray) fBarrelArray = new TClonesArray("AliBarrelTrack", 4); | |
107 | for(Int_t i=0; i<4; i++) new((*fBarrelArray)[i]) AliBarrelTrack(); | |
108 | ||
109 | fBarrelTree->Branch("tracks", &fBarrelArray); | |
110 | ||
111 | sav->cd(); | |
112 | } | |
113 | //_____________________________________________________________________________ | |
114 | ||
115 | void AliTPCtracker::StoreBarrelTrack(AliTPCtrack *ps, Int_t refPlane, Int_t isIn) { | |
116 | // | |
117 | // Stores Track at a given reference plane | |
118 | // | |
119 | // refPlane: 1-4 | |
120 | // isIn: 1 - backward, 2 - refit | |
121 | // | |
122 | ||
123 | if (!IsStoringBarrel()) return; | |
124 | if (refPlane < 0 || refPlane > 4) return; | |
125 | if (isIn > 2) return; | |
126 | ||
127 | static Int_t nClusters; | |
128 | static Int_t nWrong; | |
129 | static Double_t chi2; | |
130 | static Int_t index; | |
131 | ||
132 | Int_t newClusters, newWrong; | |
133 | Double_t newChi2; | |
134 | ||
135 | if ( (refPlane == 1 && isIn == kTrackBack) || | |
136 | (refPlane == 4 && isIn == kTrackRefit) ) { | |
137 | ||
138 | fBarrelArray->Clear(); | |
139 | nClusters = nWrong = 0; | |
140 | chi2 = 0.0; | |
141 | index = 0; | |
142 | } | |
143 | ||
144 | // propagate | |
145 | Double_t refX = 0; | |
146 | if (refPlane == 1) refX = fParam->GetInnerRadiusLow(); | |
147 | if (refPlane == 2) refX = fParam->GetInnerRadiusUp(); | |
148 | if (refPlane == 3) refX = fParam->GetOuterRadiusLow(); | |
149 | if (refPlane == 4) refX = fParam->GetOuterRadiusUp(); | |
150 | ||
151 | ps->PropagateTo(refX); | |
152 | ||
153 | fBarrelTrack = (AliBarrelTrack*)(*fBarrelArray)[index++]; | |
154 | ps->GetBarrelTrack(fBarrelTrack); | |
155 | ||
156 | newClusters = ps->GetNumberOfClusters() - nClusters; | |
157 | newWrong = ps->GetNWrong() - nWrong; | |
158 | newChi2 = ps->GetChi2() - chi2; | |
159 | ||
160 | nClusters = ps->GetNumberOfClusters(); | |
161 | nWrong = ps->GetNWrong(); | |
162 | chi2 = ps->GetChi2(); | |
163 | ||
164 | fBarrelTrack->SetNClusters(newClusters, newChi2); | |
165 | fBarrelTrack->SetNWrongClusters(newWrong); | |
166 | fBarrelTrack->SetRefPlane(refPlane, isIn); | |
b9de75e1 | 167 | } |
73042f01 | 168 | |
73042f01 | 169 | |
170 | //_____________________________________________________________________________ | |
bdbd0f7a | 171 | Double_t f1(Double_t x1,Double_t y1, |
73042f01 | 172 | Double_t x2,Double_t y2, |
173 | Double_t x3,Double_t y3) | |
174 | { | |
175 | //----------------------------------------------------------------- | |
176 | // Initial approximation of the track curvature | |
177 | //----------------------------------------------------------------- | |
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)); | |
183 | ||
184 | Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b); | |
185 | ||
186 | return -xr*yr/sqrt(xr*xr+yr*yr); | |
187 | } | |
188 | ||
189 | ||
190 | //_____________________________________________________________________________ | |
bdbd0f7a | 191 | Double_t f2(Double_t x1,Double_t y1, |
73042f01 | 192 | Double_t x2,Double_t y2, |
193 | Double_t x3,Double_t y3) | |
194 | { | |
195 | //----------------------------------------------------------------- | |
196 | // Initial approximation of the track curvature times center of curvature | |
197 | //----------------------------------------------------------------- | |
198 | Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1); | |
199 | Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)- | |
200 | (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2)); | |
201 | Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)- | |
202 | (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1)); | |
203 | ||
204 | Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b); | |
205 | ||
206 | return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr); | |
207 | } | |
208 | ||
209 | //_____________________________________________________________________________ | |
bdbd0f7a | 210 | Double_t f3(Double_t x1,Double_t y1, |
73042f01 | 211 | Double_t x2,Double_t y2, |
212 | Double_t z1,Double_t z2) | |
213 | { | |
214 | //----------------------------------------------------------------- | |
215 | // Initial approximation of the tangent of the track dip angle | |
216 | //----------------------------------------------------------------- | |
217 | return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); | |
218 | } | |
219 | ||
83d73500 | 220 | //_____________________________________________________________________________ |
c630aafd | 221 | Int_t AliTPCtracker::LoadClusters(TTree *cTree) { |
b9de75e1 | 222 | //----------------------------------------------------------------- |
c630aafd | 223 | // This function loads TPC clusters. |
b9de75e1 | 224 | //----------------------------------------------------------------- |
c630aafd | 225 | TBranch *branch=cTree->GetBranch("Segment"); |
226 | if (!branch) { | |
227 | Error("LoadClusters","Can't get the branch !"); | |
228 | return 1; | |
b9de75e1 | 229 | } |
230 | ||
c630aafd | 231 | AliClusters carray, *addr=&carray; |
232 | carray.SetClass("AliTPCcluster"); | |
233 | carray.SetArray(0); | |
234 | branch->SetAddress(&addr); | |
b9de75e1 | 235 | |
c630aafd | 236 | Int_t nentr=(Int_t)cTree->GetEntries(); |
83d73500 | 237 | |
c630aafd | 238 | for (Int_t i=0; i<nentr; i++) { |
239 | cTree->GetEvent(i); | |
bcc04e2a | 240 | |
c630aafd | 241 | Int_t ncl=carray.GetArray()->GetEntriesFast(); |
242 | ||
243 | Int_t nir=fInnerSec->GetNRows(), nor=fOuterSec->GetNRows(); | |
244 | Int_t id=carray.GetID(); | |
245 | if ((id<0) || (id>2*(fkNIS*nir + fkNOS*nor))) { | |
df02fd67 | 246 | Fatal("LoadClusters","Wrong index !"); |
bcc04e2a | 247 | } |
c630aafd | 248 | Int_t outindex = 2*fkNIS*nir; |
249 | if (id<outindex) { | |
250 | Int_t sec = id/nir; | |
251 | Int_t row = id - sec*nir; | |
252 | sec %= fkNIS; | |
253 | AliTPCRow &padrow=fInnerSec[sec][row]; | |
254 | while (ncl--) { | |
255 | AliTPCcluster *c=(AliTPCcluster*)carray[ncl]; | |
256 | padrow.InsertCluster(c,sec,row); | |
257 | } | |
258 | } else { | |
259 | id -= outindex; | |
260 | Int_t sec = id/nor; | |
261 | Int_t row = id - sec*nor; | |
262 | sec %= fkNOS; | |
263 | AliTPCRow &padrow=fOuterSec[sec][row]; | |
264 | while (ncl--) { | |
265 | AliTPCcluster *c=(AliTPCcluster*)carray[ncl]; | |
266 | padrow.InsertCluster(c,sec+fkNIS,row); | |
267 | } | |
268 | } | |
269 | carray.GetArray()->Clear(); | |
bcc04e2a | 270 | } |
88cb7938 | 271 | |
c630aafd | 272 | return 0; |
b9de75e1 | 273 | } |
274 | ||
275 | //_____________________________________________________________________________ | |
c630aafd | 276 | void AliTPCtracker::UnloadClusters() { |
b9de75e1 | 277 | //----------------------------------------------------------------- |
c630aafd | 278 | // This function unloads TPC clusters. |
b9de75e1 | 279 | //----------------------------------------------------------------- |
c630aafd | 280 | Int_t i; |
281 | for (i=0; i<fkNIS; i++) { | |
282 | Int_t nr=fInnerSec->GetNRows(); | |
283 | for (Int_t n=0; n<nr; n++) fInnerSec[i][n].ResetClusters(); | |
284 | } | |
285 | for (i=0; i<fkNOS; i++) { | |
286 | Int_t nr=fOuterSec->GetNRows(); | |
287 | for (Int_t n=0; n<nr; n++) fOuterSec[i][n].ResetClusters(); | |
b9de75e1 | 288 | } |
b9de75e1 | 289 | } |
290 | ||
291 | //_____________________________________________________________________________ | |
292 | Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) { | |
73042f01 | 293 | //----------------------------------------------------------------- |
294 | // This function tries to find a track prolongation. | |
295 | //----------------------------------------------------------------- | |
b9de75e1 | 296 | Double_t xt=t.GetX(); |
297 | const Int_t kSKIP=(t.GetNumberOfClusters()<10) ? kRowsToSkip : | |
298 | Int_t(0.5*fSectors->GetNRows()); | |
73042f01 | 299 | Int_t tryAgain=kSKIP; |
73042f01 | 300 | |
b9de75e1 | 301 | Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift(); |
302 | if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi(); | |
303 | if (alpha < 0. ) alpha += 2.*TMath::Pi(); | |
304 | Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN; | |
305 | ||
f03e3423 | 306 | Int_t nrows=fSectors->GetRowNumber(xt)-1; |
307 | for (Int_t nr=nrows; nr>=rf; nr--) { | |
b9de75e1 | 308 | Double_t x=fSectors->GetX(nr), ymax=fSectors->GetMaxY(nr); |
73042f01 | 309 | if (!t.PropagateTo(x)) return 0; |
310 | ||
311 | AliTPCcluster *cl=0; | |
312 | UInt_t index=0; | |
b9de75e1 | 313 | Double_t maxchi2=kMaxCHI2; |
314 | const AliTPCRow &krow=fSectors[s][nr]; | |
315 | Double_t pt=t.GetConvConst()/(100/0.299792458/0.2)/t.Get1Pt(); | |
316 | Double_t sy2=SigmaY2(t.GetX(),t.GetTgl(),pt); | |
73042f01 | 317 | Double_t sz2=SigmaZ2(t.GetX(),t.GetTgl()); |
318 | Double_t road=4.*sqrt(t.GetSigmaY2() + sy2), y=t.GetY(), z=t.GetZ(); | |
319 | ||
b9de75e1 | 320 | if (road>kMaxROAD) { |
73042f01 | 321 | if (t.GetNumberOfClusters()>4) |
c630aafd | 322 | Warning("FindProlongation","Too broad road !"); |
73042f01 | 323 | return 0; |
324 | } | |
325 | ||
326 | if (krow) { | |
327 | for (Int_t i=krow.Find(y-road); i<krow; i++) { | |
c630aafd | 328 | AliTPCcluster *c=(AliTPCcluster*)(krow[i]); |
329 | if (c->GetY() > y+road) break; | |
330 | if (c->IsUsed()) continue; | |
331 | if ((c->GetZ()-z)*(c->GetZ()-z) > 16.*(t.GetSigmaZ2()+sz2)) continue; | |
332 | Double_t chi2=t.GetPredictedChi2(c); | |
333 | if (chi2 > maxchi2) continue; | |
334 | maxchi2=chi2; | |
335 | cl=c; | |
73042f01 | 336 | index=krow.GetIndex(i); |
337 | } | |
338 | } | |
339 | if (cl) { | |
b9de75e1 | 340 | Float_t l=fSectors->GetPadPitchWidth(); |
024a7fe9 | 341 | Float_t corr=1.; if (nr>63) corr=0.67; // new (third) pad response ! |
342 | t.SetSampledEdx(cl->GetQ()/l*corr,t.GetNumberOfClusters()); | |
be9c5115 | 343 | if (!t.Update(cl,maxchi2,index)) { |
344 | if (!tryAgain--) return 0; | |
345 | } else tryAgain=kSKIP; | |
73042f01 | 346 | } else { |
347 | if (tryAgain==0) break; | |
348 | if (y > ymax) { | |
b9de75e1 | 349 | s = (s+1) % fN; |
350 | if (!t.Rotate(fSectors->GetAlpha())) return 0; | |
73042f01 | 351 | } else if (y <-ymax) { |
b9de75e1 | 352 | s = (s-1+fN) % fN; |
353 | if (!t.Rotate(-fSectors->GetAlpha())) return 0; | |
73042f01 | 354 | } |
355 | tryAgain--; | |
356 | } | |
357 | } | |
358 | ||
359 | return 1; | |
b9de75e1 | 360 | } |
c630aafd | 361 | //_____________________________________________________________________________ |
362 | ||
363 | Int_t AliTPCtracker::FollowRefitInward(AliTPCseed *seed, AliTPCtrack *track) { | |
364 | // | |
365 | // This function propagates seed inward TPC using old clusters | |
366 | // from the track. | |
367 | // | |
368 | // Sylwester Radomski, GSI | |
369 | // 26.02.2003 | |
370 | // | |
371 | ||
372 | // loop over rows | |
373 | ||
374 | Int_t nRows = fSectors->GetNRows(); | |
0fa7dfa7 | 375 | for (Int_t iRow = nRows-1; iRow >= 0; iRow--) { |
c630aafd | 376 | |
377 | Double_t x = fSectors->GetX(iRow); | |
378 | if (!seed->PropagateTo(x)) return 0; | |
379 | ||
380 | // try to find an assigned cluster in this row | |
381 | ||
382 | AliTPCcluster* cluster = NULL; | |
383 | Int_t idx = -1; | |
384 | Int_t sec = -1; | |
385 | for (Int_t iCluster = 0; iCluster < track->GetNumberOfClusters(); iCluster++) { | |
386 | idx = track->GetClusterIndex(iCluster); | |
387 | sec = (idx&0xff000000)>>24; | |
388 | Int_t row = (idx&0x00ff0000)>>16; | |
389 | if (((fSectors == fInnerSec) && (sec >= fkNIS)) || | |
390 | ((fSectors == fOuterSec) && (sec < fkNIS))) continue; | |
391 | if (row == iRow) { | |
392 | cluster = (AliTPCcluster*) GetCluster(idx); | |
393 | break; | |
394 | } | |
395 | } | |
396 | ||
397 | // update the track seed with the found cluster | |
398 | ||
399 | if (cluster) { | |
400 | Double_t dAlpha = fParam->GetAngle(sec) - seed->GetAlpha(); | |
401 | if (TMath::Abs(dAlpha) > 0.0001) { | |
402 | if (!seed->Rotate(dAlpha)) return 0; | |
403 | if (!seed->PropagateTo(x)) return 0; | |
404 | } | |
405 | ||
406 | seed->Update(cluster, seed->GetPredictedChi2(cluster), idx); | |
407 | } | |
408 | } | |
409 | ||
410 | return 1; | |
411 | } | |
b9de75e1 | 412 | |
413 | //_____________________________________________________________________________ | |
414 | Int_t AliTPCtracker::FollowBackProlongation | |
415 | (AliTPCseed& seed, const AliTPCtrack &track) { | |
416 | //----------------------------------------------------------------- | |
417 | // This function propagates tracks back through the TPC | |
418 | //----------------------------------------------------------------- | |
419 | Double_t alpha=seed.GetAlpha() - fSectors->GetAlphaShift(); | |
420 | if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi(); | |
421 | if (alpha < 0. ) alpha += 2.*TMath::Pi(); | |
422 | Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN; | |
423 | ||
424 | Int_t idx=-1, sec=-1, row=-1; | |
c630aafd | 425 | Int_t nc=seed.GetNumber(); |
426 | ||
b9de75e1 | 427 | if (nc--) { |
428 | idx=track.GetClusterIndex(nc); | |
429 | sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16; | |
430 | } | |
c630aafd | 431 | if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; } |
432 | else { if (sec < fkNIS) row=-1; } | |
b9de75e1 | 433 | |
434 | Int_t nr=fSectors->GetNRows(); | |
435 | for (Int_t i=0; i<nr; i++) { | |
436 | Double_t x=fSectors->GetX(i), ymax=fSectors->GetMaxY(i); | |
c630aafd | 437 | Double_t y=seed.GetYat(x); |
438 | ||
b9de75e1 | 439 | if (y > ymax) { |
440 | s = (s+1) % fN; | |
441 | if (!seed.Rotate(fSectors->GetAlpha())) return 0; | |
442 | } else if (y <-ymax) { | |
443 | s = (s-1+fN) % fN; | |
444 | if (!seed.Rotate(-fSectors->GetAlpha())) return 0; | |
445 | } | |
446 | ||
c630aafd | 447 | if (!seed.PropagateTo(x)) return 0; |
448 | ||
b9de75e1 | 449 | AliTPCcluster *cl=0; |
450 | Int_t index=0; | |
451 | Double_t maxchi2=kMaxCHI2; | |
452 | Double_t pt=seed.GetConvConst()/(100/0.299792458/0.2)/seed.Get1Pt(); | |
453 | Double_t sy2=SigmaY2(seed.GetX(),seed.GetTgl(),pt); | |
454 | Double_t sz2=SigmaZ2(seed.GetX(),seed.GetTgl()); | |
455 | Double_t road=4.*sqrt(seed.GetSigmaY2() + sy2), z=seed.GetZ(); | |
456 | if (road>kMaxROAD) { | |
c630aafd | 457 | Warning("FollowBackProlongation","Too broad road !"); |
b9de75e1 | 458 | return 0; |
459 | } | |
460 | ||
b9de75e1 | 461 | Int_t accepted=seed.GetNumberOfClusters(); |
462 | if (row==i) { | |
463 | //try to accept already found cluster | |
464 | AliTPCcluster *c=(AliTPCcluster*)GetCluster(idx); | |
465 | Double_t chi2; | |
466 | if ((chi2=seed.GetPredictedChi2(c))<maxchi2 || accepted<27) { | |
467 | index=idx; cl=c; maxchi2=chi2; | |
468 | } //else cerr<<"AliTPCtracker::FollowBackProlongation: oulier !\n"; | |
469 | ||
470 | if (nc--) { | |
471 | idx=track.GetClusterIndex(nc); | |
472 | sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16; | |
473 | } | |
c630aafd | 474 | if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; } |
475 | else { if (sec < fkNIS) row=-1; } | |
73042f01 | 476 | |
b9de75e1 | 477 | } |
478 | if (!cl) { | |
479 | //try to fill the gap | |
480 | const AliTPCRow &krow=fSectors[s][i]; | |
481 | if (accepted>27) | |
482 | if (krow) { | |
483 | for (Int_t i=krow.Find(y-road); i<krow; i++) { | |
c630aafd | 484 | AliTPCcluster *c=(AliTPCcluster*)(krow[i]); |
485 | if (c->GetY() > y+road) break; | |
486 | if (c->IsUsed()) continue; | |
487 | if ((c->GetZ()-z)*(c->GetZ()-z)>16.*(seed.GetSigmaZ2()+sz2)) continue; | |
488 | Double_t chi2=seed.GetPredictedChi2(c); | |
489 | if (chi2 > maxchi2) continue; | |
490 | maxchi2=chi2; | |
491 | cl=c; | |
b9de75e1 | 492 | index=krow.GetIndex(i); |
493 | } | |
494 | } | |
495 | } | |
496 | ||
497 | if (cl) { | |
498 | Float_t l=fSectors->GetPadPitchWidth(); | |
024a7fe9 | 499 | Float_t corr=1.; if (i>63) corr=0.67; // new (third) pad response ! |
500 | seed.SetSampledEdx(cl->GetQ()/l*corr,seed.GetNumberOfClusters()); | |
b9de75e1 | 501 | seed.Update(cl,maxchi2,index); |
502 | } | |
503 | ||
504 | } | |
505 | ||
c630aafd | 506 | seed.SetNumber(nc); |
b9de75e1 | 507 | |
508 | return 1; | |
73042f01 | 509 | } |
510 | ||
511 | //_____________________________________________________________________________ | |
b9de75e1 | 512 | void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) { |
73042f01 | 513 | //----------------------------------------------------------------- |
514 | // This function creates track seeds. | |
515 | //----------------------------------------------------------------- | |
516 | Double_t x[5], c[15]; | |
517 | ||
c630aafd | 518 | Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift(); |
73042f01 | 519 | Double_t cs=cos(alpha), sn=sin(alpha); |
520 | ||
c630aafd | 521 | Double_t x1 =fSectors->GetX(i1); |
522 | Double_t xx2=fSectors->GetX(i2); | |
73042f01 | 523 | |
c630aafd | 524 | for (Int_t ns=0; ns<fN; ns++) { |
525 | Int_t nl=fSectors[(ns-1+fN)%fN][i2]; | |
526 | Int_t nm=fSectors[ns][i2]; | |
527 | Int_t nu=fSectors[(ns+1)%fN][i2]; | |
528 | const AliTPCRow& kr1=fSectors[ns][i1]; | |
73042f01 | 529 | for (Int_t is=0; is < kr1; is++) { |
530 | Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ(); | |
531 | for (Int_t js=0; js < nl+nm+nu; js++) { | |
c630aafd | 532 | const AliTPCcluster *kcl; |
73042f01 | 533 | Double_t x2, y2, z2; |
7f6ddf58 | 534 | Double_t x3=GetX(), y3=GetY(), z3=GetZ(); |
73042f01 | 535 | |
c630aafd | 536 | if (js<nl) { |
537 | const AliTPCRow& kr2=fSectors[(ns-1+fN)%fN][i2]; | |
538 | kcl=kr2[js]; | |
73042f01 | 539 | y2=kcl->GetY(); z2=kcl->GetZ(); |
540 | x2= xx2*cs+y2*sn; | |
541 | y2=-xx2*sn+y2*cs; | |
c630aafd | 542 | } else |
543 | if (js<nl+nm) { | |
544 | const AliTPCRow& kr2=fSectors[ns][i2]; | |
545 | kcl=kr2[js-nl]; | |
73042f01 | 546 | x2=xx2; y2=kcl->GetY(); z2=kcl->GetZ(); |
c630aafd | 547 | } else { |
548 | const AliTPCRow& kr2=fSectors[(ns+1)%fN][i2]; | |
549 | kcl=kr2[js-nl-nm]; | |
73042f01 | 550 | y2=kcl->GetY(); z2=kcl->GetZ(); |
551 | x2=xx2*cs-y2*sn; | |
552 | y2=xx2*sn+y2*cs; | |
c630aafd | 553 | } |
73042f01 | 554 | |
7f6ddf58 | 555 | Double_t zz=z1 - (z1-z3)/(x1-x3)*(x1-x2); |
73042f01 | 556 | if (TMath::Abs(zz-z2)>5.) continue; |
557 | ||
558 | Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1); | |
c630aafd | 559 | if (d==0.) { |
560 | Warning("MakeSeeds","Straight seed !"); | |
561 | continue; | |
562 | } | |
563 | x[0]=y1; | |
564 | x[1]=z1; | |
565 | x[4]=f1(x1,y1,x2,y2,x3,y3); | |
566 | if (TMath::Abs(x[4]) >= 0.0066) continue; | |
567 | x[2]=f2(x1,y1,x2,y2,x3,y3); | |
568 | //if (TMath::Abs(x[4]*x1-x[2]) >= 0.99999) continue; | |
569 | x[3]=f3(x1,y1,x2,y2,z1,z2); | |
570 | if (TMath::Abs(x[3]) > 1.2) continue; | |
571 | Double_t a=asin(x[2]); | |
572 | Double_t zv=z1 - x[3]/x[4]*(a+asin(x[4]*x1-x[2])); | |
573 | if (TMath::Abs(zv-z3)>10.) continue; | |
73042f01 | 574 | |
575 | Double_t sy1=kr1[is]->GetSigmaY2(), sz1=kr1[is]->GetSigmaZ2(); | |
576 | Double_t sy2=kcl->GetSigmaY2(), sz2=kcl->GetSigmaZ2(); | |
024a7fe9 | 577 | //Double_t sy3=400*3./12., sy=0.1, sz=0.1; |
578 | Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1; | |
73042f01 | 579 | |
c630aafd | 580 | Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy; |
581 | Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy; | |
582 | Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy; | |
583 | Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy; | |
584 | Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy; | |
585 | Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy; | |
586 | Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy; | |
587 | Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz; | |
588 | Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy; | |
589 | Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz; | |
73042f01 | 590 | |
591 | c[0]=sy1; | |
592 | c[1]=0.; c[2]=sz1; | |
b9de75e1 | 593 | c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23; |
594 | c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22; | |
595 | c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34; | |
596 | c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23; | |
597 | c[13]=f30*sy1*f40+f32*sy2*f42; | |
598 | c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43; | |
73042f01 | 599 | |
600 | UInt_t index=kr1.GetIndex(is); | |
c630aafd | 601 | AliTPCseed *track=new AliTPCseed(index, x, c, x1, ns*alpha+shift); |
602 | Float_t l=fSectors->GetPadPitchWidth(); | |
73042f01 | 603 | track->SetSampledEdx(kr1[is]->GetQ()/l,0); |
604 | ||
b9de75e1 | 605 | Int_t rc=FollowProlongation(*track, i2); |
be9c5115 | 606 | if (rc==0 || track->GetNumberOfClusters()<(i1-i2)/2) delete track; |
c630aafd | 607 | else fSeeds->AddLast(track); |
73042f01 | 608 | } |
609 | } | |
610 | } | |
611 | } | |
612 | ||
613 | //_____________________________________________________________________________ | |
b9de75e1 | 614 | Int_t AliTPCtracker::ReadSeeds(const TFile *inp) { |
73042f01 | 615 | //----------------------------------------------------------------- |
b9de75e1 | 616 | // This function reades track seeds. |
73042f01 | 617 | //----------------------------------------------------------------- |
618 | TDirectory *savedir=gDirectory; | |
619 | ||
b9de75e1 | 620 | TFile *in=(TFile*)inp; |
621 | if (!in->IsOpen()) { | |
c630aafd | 622 | Error("ReadSeeds","Input file has not been open !"); |
be5b9287 | 623 | return 1; |
73042f01 | 624 | } |
625 | ||
b9de75e1 | 626 | in->cd(); |
627 | TTree *seedTree=(TTree*)in->Get("Seeds"); | |
628 | if (!seedTree) { | |
c630aafd | 629 | Error("ReadSeeds","Can't get a tree with track seeds !"); |
b9de75e1 | 630 | return 2; |
631 | } | |
632 | AliTPCtrack *seed=new AliTPCtrack; | |
633 | seedTree->SetBranchAddress("tracks",&seed); | |
634 | ||
635 | if (fSeeds==0) fSeeds=new TObjArray(15000); | |
73042f01 | 636 | |
b9de75e1 | 637 | Int_t n=(Int_t)seedTree->GetEntries(); |
638 | for (Int_t i=0; i<n; i++) { | |
639 | seedTree->GetEvent(i); | |
640 | fSeeds->AddLast(new AliTPCseed(*seed,seed->GetAlpha())); | |
641 | } | |
642 | ||
643 | delete seed; | |
f38c8ae5 | 644 | |
645 | delete seedTree; //Thanks to Mariana Bondila | |
646 | ||
b9de75e1 | 647 | savedir->cd(); |
73042f01 | 648 | |
b9de75e1 | 649 | return 0; |
650 | } | |
73042f01 | 651 | |
cab3f0a3 | 652 | //_____________________________________________________________________________ |
c630aafd | 653 | Int_t AliTPCtracker::Clusters2Tracks(AliESD *event) { |
b9de75e1 | 654 | //----------------------------------------------------------------- |
655 | // This is a track finder. | |
c630aafd | 656 | // The clusters must be already loaded ! |
b9de75e1 | 657 | //----------------------------------------------------------------- |
b9de75e1 | 658 | |
73042f01 | 659 | //find track seeds |
b9de75e1 | 660 | Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows(); |
73042f01 | 661 | Int_t nrows=nlow+nup; |
b9de75e1 | 662 | if (fSeeds==0) { |
663 | Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap); | |
c630aafd | 664 | fSectors=fOuterSec; fN=fkNOS; |
665 | fSeeds=new TObjArray(15000); | |
b9de75e1 | 666 | MakeSeeds(nup-1, nup-1-gap); |
667 | MakeSeeds(nup-1-shift, nup-1-shift-gap); | |
c630aafd | 668 | } |
b9de75e1 | 669 | fSeeds->Sort(); |
73042f01 | 670 | |
b9de75e1 | 671 | Int_t nseed=fSeeds->GetEntriesFast(); |
c630aafd | 672 | for (Int_t i=0; i<nseed; i++) { |
673 | //tracking in the outer sectors | |
674 | fSectors=fOuterSec; fN=fkNOS; | |
675 | ||
b9de75e1 | 676 | AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt; |
c630aafd | 677 | if (!FollowProlongation(t)) { |
678 | delete fSeeds->RemoveAt(i); | |
73042f01 | 679 | continue; |
680 | } | |
c630aafd | 681 | |
682 | //tracking in the inner sectors | |
683 | fSectors=fInnerSec; fN=fkNIS; | |
684 | ||
685 | Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift(); | |
686 | if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi(); | |
687 | if (alpha < 0. ) alpha += 2.*TMath::Pi(); | |
688 | Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS; | |
689 | ||
690 | alpha=ns*fInnerSec->GetAlpha()+fInnerSec->GetAlphaShift()-t.GetAlpha(); | |
691 | ||
692 | if (t.Rotate(alpha)) { | |
693 | if (FollowProlongation(t)) { | |
694 | if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) { | |
695 | t.CookdEdx(); | |
696 | CookLabel(pt,0.1); //For comparison only | |
697 | pt->PropagateTo(fParam->GetInnerRadiusLow()); | |
698 | AliESDtrack iotrack; | |
699 | iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin); | |
700 | ||
701 | event->AddTrack(&iotrack); | |
702 | ||
703 | UseClusters(&t); | |
704 | } | |
705 | } | |
706 | } | |
88cb7938 | 707 | delete fSeeds->RemoveAt(i); |
c630aafd | 708 | } |
709 | ||
710 | Info("Clusters2Tracks","Number of found tracks : %d", | |
711 | event->GetNumberOfTracks()); | |
712 | ||
713 | fSeeds->Clear(); delete fSeeds; fSeeds=0; | |
714 | ||
715 | return 0; | |
716 | } | |
717 | ||
c630aafd | 718 | //_____________________________________________________________________________ |
719 | Int_t AliTPCtracker::RefitInward(AliESD* event) { | |
720 | // | |
721 | // The function propagates tracks throught TPC inward | |
722 | // using already associated clusters. | |
723 | // The clusters must be already loaded ! | |
724 | // | |
725 | ||
726 | Int_t nTracks = event->GetNumberOfTracks(); | |
727 | Int_t nRefited = 0; | |
728 | ||
729 | for (Int_t i = 0; i < nTracks; i++) { | |
730 | AliESDtrack* track = event->GetTrack(i); | |
731 | ULong_t status = track->GetStatus(); | |
732 | ||
4ec88b9c | 733 | if ( (status & AliESDtrack::kTPCrefit) != 0 ) continue; |
c630aafd | 734 | if ( (status & AliESDtrack::kTPCout ) == 0 ) continue; |
4ec88b9c | 735 | |
736 | if ( (status & AliESDtrack::kTRDout ) != 0 ) | |
737 | if ( (status & AliESDtrack::kTRDrefit ) == 0 ) continue; | |
738 | ||
c630aafd | 739 | AliTPCtrack* tpcTrack = new AliTPCtrack(*track); |
740 | AliTPCseed* seed = new AliTPCseed(*tpcTrack, tpcTrack->GetAlpha()); | |
08dba16b | 741 | |
4ec88b9c | 742 | if ( (status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(); |
743 | ||
c630aafd | 744 | fSectors = fOuterSec; |
745 | ||
746 | Int_t res = FollowRefitInward(seed, tpcTrack); | |
747 | UseClusters(seed); | |
748 | Int_t nc = seed->GetNumberOfClusters(); | |
749 | ||
750 | fSectors = fInnerSec; | |
751 | ||
752 | res = FollowRefitInward(seed, tpcTrack); | |
753 | UseClusters(seed, nc); | |
754 | ||
755 | if (res) { | |
756 | seed->PropagateTo(fParam->GetInnerRadiusLow()); | |
757 | seed->SetLabel(tpcTrack->GetLabel()); | |
758 | seed->SetdEdx(tpcTrack->GetdEdx()); | |
759 | track->UpdateTrackParams(seed, AliESDtrack::kTPCrefit); | |
760 | nRefited++; | |
761 | } | |
762 | ||
763 | delete seed; | |
764 | delete tpcTrack; | |
765 | } | |
766 | ||
767 | Info("RefitInward","Number of refitted tracks : %d",nRefited); | |
768 | ||
769 | return 0; | |
770 | } | |
771 | ||
c630aafd | 772 | Int_t AliTPCtracker::PropagateBack(AliESD *event) { |
773 | //----------------------------------------------------------------- | |
774 | // This function propagates tracks back through the TPC. | |
775 | // The clusters must be already loaded ! | |
776 | //----------------------------------------------------------------- | |
777 | Int_t nentr=event->GetNumberOfTracks(); | |
778 | Info("PropagateBack", "Number of ESD tracks: %d\n", nentr); | |
779 | ||
780 | Int_t ntrk=0; | |
781 | for (Int_t i=0; i<nentr; i++) { | |
782 | AliESDtrack *esd=event->GetTrack(i); | |
783 | ULong_t status=esd->GetStatus(); | |
784 | ||
785 | if ( (status & AliESDtrack::kTPCin ) == 0 ) continue; | |
786 | if ( (status & AliESDtrack::kTPCout) != 0 ) continue; | |
14718359 | 787 | if ( (status & AliESDtrack::kITSin) != 0 ) |
788 | if ( (status & AliESDtrack::kITSout) == 0 ) continue; | |
c630aafd | 789 | |
790 | const AliTPCtrack t(*esd); | |
791 | AliTPCseed s(t,t.GetAlpha()); | |
792 | ||
793 | if ( (status & AliESDtrack::kITSout) == 0 ) s.ResetCovariance(); | |
794 | ||
795 | s.ResetNWrong(); | |
796 | s.ResetNRotation(); | |
797 | ||
798 | Int_t nc=t.GetNumberOfClusters(); | |
799 | s.SetNumber(nc); //set number of the cluster to start with | |
800 | ||
801 | //inner sectors | |
802 | fSectors=fInnerSec; fN=fkNIS; | |
803 | ||
804 | Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift(); | |
805 | if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi(); | |
806 | if (alpha < 0. ) alpha += 2.*TMath::Pi(); | |
807 | Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN; | |
808 | alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift(); | |
809 | alpha-=s.GetAlpha(); | |
810 | ||
811 | if (!s.Rotate(alpha)) continue; | |
812 | if (!FollowBackProlongation(s,t)) continue; | |
813 | ||
814 | UseClusters(&s); | |
815 | ||
816 | //outer sectors | |
817 | fSectors=fOuterSec; fN=fkNOS; | |
818 | ||
819 | nc=s.GetNumberOfClusters(); | |
820 | ||
821 | alpha=s.GetAlpha() - fSectors->GetAlphaShift(); | |
822 | if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi(); | |
823 | if (alpha < 0. ) alpha += 2.*TMath::Pi(); | |
824 | ns=Int_t(alpha/fSectors->GetAlpha())%fN; | |
825 | ||
826 | alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift(); | |
827 | alpha-=s.GetAlpha(); | |
828 | ||
829 | if (!s.Rotate(alpha)) continue; | |
830 | if (!FollowBackProlongation(s,t)) continue; | |
831 | { | |
832 | Int_t nrows=fOuterSec->GetNRows()+fInnerSec->GetNRows(); | |
833 | if (s.GetNumberOfClusters() < Int_t(0.4*nrows)) continue; | |
834 | } | |
835 | s.PropagateTo(fParam->GetOuterRadiusUp()); | |
836 | s.CookdEdx(); | |
837 | CookLabel(&s,0.1); //For comparison only | |
838 | UseClusters(&s,nc); | |
839 | esd->UpdateTrackParams(&s,AliESDtrack::kTPCout); | |
840 | ntrk++; | |
841 | } | |
842 | Info("PropagateBack","Number of back propagated tracks: %d",ntrk); | |
08dba16b | 843 | |
844 | return 0; | |
845 | } | |
b9de75e1 | 846 | |
b9de75e1 | 847 | //_________________________________________________________________________ |
848 | AliCluster *AliTPCtracker::GetCluster(Int_t index) const { | |
849 | //-------------------------------------------------------------------- | |
850 | // Return pointer to a given cluster | |
851 | //-------------------------------------------------------------------- | |
852 | Int_t sec=(index&0xff000000)>>24; | |
853 | Int_t row=(index&0x00ff0000)>>16; | |
854 | Int_t ncl=(index&0x0000ffff)>>00; | |
855 | ||
c630aafd | 856 | const AliTPCcluster *cl=0; |
857 | ||
858 | if (sec<fkNIS) { | |
859 | cl=fInnerSec[sec][row].GetUnsortedCluster(ncl); | |
860 | } else { | |
861 | sec-=fkNIS; | |
862 | cl=fOuterSec[sec][row].GetUnsortedCluster(ncl); | |
863 | } | |
864 | ||
865 | return (AliCluster*)cl; | |
b9de75e1 | 866 | } |
867 | ||
868 | //__________________________________________________________________________ | |
869 | void AliTPCtracker::CookLabel(AliKalmanTrack *t, Float_t wrong) const { | |
870 | //-------------------------------------------------------------------- | |
871 | //This function "cooks" a track label. If label<0, this track is fake. | |
872 | //-------------------------------------------------------------------- | |
873 | Int_t noc=t->GetNumberOfClusters(); | |
874 | Int_t *lb=new Int_t[noc]; | |
875 | Int_t *mx=new Int_t[noc]; | |
876 | AliCluster **clusters=new AliCluster*[noc]; | |
877 | ||
878 | Int_t i; | |
879 | for (i=0; i<noc; i++) { | |
880 | lb[i]=mx[i]=0; | |
881 | Int_t index=t->GetClusterIndex(i); | |
882 | clusters[i]=GetCluster(index); | |
883 | } | |
884 | ||
885 | Int_t lab=123456789; | |
886 | for (i=0; i<noc; i++) { | |
887 | AliCluster *c=clusters[i]; | |
888 | lab=TMath::Abs(c->GetLabel(0)); | |
889 | Int_t j; | |
890 | for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break; | |
891 | lb[j]=lab; | |
892 | (mx[j])++; | |
893 | } | |
894 | ||
895 | Int_t max=0; | |
896 | for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];} | |
897 | ||
898 | for (i=0; i<noc; i++) { | |
899 | AliCluster *c=clusters[i]; | |
900 | if (TMath::Abs(c->GetLabel(1)) == lab || | |
901 | TMath::Abs(c->GetLabel(2)) == lab ) max++; | |
902 | } | |
903 | ||
904 | if ((1.- Float_t(max)/noc) > wrong) lab=-lab; | |
905 | ||
906 | else { | |
907 | Int_t tail=Int_t(0.10*noc); | |
908 | max=0; | |
909 | for (i=1; i<=tail; i++) { | |
910 | AliCluster *c=clusters[noc-i]; | |
911 | if (lab == TMath::Abs(c->GetLabel(0)) || | |
912 | lab == TMath::Abs(c->GetLabel(1)) || | |
913 | lab == TMath::Abs(c->GetLabel(2))) max++; | |
914 | } | |
915 | if (max < Int_t(0.5*tail)) lab=-lab; | |
916 | } | |
917 | ||
918 | t->SetLabel(lab); | |
919 | ||
920 | delete[] lb; | |
921 | delete[] mx; | |
922 | delete[] clusters; | |
923 | } | |
924 | ||
925 | //_________________________________________________________________________ | |
926 | void AliTPCtracker::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) { | |
927 | //----------------------------------------------------------------------- | |
928 | // Setup inner sector | |
929 | //----------------------------------------------------------------------- | |
930 | if (f==0) { | |
931 | fAlpha=par->GetInnerAngle(); | |
932 | fAlphaShift=par->GetInnerAngleShift(); | |
933 | fPadPitchWidth=par->GetInnerPadPitchWidth(); | |
024a7fe9 | 934 | f1PadPitchLength=par->GetInnerPadPitchLength(); |
935 | f2PadPitchLength=f1PadPitchLength; | |
b9de75e1 | 936 | |
937 | fN=par->GetNRowLow(); | |
938 | fRow=new AliTPCRow[fN]; | |
939 | for (Int_t i=0; i<fN; i++) fRow[i].SetX(par->GetPadRowRadiiLow(i)); | |
940 | } else { | |
941 | fAlpha=par->GetOuterAngle(); | |
942 | fAlphaShift=par->GetOuterAngleShift(); | |
943 | fPadPitchWidth=par->GetOuterPadPitchWidth(); | |
f03e3423 | 944 | f1PadPitchLength=par->GetOuter1PadPitchLength(); |
945 | f2PadPitchLength=par->GetOuter2PadPitchLength(); | |
b9de75e1 | 946 | |
947 | fN=par->GetNRowUp(); | |
948 | fRow=new AliTPCRow[fN]; | |
f03e3423 | 949 | for (Int_t i=0; i<fN; i++){ |
950 | fRow[i].SetX(par->GetPadRowRadiiUp(i)); | |
951 | } | |
b9de75e1 | 952 | } |
953 | } | |
954 | ||
73042f01 | 955 | //_________________________________________________________________________ |
c630aafd | 956 | void AliTPCtracker:: |
957 | AliTPCRow::InsertCluster(const AliTPCcluster* c, Int_t sec, Int_t row) { | |
73042f01 | 958 | //----------------------------------------------------------------------- |
959 | // Insert a cluster into this pad row in accordence with its y-coordinate | |
960 | //----------------------------------------------------------------------- | |
b9de75e1 | 961 | if (fN==kMaxClusterPerRow) { |
c630aafd | 962 | ::Error("InsertCluster","Too many clusters !"); |
963 | return; | |
964 | } | |
965 | ||
966 | Int_t index=(((sec<<8)+row)<<16)+fN; | |
967 | ||
968 | if (fN==0) { | |
969 | fSize=kMaxClusterPerRow/8; | |
970 | fClusterArray=new AliTPCcluster[fSize]; | |
971 | fIndex[0]=index; | |
972 | fClusterArray[0]=*c; fClusters[fN++]=fClusterArray; | |
973 | return; | |
73042f01 | 974 | } |
c630aafd | 975 | |
976 | if (fN==fSize) { | |
977 | Int_t size=fSize*2; | |
978 | AliTPCcluster *buff=new AliTPCcluster[size]; | |
979 | memcpy(buff,fClusterArray,fSize*sizeof(AliTPCcluster)); | |
980 | for (Int_t i=0; i<fN; i++) | |
981 | fClusters[i]=buff+(fClusters[i]-fClusterArray); | |
982 | delete[] fClusterArray; | |
983 | fClusterArray=buff; | |
984 | fSize=size; | |
985 | } | |
986 | ||
73042f01 | 987 | Int_t i=Find(c->GetY()); |
988 | memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCcluster*)); | |
989 | memmove(fIndex +i+1 ,fIndex +i,(fN-i)*sizeof(UInt_t)); | |
c630aafd | 990 | fIndex[i]=index; |
991 | fClusters[i]=fClusterArray+fN; fClusterArray[fN++]=*c; | |
73042f01 | 992 | } |
993 | ||
994 | //___________________________________________________________________ | |
995 | Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const { | |
996 | //----------------------------------------------------------------------- | |
997 | // Return the index of the nearest cluster | |
998 | //----------------------------------------------------------------------- | |
11c7b548 | 999 | if(fN<=0) return 0; |
73042f01 | 1000 | if (y <= fClusters[0]->GetY()) return 0; |
1001 | if (y > fClusters[fN-1]->GetY()) return fN; | |
1002 | Int_t b=0, e=fN-1, m=(b+e)/2; | |
1003 | for (; b<e; m=(b+e)/2) { | |
1004 | if (y > fClusters[m]->GetY()) b=m+1; | |
1005 | else e=m; | |
1006 | } | |
1007 | return m; | |
1008 | } | |
1009 | ||
1010 | //_____________________________________________________________________________ | |
1011 | void AliTPCtracker::AliTPCseed::CookdEdx(Double_t low, Double_t up) { | |
1012 | //----------------------------------------------------------------- | |
1013 | // This funtion calculates dE/dX within the "low" and "up" cuts. | |
1014 | //----------------------------------------------------------------- | |
1015 | Int_t i; | |
be9c5115 | 1016 | Int_t nc=GetNumberOfClusters(); |
c630aafd | 1017 | |
1018 | Int_t swap;//stupid sorting | |
1019 | do { | |
1020 | swap=0; | |
1021 | for (i=0; i<nc-1; i++) { | |
1022 | if (fdEdxSample[i]<=fdEdxSample[i+1]) continue; | |
1023 | Float_t tmp=fdEdxSample[i]; | |
1024 | fdEdxSample[i]=fdEdxSample[i+1]; fdEdxSample[i+1]=tmp; | |
1025 | swap++; | |
1026 | } | |
1027 | } while (swap); | |
73042f01 | 1028 | |
be9c5115 | 1029 | Int_t nl=Int_t(low*nc), nu=Int_t(up*nc); |
73042f01 | 1030 | Float_t dedx=0; |
c630aafd | 1031 | for (i=nl; i<=nu; i++) dedx += fdEdxSample[i]; |
73042f01 | 1032 | dedx /= (nu-nl+1); |
1033 | SetdEdx(dedx); | |
7f6ddf58 | 1034 | |
14718359 | 1035 | return; |
73042f01 | 1036 | } |
1037 | ||
73042f01 | 1038 | |
1039 |