]>
Commit | Line | Data |
---|---|---|
46d29e70 | 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 | * * | |
69dee759 | 7 | * Permission to use, copy, modify and distribute this software and its * |
46d29e70 | 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$ */ |
46d29e70 | 17 | |
e1e6896f | 18 | #include <TVector2.h> |
46d29e70 | 19 | |
6c94f330 | 20 | #include "AliTracker.h" |
53c17fbf | 21 | #include "AliESDtrack.h" |
fe33d239 | 22 | |
46d29e70 | 23 | #include "AliTRDgeometry.h" |
24 | #include "AliTRDcluster.h" | |
25 | #include "AliTRDtrack.h" | |
43bfc8af | 26 | #include "AliTRDcalibDB.h" |
720a0a16 | 27 | #include "Cal/AliTRDCalPID.h" |
43bfc8af | 28 | |
46d29e70 | 29 | ClassImp(AliTRDtrack) |
30 | ||
53c17fbf | 31 | /////////////////////////////////////////////////////////////////////////////// |
32 | // // | |
33 | // Represents a reconstructed TRD track // | |
34 | // Local TRD Kalman track // | |
35 | // // | |
36 | /////////////////////////////////////////////////////////////////////////////// | |
7ad19338 | 37 | |
fe33d239 | 38 | //_____________________________________________________________________________ |
39 | AliTRDtrack::AliTRDtrack() | |
40 | :AliKalmanTrack() | |
41 | ,fSeedLab(-1) | |
42 | ,fdEdx(0) | |
43 | ,fDE(0) | |
0906e73e | 44 | ,fPIDquality(0) |
79143cbf | 45 | ,fClusterOwner(kFALSE) |
69dee759 | 46 | ,fPIDmethod(kLQ) |
fe33d239 | 47 | ,fStopped(kFALSE) |
48 | ,fLhElectron(0) | |
49 | ,fNWrong(0) | |
50 | ,fNRotate(0) | |
51 | ,fNCross(0) | |
52 | ,fNExpected(0) | |
53 | ,fNLast(0) | |
54 | ,fNExpectedLast(0) | |
55 | ,fNdedx(0) | |
56 | ,fChi2Last(1e10) | |
57 | ,fBackupTrack(0x0) | |
f146da82 | 58 | { |
fe33d239 | 59 | // |
60 | // AliTRDtrack default constructor | |
61 | // | |
62 | ||
63 | for (Int_t i = 0; i < kNplane; i++) { | |
64 | for (Int_t j = 0; j < kNslice; j++) { | |
65 | fdEdxPlane[i][j] = 0.0; | |
6d45eaef | 66 | } |
f146da82 | 67 | fTimBinPlane[i] = -1; |
af26ce80 | 68 | fMom[i] = -1.; |
69 | fSnp[i] = 0.; | |
70 | fTgl[i] = 0.; | |
d97e95e4 | 71 | fTrackletIndex[i] = -1; |
72 | } | |
73 | for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) { | |
74 | fPID[ispec] = 1.0 / AliPID::kSPECIES; | |
af26ce80 | 75 | } |
fe33d239 | 76 | |
77 | for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) { | |
78 | fIndex[i] = 0; | |
6c94f330 | 79 | fIndexBackup[i] = 0; |
fe33d239 | 80 | fdQdl[i] = 0; |
af26ce80 | 81 | fClusters[i] = 0x0; |
82 | } | |
fe33d239 | 83 | |
84 | for (Int_t i = 0; i < 3; i++) { | |
85 | fBudget[i] = 0; | |
f146da82 | 86 | } |
fe33d239 | 87 | |
f146da82 | 88 | } |
6d45eaef | 89 | |
46d29e70 | 90 | //_____________________________________________________________________________ |
43bfc8af | 91 | AliTRDtrack::AliTRDtrack(AliTRDcluster *c, Int_t index |
fe33d239 | 92 | , const Double_t p[5], const Double_t cov[15] |
93 | , Double_t x, Double_t alpha) | |
94 | :AliKalmanTrack() | |
95 | ,fSeedLab(-1) | |
96 | ,fdEdx(0) | |
97 | ,fDE(0) | |
0906e73e | 98 | ,fPIDquality(0) |
79143cbf | 99 | ,fClusterOwner(kFALSE) |
69dee759 | 100 | ,fPIDmethod(kLQ) |
fe33d239 | 101 | ,fStopped(kFALSE) |
102 | ,fLhElectron(0) | |
103 | ,fNWrong(0) | |
104 | ,fNRotate(0) | |
105 | ,fNCross(0) | |
106 | ,fNExpected(0) | |
107 | ,fNLast(0) | |
108 | ,fNExpectedLast(0) | |
109 | ,fNdedx(0) | |
110 | ,fChi2Last(1e10) | |
43bfc8af | 111 | ,fBackupTrack(0x0) |
15ed8ba1 | 112 | { |
fe33d239 | 113 | // |
114 | // The main AliTRDtrack constructor. | |
115 | // | |
116 | ||
af26ce80 | 117 | Double_t cnv = 1.0 / (GetBz() * kB2C); |
fe33d239 | 118 | |
119 | Double_t pp[5] = { p[0] | |
120 | , p[1] | |
121 | , x*p[4] - p[2] | |
122 | , p[3] | |
123 | , p[4]*cnv }; | |
6c94f330 | 124 | |
af26ce80 | 125 | Double_t c22 = x*x*cov[14] - 2*x*cov[12] + cov[ 5]; |
126 | Double_t c32 = x*cov[13] - cov[ 8]; | |
127 | Double_t c20 = x*cov[10] - cov[ 3]; | |
128 | Double_t c21 = x*cov[11] - cov[ 4]; | |
129 | Double_t c42 = x*cov[14] - cov[12]; | |
6c94f330 | 130 | |
af26ce80 | 131 | Double_t cc[15] = { cov[ 0] |
132 | , cov[ 1], cov[ 2] | |
fe33d239 | 133 | , c20, c21, c22 |
af26ce80 | 134 | , cov[ 6], cov[ 7], c32, cov[ 9] |
fe33d239 | 135 | , cov[10]*cnv, cov[11]*cnv, c42*cnv, cov[13]*cnv, cov[14]*cnv*cnv }; |
6c94f330 | 136 | |
137 | Set(x,alpha,pp,cc); | |
5443e65e | 138 | SetNumberOfClusters(1); |
af26ce80 | 139 | fIndex[0] = index; |
140 | fClusters[0] = c; | |
5443e65e | 141 | |
fe33d239 | 142 | for (Int_t i = 0; i < kNplane; i++) { |
143 | for (Int_t j = 0; j < kNslice; j++) { | |
144 | fdEdxPlane[i][j] = 0.0; | |
6d45eaef | 145 | } |
146 | fTimBinPlane[i] = -1; | |
af26ce80 | 147 | fMom[i] = -1.; |
148 | fSnp[i] = 0.; | |
149 | fTgl[i] = 0.; | |
d97e95e4 | 150 | fTrackletIndex[i] = -1; |
151 | } | |
152 | for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) { | |
153 | fPID[ispec] = 1.0 / AliPID::kSPECIES; | |
eab5961e | 154 | } |
a2b90f83 | 155 | |
5443e65e | 156 | Double_t q = TMath::Abs(c->GetQ()); |
fe33d239 | 157 | Double_t s = GetSnp(); |
158 | Double_t t = GetTgl(); | |
159 | if (s*s < 1) { | |
160 | q *= TMath::Sqrt((1-s*s)/(1+t*t)); | |
161 | } | |
53c17fbf | 162 | |
af26ce80 | 163 | fdQdl[0] = q; |
fe33d239 | 164 | for (UInt_t i = 1; i < kMAXCLUSTERSPERTRACK; i++) { |
165 | fdQdl[i] = 0; | |
166 | fIndex[i] = 0; | |
167 | fIndexBackup[i] = 0; | |
af26ce80 | 168 | fClusters[i] = 0x0; |
15ed8ba1 | 169 | } |
fe33d239 | 170 | |
171 | for (Int_t i = 0; i < 3;i++) { | |
172 | fBudget[i] = 0; | |
173 | } | |
174 | ||
46d29e70 | 175 | } |
176 | ||
177 | //_____________________________________________________________________________ | |
43bfc8af | 178 | AliTRDtrack::AliTRDtrack(const AliTRDtrack &t/*, const Bool_t owner*/) |
fe33d239 | 179 | :AliKalmanTrack(t) |
180 | ,fSeedLab(t.GetSeedLabel()) | |
181 | ,fdEdx(t.fdEdx) | |
182 | ,fDE(t.fDE) | |
0906e73e | 183 | ,fPIDquality(t.fPIDquality) |
79143cbf | 184 | ,fClusterOwner(kTRUE) |
69dee759 | 185 | ,fPIDmethod(t.fPIDmethod) |
fe33d239 | 186 | ,fStopped(t.fStopped) |
187 | ,fLhElectron(0) | |
188 | ,fNWrong(t.fNWrong) | |
189 | ,fNRotate(t.fNRotate) | |
190 | ,fNCross(t.fNCross) | |
191 | ,fNExpected(t.fNExpected) | |
192 | ,fNLast(t.fNLast) | |
193 | ,fNExpectedLast(t.fNExpectedLast) | |
194 | ,fNdedx(t.fNdedx) | |
195 | ,fChi2Last(t.fChi2Last) | |
43bfc8af | 196 | ,fBackupTrack(0x0) |
53c17fbf | 197 | { |
46d29e70 | 198 | // |
199 | // Copy constructor. | |
200 | // | |
fe33d239 | 201 | |
202 | for (Int_t i = 0; i < kNplane; i++) { | |
203 | for (Int_t j = 0; j < kNslice; j++) { | |
6d45eaef | 204 | fdEdxPlane[i][j] = t.fdEdxPlane[i][j]; |
205 | } | |
206 | fTimBinPlane[i] = t.fTimBinPlane[i]; | |
207 | fTracklets[i] = t.fTracklets[i]; | |
af26ce80 | 208 | fMom[i] = t.fMom[i]; |
209 | fSnp[i] = t.fSnp[i]; | |
210 | fTgl[i] = t.fTgl[i]; | |
d97e95e4 | 211 | fTrackletIndex[i] = t.fTrackletIndex[i]; |
eab5961e | 212 | } |
46d29e70 | 213 | |
fe33d239 | 214 | Int_t n = t.GetNumberOfClusters(); |
6c94f330 | 215 | SetNumberOfClusters(n); |
fe33d239 | 216 | |
217 | for (Int_t i = 0; i < n; i++) { | |
218 | fIndex[i] = t.fIndex[i]; | |
219 | fIndexBackup[i] = t.fIndex[i]; | |
220 | fdQdl[i] = t.fdQdl[i]; | |
af26ce80 | 221 | if (fClusterOwner && t.fClusters[i]) { |
222 | fClusters[i] = new AliTRDcluster(*(t.fClusters[i])); | |
223 | } | |
224 | else { | |
225 | fClusters[i] = t.fClusters[i]; | |
226 | } | |
227 | } | |
fe33d239 | 228 | |
229 | for (UInt_t i = n; i < kMAXCLUSTERSPERTRACK; i++) { | |
230 | fdQdl[i] = 0; | |
231 | fIndex[i] = 0; | |
232 | fIndexBackup[i] = 0; | |
af26ce80 | 233 | fClusters[i] = 0x0; |
03b0452e | 234 | } |
15ed8ba1 | 235 | |
fe33d239 | 236 | for (Int_t i = 0; i < 3;i++) { |
237 | fBudget[i] = t.fBudget[i]; | |
15ed8ba1 | 238 | } |
fe33d239 | 239 | |
0906e73e | 240 | for(Int_t ispec = 0; ispec<AliPID::kSPECIES; ispec++) fPID[ispec] = t.fPID[ispec]; |
241 | } | |
5443e65e | 242 | |
243 | //_____________________________________________________________________________ | |
fe33d239 | 244 | AliTRDtrack::AliTRDtrack(const AliKalmanTrack &t, Double_t /*alpha*/) |
245 | :AliKalmanTrack(t) | |
246 | ,fSeedLab(-1) | |
247 | ,fdEdx(t.GetPIDsignal()) | |
248 | ,fDE(0) | |
0906e73e | 249 | ,fPIDquality(0) |
79143cbf | 250 | ,fClusterOwner(kFALSE) |
69dee759 | 251 | ,fPIDmethod(kLQ) |
fe33d239 | 252 | ,fStopped(kFALSE) |
253 | ,fLhElectron(0.0) | |
254 | ,fNWrong(0) | |
255 | ,fNRotate(0) | |
256 | ,fNCross(0) | |
257 | ,fNExpected(0) | |
258 | ,fNLast(0) | |
259 | ,fNExpectedLast(0) | |
260 | ,fNdedx(0) | |
261 | ,fChi2Last(0.0) | |
262 | ,fBackupTrack(0x0) | |
53c17fbf | 263 | { |
5443e65e | 264 | // |
fe33d239 | 265 | // Constructor from AliTPCtrack or AliITStrack |
5443e65e | 266 | // |
267 | ||
6c94f330 | 268 | SetLabel(t.GetLabel()); |
fe33d239 | 269 | SetChi2(0.0); |
6c94f330 | 270 | SetMass(t.GetMass()); |
5443e65e | 271 | SetNumberOfClusters(0); |
272 | ||
fe33d239 | 273 | for (Int_t i = 0; i < kNplane; i++) { |
274 | for (Int_t j = 0; j < kNslice; j++) { | |
6d45eaef | 275 | fdEdxPlane[i][j] = 0.0; |
276 | } | |
eab5961e | 277 | fTimBinPlane[i] = -1; |
af26ce80 | 278 | fMom[i] = -1.; |
279 | fSnp[i] = 0.; | |
280 | fTgl[i] = 0.; | |
d97e95e4 | 281 | fTrackletIndex[i] = -1; |
282 | } | |
283 | for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) { | |
284 | fPID[ispec] = 1.0 / AliPID::kSPECIES; | |
eab5961e | 285 | } |
5443e65e | 286 | |
fe33d239 | 287 | for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) { |
288 | fdQdl[i] = 0; | |
289 | fIndex[i] = 0; | |
290 | fIndexBackup[i] = 0; | |
af26ce80 | 291 | fClusters[i] = 0x0; |
79e94bf8 | 292 | } |
4f1c04d3 | 293 | |
fe33d239 | 294 | for (Int_t i = 0; i < 3; i++) { |
295 | fBudget[i] = 0; | |
296 | } | |
297 | ||
0906e73e | 298 | } |
53c17fbf | 299 | |
79e94bf8 | 300 | //_____________________________________________________________________________ |
fe33d239 | 301 | AliTRDtrack::AliTRDtrack(const AliESDtrack &t) |
302 | :AliKalmanTrack() | |
303 | ,fSeedLab(-1) | |
304 | ,fdEdx(t.GetTRDsignal()) | |
305 | ,fDE(0) | |
0906e73e | 306 | ,fPIDquality(0) |
79143cbf | 307 | ,fClusterOwner(kFALSE) |
69dee759 | 308 | ,fPIDmethod(kLQ) |
fe33d239 | 309 | ,fStopped(kFALSE) |
310 | ,fLhElectron(0) | |
311 | ,fNWrong(0) | |
312 | ,fNRotate(0) | |
313 | ,fNCross(0) | |
314 | ,fNExpected(0) | |
315 | ,fNLast(0) | |
316 | ,fNExpectedLast(0) | |
317 | ,fNdedx(0) | |
318 | ,fChi2Last(1e10) | |
319 | ,fBackupTrack(0x0) | |
53c17fbf | 320 | { |
79e94bf8 | 321 | // |
322 | // Constructor from AliESDtrack | |
323 | // | |
fe33d239 | 324 | |
79e94bf8 | 325 | SetLabel(t.GetLabel()); |
fe33d239 | 326 | SetChi2(0.0); |
79e94bf8 | 327 | SetMass(t.GetMass()); |
1e9bb598 | 328 | SetNumberOfClusters(t.GetTRDclusters(fIndex)); |
15ed8ba1 | 329 | |
46e2d86c | 330 | Int_t ncl = t.GetTRDclusters(fIndexBackup); |
fe33d239 | 331 | for (UInt_t i = ncl; i < kMAXCLUSTERSPERTRACK; i++) { |
332 | fIndexBackup[i] = 0; | |
333 | fIndex[i] = 0; | |
15ed8ba1 | 334 | } |
fe33d239 | 335 | |
336 | for (Int_t i = 0; i < kNplane; i++) { | |
337 | for (Int_t j = 0; j < kNslice; j++) { | |
6d45eaef | 338 | fdEdxPlane[i][j] = t.GetTRDsignals(i,j); |
339 | } | |
eab5961e | 340 | fTimBinPlane[i] = t.GetTRDTimBin(i); |
af26ce80 | 341 | fMom[i] = -1.; |
342 | fSnp[i] = 0.; | |
343 | fTgl[i] = 0.; | |
d97e95e4 | 344 | fTrackletIndex[i] = -1; |
eab5961e | 345 | } |
79e94bf8 | 346 | |
fe33d239 | 347 | const AliExternalTrackParam *par = &t; |
348 | if (t.GetStatus() & AliESDtrack::kTRDbackup) { | |
349 | par = t.GetOuterParam(); | |
350 | if (!par) { | |
351 | AliError("No backup info!"); | |
352 | par = &t; | |
353 | } | |
c5a8e3df | 354 | } |
69dee759 | 355 | Set(par->GetX() |
356 | ,par->GetAlpha() | |
357 | ,par->GetParameter() | |
358 | ,par->GetCovariance()); | |
79e94bf8 | 359 | |
fe33d239 | 360 | for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) { |
43bfc8af | 361 | fdQdl[i] = 0; |
af26ce80 | 362 | fClusters[i] = 0x0; |
363 | } | |
fe33d239 | 364 | |
365 | for (Int_t i = 0; i < 3; i++) { | |
366 | fBudget[i] = 0; | |
367 | } | |
d97e95e4 | 368 | for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) { |
369 | fPID[ispec] = t.GetTRDpid(ispec); | |
370 | } | |
5443e65e | 371 | |
fe33d239 | 372 | if ((t.GetStatus() & AliESDtrack::kTIME) == 0) { |
373 | return; | |
374 | } | |
c630aafd | 375 | |
c630aafd | 376 | StartTimeIntegral(); |
fe33d239 | 377 | Double_t times[10]; |
378 | t.GetIntegratedTimes(times); | |
379 | SetIntegratedTimes(times); | |
c630aafd | 380 | SetIntegratedLength(t.GetIntegratedLength()); |
381 | ||
16d9fbba | 382 | } |
383 | ||
53c17fbf | 384 | //____________________________________________________________________________ |
385 | AliTRDtrack::~AliTRDtrack() | |
3fad3d32 | 386 | { |
387 | // | |
53c17fbf | 388 | // Destructor |
389 | // | |
3fad3d32 | 390 | |
fe33d239 | 391 | if (fBackupTrack) { |
392 | delete fBackupTrack; | |
393 | } | |
43bfc8af | 394 | fBackupTrack = 0x0; |
69dee759 | 395 | |
af26ce80 | 396 | if (fClusterOwner) { |
397 | UInt_t icluster = 0; | |
398 | while ((icluster < kMAXCLUSTERSPERTRACK) && fClusters[icluster]) { | |
399 | delete fClusters[icluster]; | |
400 | fClusters[icluster] = 0x0; | |
401 | icluster++; | |
402 | } | |
43bfc8af | 403 | } |
3fad3d32 | 404 | |
53c17fbf | 405 | } |
406 | ||
53c17fbf | 407 | //____________________________________________________________________________ |
408 | Float_t AliTRDtrack::StatusForTOF() | |
7ad19338 | 409 | { |
53c17fbf | 410 | // |
411 | // Defines the status of the TOF extrapolation | |
412 | // | |
03b0452e | 413 | |
fe33d239 | 414 | // Definition of res ???? |
415 | Float_t res = (0.2 + 0.8 * (fN / (fNExpected + 5.0))) | |
416 | * (0.4 + 0.6 * fTracklets[5].GetN() / 20.0); | |
417 | res *= (0.25 + 0.8 * 40.0 / (40.0 + fBudget[2])); | |
03b0452e | 418 | return res; |
419 | ||
4f1c04d3 | 420 | } |
46d29e70 | 421 | |
422 | //_____________________________________________________________________________ | |
53c17fbf | 423 | Int_t AliTRDtrack::Compare(const TObject *o) const |
424 | { | |
425 | // | |
426 | // Compares tracks according to their Y2 or curvature | |
427 | // | |
46d29e70 | 428 | |
d49e463b | 429 | AliTRDtrack *t = (AliTRDtrack *) o; |
46d29e70 | 430 | |
d49e463b | 431 | Double_t co = TMath::Abs(t->GetC()); |
432 | Double_t c = TMath::Abs(GetC()); | |
46d29e70 | 433 | |
d49e463b | 434 | if (c > co) { |
435 | return 1; | |
436 | } | |
437 | else if (c < co) { | |
438 | return -1; | |
439 | } | |
69dee759 | 440 | |
46d29e70 | 441 | return 0; |
53c17fbf | 442 | |
46d29e70 | 443 | } |
444 | ||
a819a5f7 | 445 | //_____________________________________________________________________________ |
43bfc8af | 446 | void AliTRDtrack::CookdEdx(Double_t low, Double_t up) |
15ed8ba1 | 447 | { |
448 | // | |
d49e463b | 449 | // Calculates the truncated dE/dx within the "low" and "up" cuts. |
15ed8ba1 | 450 | // |
451 | ||
d49e463b | 452 | // Array to sort the dEdx values according to amplitude |
af26ce80 | 453 | Float_t sorted[kMAXCLUSTERSPERTRACK]; |
69dee759 | 454 | fdEdx = 0.0; |
43bfc8af | 455 | |
15ed8ba1 | 456 | // Require at least 10 clusters for a dedx measurement |
69dee759 | 457 | if (fNdedx < 10) { |
458 | return; | |
459 | } | |
15ed8ba1 | 460 | |
d49e463b | 461 | // Can fdQdl be negative ???? |
af26ce80 | 462 | for (Int_t i = 0; i < fNdedx; i++) { |
463 | sorted[i] = TMath::Abs(fdQdl[i]); | |
464 | } | |
15ed8ba1 | 465 | // Sort the dedx values by amplitude |
c6011b06 | 466 | Int_t *index = new Int_t[fNdedx]; |
467 | TMath::Sort(fNdedx, sorted, index, kFALSE); | |
468 | ||
43bfc8af | 469 | // Sum up the truncated charge between lower and upper bounds |
c6011b06 | 470 | Int_t nl = Int_t(low * fNdedx); |
471 | Int_t nu = Int_t( up * fNdedx); | |
af26ce80 | 472 | for (Int_t i = nl; i <= nu; i++) { |
473 | fdEdx += sorted[index[i]]; | |
474 | } | |
475 | fdEdx /= (nu - nl + 1.0); | |
476 | ||
477 | delete[] index; | |
43bfc8af | 478 | |
43bfc8af | 479 | } |
480 | ||
481 | //_____________________________________________________________________________ | |
44dbae42 | 482 | void AliTRDtrack::CookdEdxTimBin(const Int_t/* tid*/) |
43bfc8af | 483 | { |
484 | // | |
485 | // Set fdEdxPlane and fTimBinPlane and also get the | |
486 | // Time bin for Max. Cluster | |
af26ce80 | 487 | // |
488 | // Authors: | |
43bfc8af | 489 | // Prashant Shukla (shukla@physi.uni-heidelberg.de) |
490 | // Alexandru Bercuci (A.Bercuci@gsi.de) | |
af26ce80 | 491 | // |
43bfc8af | 492 | |
69dee759 | 493 | // Max charge in chamber |
494 | Double_t maxcharge[AliESDtrack::kNPlane]; | |
af26ce80 | 495 | // Number of clusters attached to track per chamber and slice |
496 | Int_t nCluster[AliESDtrack::kNPlane][AliESDtrack::kNSlice]; | |
497 | // Number of time bins in chamber | |
498 | Int_t ntb = AliTRDcalibDB::Instance()->GetNumberOfTimeBins(); | |
499 | Int_t plane; // Plane of current cluster | |
500 | Int_t tb; // Time bin of current cluster | |
501 | Int_t slice; // Current slice | |
502 | AliTRDcluster *cluster = 0x0; // Pointer to current cluster | |
503 | ||
504 | // Reset class and local counters/variables | |
43bfc8af | 505 | for (Int_t iPlane = 0; iPlane < AliESDtrack::kNPlane; iPlane++) { |
af26ce80 | 506 | fTimBinPlane[iPlane] = -1; |
69dee759 | 507 | maxcharge[iPlane] = 0.0; |
af26ce80 | 508 | for (Int_t iSlice = 0; iSlice < AliESDtrack::kNSlice; iSlice++) { |
69dee759 | 509 | fdEdxPlane[iPlane][iSlice] = 0.0; |
43bfc8af | 510 | nCluster[iPlane][iSlice] = 0; |
511 | } | |
15ed8ba1 | 512 | } |
c6011b06 | 513 | |
af26ce80 | 514 | // Start looping over clusters attached to this track |
515 | for (Int_t iClus = 0; iClus < GetNumberOfClusters(); iClus++) { | |
516 | ||
43bfc8af | 517 | cluster = fClusters[iClus]; //(AliTRDcluster*)tracker->GetCluster(fIndex[iClus]); |
69dee759 | 518 | if (!cluster) continue; |
43bfc8af | 519 | |
af26ce80 | 520 | // Read info from current cluster |
521 | plane = AliTRDgeometry::GetPlane(cluster->GetDetector()); | |
43bfc8af | 522 | if (plane < 0 || plane >= AliESDtrack::kNPlane) { |
523 | AliError(Form("Wrong plane %d", plane)); | |
524 | continue; | |
525 | } | |
526 | ||
af26ce80 | 527 | tb = cluster->GetLocalTimeBin(); |
e4f2f73d | 528 | if ((tb < 0) || (tb >= ntb)) { |
529 | AliWarning(Form("time bin < 0 or > %d in cluster %d", ntb, iClus)); | |
af26ce80 | 530 | AliInfo(Form("dQ/dl %f", fdQdl[iClus])); |
531 | continue; | |
532 | } | |
43bfc8af | 533 | |
af26ce80 | 534 | slice = tb * AliESDtrack::kNSlice / ntb; |
535 | ||
536 | fdEdxPlane[plane][slice] += fdQdl[iClus]; | |
537 | if (fdQdl[iClus] > maxcharge[plane]) { | |
538 | maxcharge[plane] = fdQdl[iClus]; | |
43bfc8af | 539 | fTimBinPlane[plane] = tb; |
540 | } | |
43bfc8af | 541 | |
af26ce80 | 542 | nCluster[plane][slice]++; |
43bfc8af | 543 | |
af26ce80 | 544 | } // End of loop over cluster |
43bfc8af | 545 | |
546 | // Normalize fdEdxPlane to number of clusters and set track segments | |
547 | for (Int_t iPlane = 0; iPlane < AliESDtrack::kNPlane; iPlane++) { | |
548 | for (Int_t iSlice = 0; iSlice < AliESDtrack::kNSlice; iSlice++) { | |
af26ce80 | 549 | if (nCluster[iPlane][iSlice]) { |
550 | fdEdxPlane[iPlane][iSlice] /= nCluster[iPlane][iSlice]; | |
551 | } | |
43bfc8af | 552 | } |
af26ce80 | 553 | } |
43bfc8af | 554 | |
af26ce80 | 555 | } |
43bfc8af | 556 | |
44dbae42 | 557 | //_____________________________________________________________________________ |
69dee759 | 558 | void AliTRDtrack::CookdEdxNN(Float_t *dedx) |
559 | { | |
560 | // | |
44dbae42 | 561 | // This function calcuates the input for the neural networks |
562 | // which are used for the PID. | |
69dee759 | 563 | // |
564 | ||
565 | //number of time bins in chamber | |
566 | Int_t ntb = AliTRDcalibDB::Instance()->GetNumberOfTimeBins(); | |
567 | ||
568 | Int_t plane; // plane of current cluster | |
569 | Int_t tb; // time bin of current cluster | |
570 | Int_t slice; // curent slice | |
571 | AliTRDcluster *cluster = 0x0; // pointer to current cluster | |
572 | const Int_t kMLPscale = 16000; // scaling of the MLP input to be smaller than 1 | |
573 | ||
574 | // Reset class and local contors/variables | |
575 | for (Int_t iPlane = 0; iPlane < AliESDtrack::kNPlane; iPlane++){ | |
576 | for (Int_t iSlice = 0; iSlice < kNMLPslice; iSlice++) { | |
577 | *(dedx + (kNMLPslice * iPlane) + iSlice) = 0.0; | |
578 | } | |
579 | } | |
580 | ||
581 | // Start looping over clusters attached to this track | |
582 | for (Int_t iClus = 0; iClus < GetNumberOfClusters(); iClus++) { | |
44dbae42 | 583 | |
69dee759 | 584 | cluster = fClusters[iClus]; //(AliTRDcluster*)tracker->GetCluster(fIndex[iClus]); |
585 | if (!cluster) { | |
586 | continue; | |
587 | } | |
44dbae42 | 588 | |
69dee759 | 589 | // Read info from current cluster |
590 | plane = AliTRDgeometry::GetPlane(cluster->GetDetector()); | |
591 | if (plane < 0 || plane >= AliESDtrack::kNPlane) { | |
592 | AliError(Form("Wrong plane %d",plane)); | |
593 | continue; | |
594 | } | |
595 | ||
596 | tb = cluster->GetLocalTimeBin(); | |
597 | if (tb == 0 || tb >= ntb) { | |
598 | AliWarning(Form("time bin 0 or > %d in cluster %d",ntb,iClus)); | |
599 | AliInfo(Form("dQ/dl %f",fdQdl[iClus])); | |
600 | continue; | |
601 | } | |
602 | ||
603 | slice = tb * kNMLPslice / ntb; | |
44dbae42 | 604 | |
69dee759 | 605 | *(dedx+(kNMLPslice * plane) + slice) += fdQdl[iClus]/kMLPscale; |
606 | ||
607 | } // End of loop over cluster | |
44dbae42 | 608 | |
69dee759 | 609 | } |
44dbae42 | 610 | |
43bfc8af | 611 | //_____________________________________________________________________________ |
69dee759 | 612 | void AliTRDtrack::SetTrackSegmentDirMom(const Int_t plane) |
43bfc8af | 613 | { |
af26ce80 | 614 | // |
615 | // Set the momenta for a track segment in a given plane | |
616 | // | |
617 | ||
618 | if ((plane < 0) || | |
619 | (plane>= kNplane)) { | |
620 | AliError(Form("Trying to access out of range plane (%d)", plane)); | |
621 | return; | |
622 | } | |
43bfc8af | 623 | |
af26ce80 | 624 | fSnp[plane] = GetSnp(); |
625 | fTgl[plane] = GetTgl(); | |
626 | Double_t p[3]; | |
627 | GetPxPyPz(p); | |
628 | fMom[plane] = TMath::Sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]); | |
629 | ||
43bfc8af | 630 | } |
631 | ||
632 | //_____________________________________________________________________________ | |
633 | Float_t AliTRDtrack::GetTrackLengthPlane(Int_t plane) const | |
634 | { | |
af26ce80 | 635 | // |
636 | // Calculate the track length of a track segment in a given plane | |
637 | // | |
43bfc8af | 638 | |
69dee759 | 639 | if ((plane < 0) || |
640 | (plane >= kNplane)) { | |
641 | return 0.0; | |
642 | } | |
43bfc8af | 643 | |
af26ce80 | 644 | return (AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick()) |
645 | / TMath::Sqrt((1.0 - fSnp[plane]*fSnp[plane]) | |
646 | / (1.0 + fTgl[plane]*fTgl[plane])); | |
647 | ||
648 | } | |
43bfc8af | 649 | |
650 | //_____________________________________________________________________________ | |
44dbae42 | 651 | Bool_t AliTRDtrack::CookPID(Int_t &pidQuality) |
43bfc8af | 652 | { |
653 | // | |
654 | // This function calculates the PID probabilities based on TRD signals | |
655 | // | |
656 | // The method produces probabilities based on the charge | |
657 | // and the position of the maximum time bin in each layer. | |
658 | // The dE/dx information can be used as global charge or 2 to 3 | |
720a0a16 | 659 | // slices. Check AliTRDCalPID and AliTRDCalPIDRefMaker for the actual |
43bfc8af | 660 | // implementation. |
661 | // | |
662 | // Author | |
663 | // Alex Bercuci (A.Bercuci@gsi.de) 2nd May 2007 | |
af26ce80 | 664 | // |
43bfc8af | 665 | |
af26ce80 | 666 | AliTRDcalibDB *calibration = AliTRDcalibDB::Instance(); |
667 | if (!calibration) { | |
668 | AliError("No access to calibration data"); | |
44dbae42 | 669 | return kFALSE; |
af26ce80 | 670 | } |
43bfc8af | 671 | |
44dbae42 | 672 | // Retrieve the CDB container class with the probability distributions |
673 | const AliTRDCalPID *pd = calibration->GetPIDObject(fPIDmethod == kNN ? 0 : 1); | |
674 | if (!pd) { | |
675 | AliError("No access to AliTRDCalPID"); | |
676 | return kFALSE; | |
677 | } | |
43bfc8af | 678 | |
44dbae42 | 679 | // Calculate the input for the NN if fPIDmethod is kNN |
680 | Float_t ldEdxNN[AliTRDCalPID::kNPlane * kNMLPslice], *dedx = 0x0; | |
681 | if(fPIDmethod == kNN) { | |
682 | CookdEdxNN(&ldEdxNN[0]); | |
683 | } | |
43bfc8af | 684 | |
44dbae42 | 685 | // Sets the a priori probabilities |
686 | for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) { | |
69dee759 | 687 | fPID[ispec] = 1.0 / AliPID::kSPECIES; |
44dbae42 | 688 | } |
43bfc8af | 689 | |
44dbae42 | 690 | if(AliPID::kSPECIES != 5){ |
691 | AliError("Probabilities array defined only for 5 values. Please modify !!"); | |
692 | return kFALSE; | |
693 | } | |
43bfc8af | 694 | |
44dbae42 | 695 | pidQuality = 0; |
696 | Float_t length; // track segment length in chamber | |
43bfc8af | 697 | |
44dbae42 | 698 | // Skip tracks which have no TRD signal at all |
699 | if (fdEdx == 0.) return kFALSE; | |
700 | ||
701 | for (Int_t iPlane = 0; iPlane < AliTRDgeometry::kNplan; iPlane++) { | |
702 | ||
69dee759 | 703 | length = (AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick()) |
704 | / TMath::Sqrt((1.0 - fSnp[iPlane]*fSnp[iPlane]) | |
705 | / (1.0 + fTgl[iPlane]*fTgl[iPlane])); | |
44dbae42 | 706 | |
707 | // check data | |
708 | if((fdEdxPlane[iPlane][0] + fdEdxPlane[iPlane][1] + fdEdxPlane[iPlane][2]) <= 0. | |
709 | || fTimBinPlane[iPlane] == -1.) continue; | |
710 | ||
711 | // this track segment has fulfilled all requierments | |
712 | pidQuality++; | |
713 | ||
714 | // Get the probabilities for the different particle species | |
715 | for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) { | |
716 | switch(fPIDmethod){ | |
717 | case kLQ: | |
718 | dedx = fdEdxPlane[iPlane]; | |
719 | break; | |
720 | case kNN: | |
721 | dedx = &ldEdxNN[iPlane*kNMLPslice]; | |
722 | break; | |
723 | } | |
724 | fPID[iSpecies] *= pd->GetProbability(iSpecies, fMom[iPlane], dedx, length, iPlane); | |
725 | } | |
69dee759 | 726 | |
727 | } | |
728 | ||
729 | if (pidQuality == 0) { | |
730 | return kTRUE; | |
44dbae42 | 731 | } |
43bfc8af | 732 | |
44dbae42 | 733 | // normalize probabilities |
69dee759 | 734 | Double_t probTotal = 0.0; |
735 | for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) { | |
736 | probTotal += fPID[iSpecies]; | |
737 | } | |
43bfc8af | 738 | |
69dee759 | 739 | if (probTotal <= 0.0) { |
740 | AliWarning("The total probability over all species <= 0."); | |
741 | AliWarning("This may be caused by some error in the reference histograms."); | |
44dbae42 | 742 | return kFALSE; |
743 | } | |
69dee759 | 744 | |
745 | for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) { | |
746 | fPID[iSpecies] /= probTotal; | |
747 | } | |
748 | ||
44dbae42 | 749 | return kTRUE; |
43bfc8af | 750 | |
69dee759 | 751 | } |
44dbae42 | 752 | |
46d29e70 | 753 | //_____________________________________________________________________________ |
826fe01c | 754 | Bool_t AliTRDtrack::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho) |
46d29e70 | 755 | { |
fe33d239 | 756 | // |
826fe01c | 757 | // Propagates this track to a reference plane defined by "xk" [cm] |
758 | // correcting for the mean crossed material. | |
fe33d239 | 759 | // |
826fe01c | 760 | // "xx0" - thickness/rad.length [units of the radiation length] |
761 | // "xrho" - thickness*density [g/cm^2] | |
762 | // | |
fe33d239 | 763 | |
764 | if (xk == GetX()) { | |
765 | return kTRUE; | |
766 | } | |
15ed8ba1 | 767 | |
fe33d239 | 768 | Double_t oldX = GetX(); |
769 | Double_t oldY = GetY(); | |
770 | Double_t oldZ = GetZ(); | |
15ed8ba1 | 771 | |
fe33d239 | 772 | Double_t bz = GetBz(); |
46d29e70 | 773 | |
fe33d239 | 774 | if (!AliExternalTrackParam::PropagateTo(xk,bz)) { |
775 | return kFALSE; | |
776 | } | |
9c9d2487 | 777 | |
fe33d239 | 778 | Double_t x = GetX(); |
779 | Double_t y = GetY(); | |
780 | Double_t z = GetZ(); | |
826fe01c | 781 | |
fe33d239 | 782 | if (oldX < xk) { |
826fe01c | 783 | xrho = -xrho; |
fe33d239 | 784 | if (IsStartedTimeIntegral()) { |
69dee759 | 785 | Double_t l2 = TMath::Sqrt((x-oldX)*(x-oldX) |
786 | + (y-oldY)*(y-oldY) | |
787 | + (z-oldZ)*(z-oldZ)); | |
fe33d239 | 788 | Double_t crv = GetC(); |
789 | if (TMath::Abs(l2*crv) > 0.0001) { | |
790 | // Make correction for curvature if neccesary | |
69dee759 | 791 | l2 = 0.5 * TMath::Sqrt((x-oldX)*(x-oldX) |
792 | + (y-oldY)*(y-oldY)); | |
fe33d239 | 793 | l2 = 2.0 * TMath::ASin(l2 * crv) / crv; |
794 | l2 = TMath::Sqrt(l2*l2 + (z-oldZ)*(z-oldZ)); | |
795 | } | |
796 | AddTimeStep(l2); | |
6c94f330 | 797 | } |
46d29e70 | 798 | } |
15ed8ba1 | 799 | |
826fe01c | 800 | if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0,xrho,GetMass())) { |
fe33d239 | 801 | return kFALSE; |
802 | } | |
15ed8ba1 | 803 | |
fe33d239 | 804 | { |
805 | ||
69dee759 | 806 | // Energy losses |
6c23ffed | 807 | Double_t p2 = (1.0 + GetTgl()*GetTgl()) / (GetSigned1Pt()*GetSigned1Pt()); |
fe33d239 | 808 | Double_t beta2 = p2 / (p2 + GetMass()*GetMass()); |
69dee759 | 809 | if ((beta2 < 1.0e-10) || |
810 | ((5940.0 * beta2/(1.0 - beta2 + 1.0e-10) - beta2) < 0.0)) { | |
fe33d239 | 811 | return kFALSE; |
812 | } | |
813 | ||
814 | Double_t dE = 0.153e-3 / beta2 | |
69dee759 | 815 | * (TMath::Log(5940.0 * beta2/(1.0 - beta2 + 1.0e-10)) - beta2) |
826fe01c | 816 | * xrho; |
817 | fBudget[0] += xrho; | |
fe33d239 | 818 | |
819 | /* | |
820 | // Suspicious part - think about it ? | |
821 | Double_t kinE = TMath::Sqrt(p2); | |
822 | if (dE > 0.8*kinE) dE = 0.8 * kinE; // | |
823 | if (dE < 0) dE = 0.0; // Not valid region for Bethe bloch | |
824 | */ | |
825 | ||
826 | fDE += dE; | |
827 | ||
828 | /* | |
829 | // Suspicious ! I.B. | |
830 | Double_t sigmade = 0.07 * TMath::Sqrt(TMath::Abs(dE)); // Energy loss fluctuation | |
831 | Double_t sigmac2 = sigmade*sigmade*fC*fC*(p2+GetMass()*GetMass())/(p2*p2); | |
832 | fCcc += sigmac2; | |
833 | fCee += fX*fX * sigmac2; | |
834 | */ | |
6c94f330 | 835 | |
0d5b5c27 | 836 | } |
837 | ||
6c94f330 | 838 | return kTRUE; |
6d45eaef | 839 | |
46d29e70 | 840 | } |
841 | ||
46d29e70 | 842 | //_____________________________________________________________________________ |
69dee759 | 843 | Bool_t AliTRDtrack::Update(const AliTRDcluster *c, Double_t chisq |
844 | , Int_t index, Double_t h01) | |
46d29e70 | 845 | { |
fe33d239 | 846 | // |
69dee759 | 847 | // Assignes the found cluster <c> to the track and updates |
848 | // track information. | |
849 | // <chisq> : predicted chi2 | |
850 | // <index> : ?? | |
851 | // <h01> : Tilting factor | |
fe33d239 | 852 | // |
46d29e70 | 853 | |
69dee759 | 854 | Double_t p[2] = { c->GetY() |
855 | , c->GetZ() }; | |
fe33d239 | 856 | Double_t sy2 = c->GetSigmaY2() * 4.0; |
857 | Double_t sz2 = c->GetSigmaZ2() * 4.0; | |
69dee759 | 858 | Double_t cov[3] = { sy2 + h01*h01*sz2 |
859 | , h01 * (sy2-sz2) | |
860 | , sz2 + h01*h01*sy2 }; | |
46e2d86c | 861 | |
fe33d239 | 862 | if (!AliExternalTrackParam::Update(p,cov)) { |
863 | return kFALSE; | |
864 | } | |
46d29e70 | 865 | |
af26ce80 | 866 | Int_t n = GetNumberOfClusters(); |
fe33d239 | 867 | fIndex[n] = index; |
b8dc2353 | 868 | SetNumberOfClusters(n+1); |
af26ce80 | 869 | |
b8dc2353 | 870 | SetChi2(GetChi2()+chisq); |
5443e65e | 871 | |
af26ce80 | 872 | return kTRUE; |
fe33d239 | 873 | |
874 | } | |
53c17fbf | 875 | |
46e2d86c | 876 | //_____________________________________________________________________________ |
af26ce80 | 877 | Int_t AliTRDtrack::UpdateMI(AliTRDcluster *c, Double_t chisq, Int_t index |
69dee759 | 878 | , Double_t h01, Int_t /*plane*/, Int_t /*tid*/) |
fe33d239 | 879 | { |
880 | // | |
69dee759 | 881 | // Assignes the found cluster <c> to the track and |
882 | // updates track information | |
883 | // <chisq> : predicted chi2 | |
884 | // <index> : ?? | |
885 | // <h01> : Tilting factor | |
fe33d239 | 886 | // |
69dee759 | 887 | // Difference to Update(AliTRDcluster *c): cluster is added to fClusters |
6c94f330 | 888 | // |
15ed8ba1 | 889 | |
69dee759 | 890 | Double_t p[2] = { c->GetY() |
891 | , c->GetZ() }; | |
fe33d239 | 892 | Double_t sy2 = c->GetSigmaY2() * 4.0; |
893 | Double_t sz2 = c->GetSigmaZ2() * 4.0; | |
69dee759 | 894 | Double_t cov[3] = { sy2 + h01*h01*sz2 |
895 | , h01 * (sy2-sz2) | |
896 | , sz2 + h01*h01*sy2 }; | |
46e2d86c | 897 | |
fe33d239 | 898 | if (!AliExternalTrackParam::Update(p,cov)) { |
899 | return kFALSE; | |
900 | } | |
99910b5a | 901 | |
902 | AliTracker::FillResiduals(this,p,cov,c->GetVolumeId()); | |
fe33d239 | 903 | |
af26ce80 | 904 | // Register cluster to track |
905 | Int_t n = GetNumberOfClusters(); | |
906 | fIndex[n] = index; | |
907 | fClusters[n] = c; | |
46e2d86c | 908 | SetNumberOfClusters(n+1); |
fe33d239 | 909 | SetChi2(GetChi2() + chisq); |
910 | ||
911 | return kTRUE; | |
46e2d86c | 912 | |
53c17fbf | 913 | } |
7ad19338 | 914 | |
69dee759 | 915 | //_____________________________________________________________________________ |
916 | Bool_t AliTRDtrack::Update(const AliTRDtracklet &t, Double_t chisq, Int_t index) | |
917 | { | |
918 | // | |
919 | // Assignes the found tracklet <t> to the track | |
920 | // and updates track information | |
921 | // <chisq> : predicted chi2 | |
922 | // <index> : ?? | |
923 | // | |
7ad19338 | 924 | |
69dee759 | 925 | Double_t h01 = t.GetTilt(); // Is this correct???? |
926 | Double_t p[2] = { t.GetY(), t.GetZ() }; | |
927 | Double_t sy2 = t.GetTrackletSigma2(); // Error pad-column | |
928 | Double_t sz2 = 100000.0; // Error pad-row (????) | |
929 | Double_t cov[3] = { sy2 + h01*h01*sz2 // Does this have any sense???? | |
930 | , h01 * (sy2 - sz2) | |
931 | , sz2 + h01*h01*sy2 }; | |
932 | if (!AliExternalTrackParam::Update(p,cov)) { | |
933 | return kFALSE; | |
934 | } | |
6c94f330 | 935 | |
69dee759 | 936 | Int_t n = GetNumberOfClusters(); |
937 | fIndex[n] = index; | |
938 | SetNumberOfClusters(n+1); | |
939 | SetChi2(GetChi2()+chisq); | |
7ad19338 | 940 | |
69dee759 | 941 | return kTRUE; |
7ad19338 | 942 | |
69dee759 | 943 | } |
c84a5e9e | 944 | |
46d29e70 | 945 | //_____________________________________________________________________________ |
6c94f330 | 946 | Bool_t AliTRDtrack::Rotate(Double_t alpha, Bool_t absolute) |
46d29e70 | 947 | { |
fe33d239 | 948 | // |
6c94f330 | 949 | // Rotates track parameters in R*phi plane |
950 | // if absolute rotation alpha is in global system | |
951 | // otherwise alpha rotation is relative to the current rotation angle | |
fe33d239 | 952 | // |
953 | ||
3fad3d32 | 954 | if (absolute) { |
6c94f330 | 955 | alpha -= GetAlpha(); |
3fad3d32 | 956 | } |
957 | else{ | |
958 | fNRotate++; | |
959 | } | |
46d29e70 | 960 | |
6c94f330 | 961 | return AliExternalTrackParam::Rotate(GetAlpha()+alpha); |
fe33d239 | 962 | |
69dee759 | 963 | } |
7ad19338 | 964 | |
46d29e70 | 965 | //_____________________________________________________________________________ |
fd621f36 | 966 | Double_t AliTRDtrack::GetPredictedChi2(const AliTRDcluster *c, Double_t h01) const |
46d29e70 | 967 | { |
53c17fbf | 968 | // |
969 | // Returns the track chi2 | |
970 | // | |
971 | ||
69dee759 | 972 | Double_t p[2] = { c->GetY() |
973 | , c->GetZ() }; | |
fe33d239 | 974 | Double_t sy2 = c->GetSigmaY2() * 4.0; |
975 | Double_t sz2 = c->GetSigmaZ2() * 4.0; | |
69dee759 | 976 | Double_t cov[3] = { sy2 + h01*h01*sz2 |
977 | , h01*(sy2-sz2) | |
978 | , sz2 + h01*h01*sy2 }; | |
6c94f330 | 979 | |
980 | return AliExternalTrackParam::GetPredictedChi2(p,cov); | |
15ed8ba1 | 981 | |
fe33d239 | 982 | } |
7ad19338 | 983 | |
53c17fbf | 984 | //_____________________________________________________________________________ |
16d9fbba | 985 | void AliTRDtrack::MakeBackupTrack() |
986 | { | |
987 | // | |
53c17fbf | 988 | // Creates a backup track |
16d9fbba | 989 | // |
53c17fbf | 990 | |
fe33d239 | 991 | if (fBackupTrack) { |
992 | delete fBackupTrack; | |
993 | } | |
16d9fbba | 994 | fBackupTrack = new AliTRDtrack(*this); |
4f1c04d3 | 995 | |
996 | } | |
997 | ||
53c17fbf | 998 | //_____________________________________________________________________________ |
999 | Int_t AliTRDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z) | |
1000 | { | |
4f1c04d3 | 1001 | // |
fe33d239 | 1002 | // Find a prolongation at given x |
1003 | // Return 0 if it does not exist | |
1004 | // | |
1005 | ||
1006 | Double_t bz = GetBz(); | |
15ed8ba1 | 1007 | |
fe33d239 | 1008 | if (!AliExternalTrackParam::GetYAt(xk,bz,y)) { |
1009 | return 0; | |
1010 | } | |
1011 | if (!AliExternalTrackParam::GetZAt(xk,bz,z)) { | |
1012 | return 0; | |
1013 | } | |
4f1c04d3 | 1014 | |
6c94f330 | 1015 | return 1; |
fe33d239 | 1016 | |
16d9fbba | 1017 | } |
3fad3d32 | 1018 | |
53c17fbf | 1019 | //_____________________________________________________________________________ |
fe33d239 | 1020 | Int_t AliTRDtrack::PropagateToX(Double_t xr, Double_t step) |
3fad3d32 | 1021 | { |
1022 | // | |
6c94f330 | 1023 | // Propagate track to given x position |
af26ce80 | 1024 | // Works inside of the 20 degree segmentation |
1025 | // (local cooordinate frame for TRD , TPC, TOF) | |
3fad3d32 | 1026 | // |
fe33d239 | 1027 | // Material budget from geo manager |
6c94f330 | 1028 | // |
fe33d239 | 1029 | |
1030 | Double_t xyz0[3]; | |
1031 | Double_t xyz1[3]; | |
1032 | Double_t y; | |
1033 | Double_t z; | |
1034 | ||
1035 | const Double_t kAlphac = TMath::Pi()/9.0; | |
15ed8ba1 | 1036 | const Double_t kTalphac = TMath::Tan(kAlphac*0.5); |
fe33d239 | 1037 | |
1038 | // Critical alpha - cross sector indication | |
af26ce80 | 1039 | Double_t dir = (GetX() > xr) ? -1.0 : 1.0; |
fe33d239 | 1040 | |
1041 | // Direction +- | |
1042 | for (Double_t x = GetX()+dir*step; dir*x < dir*xr; x += dir*step) { | |
1043 | ||
6c94f330 | 1044 | GetXYZ(xyz0); |
3fad3d32 | 1045 | GetProlongation(x,y,z); |
fe33d239 | 1046 | xyz1[0] = x * TMath::Cos(GetAlpha()) + y * TMath::Sin(GetAlpha()); |
1047 | xyz1[1] = x * TMath::Sin(GetAlpha()) - y * TMath::Cos(GetAlpha()); | |
3fad3d32 | 1048 | xyz1[2] = z; |
1049 | Double_t param[7]; | |
826fe01c | 1050 | AliTracker::MeanMaterialBudget(xyz0,xyz1,param); |
fe33d239 | 1051 | |
1052 | if ((param[0] > 0) && | |
1053 | (param[1] > 0)) { | |
826fe01c | 1054 | PropagateTo(x,param[1],param[0]*param[4]); |
fe33d239 | 1055 | } |
1056 | ||
1057 | if (GetY() > GetX()*kTalphac) { | |
53c17fbf | 1058 | Rotate(-kAlphac); |
3fad3d32 | 1059 | } |
fe33d239 | 1060 | if (GetY() < -GetX()*kTalphac) { |
1061 | Rotate( kAlphac); | |
3fad3d32 | 1062 | } |
fe33d239 | 1063 | |
3fad3d32 | 1064 | } |
fe33d239 | 1065 | |
3fad3d32 | 1066 | PropagateTo(xr); |
53c17fbf | 1067 | |
3fad3d32 | 1068 | return 0; |
3fad3d32 | 1069 | |
53c17fbf | 1070 | } |
3fad3d32 | 1071 | |
53c17fbf | 1072 | //_____________________________________________________________________________ |
6c94f330 | 1073 | Int_t AliTRDtrack::PropagateToR(Double_t r,Double_t step) |
3fad3d32 | 1074 | { |
1075 | // | |
fe33d239 | 1076 | // Propagate track to the radial position |
1077 | // Rotation always connected to the last track position | |
3fad3d32 | 1078 | // |
fe33d239 | 1079 | |
1080 | Double_t xyz0[3]; | |
1081 | Double_t xyz1[3]; | |
1082 | Double_t y; | |
1083 | Double_t z; | |
1084 | ||
6c94f330 | 1085 | Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY()); |
fe33d239 | 1086 | // Direction +- |
af26ce80 | 1087 | Double_t dir = (radius > r) ? -1.0 : 1.0; |
fe33d239 | 1088 | |
1089 | for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) { | |
1090 | ||
6c94f330 | 1091 | GetXYZ(xyz0); |
3fad3d32 | 1092 | Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]); |
1093 | Rotate(alpha,kTRUE); | |
6c94f330 | 1094 | GetXYZ(xyz0); |
3fad3d32 | 1095 | GetProlongation(x,y,z); |
fe33d239 | 1096 | xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha); |
1097 | xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha); | |
3fad3d32 | 1098 | xyz1[2] = z; |
1099 | Double_t param[7]; | |
826fe01c | 1100 | AliTracker::MeanMaterialBudget(xyz0,xyz1,param); |
fe33d239 | 1101 | if (param[1] <= 0) { |
1102 | param[1] = 100000000; | |
1103 | } | |
826fe01c | 1104 | PropagateTo(x,param[1],param[0]*param[4]); |
fe33d239 | 1105 | |
3fad3d32 | 1106 | } |
fe33d239 | 1107 | |
6c94f330 | 1108 | GetXYZ(xyz0); |
3fad3d32 | 1109 | Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]); |
1110 | Rotate(alpha,kTRUE); | |
6c94f330 | 1111 | GetXYZ(xyz0); |
3fad3d32 | 1112 | GetProlongation(r,y,z); |
fe33d239 | 1113 | xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha); |
1114 | xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha); | |
3fad3d32 | 1115 | xyz1[2] = z; |
1116 | Double_t param[7]; | |
826fe01c | 1117 | AliTracker::MeanMaterialBudget(xyz0,xyz1,param); |
fe33d239 | 1118 | |
1119 | if (param[1] <= 0) { | |
1120 | param[1] = 100000000; | |
1121 | } | |
826fe01c | 1122 | PropagateTo(r,param[1],param[0]*param[4]); |
53c17fbf | 1123 | |
3fad3d32 | 1124 | return 0; |
53c17fbf | 1125 | |
1126 | } | |
1127 | ||
1128 | //_____________________________________________________________________________ | |
4e28c495 | 1129 | Int_t AliTRDtrack::GetSector() const |
53c17fbf | 1130 | { |
1131 | // | |
1132 | // Return the current sector | |
1133 | // | |
1134 | ||
fe33d239 | 1135 | return Int_t(TVector2::Phi_0_2pi(GetAlpha()) / AliTRDgeometry::GetAlpha()) |
af26ce80 | 1136 | % AliTRDgeometry::kNsect; |
53c17fbf | 1137 | |
3fad3d32 | 1138 | } |
1139 | ||
53c17fbf | 1140 | //_____________________________________________________________________________ |
4e28c495 | 1141 | void AliTRDtrack::SetSampledEdx(Float_t q, Int_t i) |
53c17fbf | 1142 | { |
1143 | // | |
1144 | // The sampled energy loss | |
1145 | // | |
1146 | ||
1147 | Double_t s = GetSnp(); | |
1148 | Double_t t = GetTgl(); | |
fe33d239 | 1149 | q *= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t)); |
53c17fbf | 1150 | fdQdl[i] = q; |
1151 | ||
1152 | } | |
1153 | ||
fe33d239 | 1154 | //_____________________________________________________________________________ |
4e28c495 | 1155 | void AliTRDtrack::SetSampledEdx(Float_t q) |
53c17fbf | 1156 | { |
1157 | // | |
1158 | // The sampled energy loss | |
1159 | // | |
1160 | ||
1161 | Double_t s = GetSnp(); | |
1162 | Double_t t = GetTgl(); | |
fe33d239 | 1163 | q *= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t)); |
53c17fbf | 1164 | fdQdl[fNdedx] = q; |
1165 | fNdedx++; | |
1166 | ||
1167 | } | |
1168 | ||
fe33d239 | 1169 | //_____________________________________________________________________________ |
1170 | Double_t AliTRDtrack::GetBz() const | |
1171 | { | |
15ed8ba1 | 1172 | // |
fe33d239 | 1173 | // Returns Bz component of the magnetic field (kG) |
15ed8ba1 | 1174 | // |
53c17fbf | 1175 | |
fe33d239 | 1176 | if (AliTracker::UniformField()) { |
1177 | return AliTracker::GetBz(); | |
1178 | } | |
1179 | Double_t r[3]; | |
1180 | GetXYZ(r); | |
1181 | ||
1182 | return AliTracker::GetBz(r); | |
53c17fbf | 1183 | |
fe33d239 | 1184 | } |