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