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