]>
Commit | Line | Data |
---|---|---|
e3b2b5e5 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /////////////////////////////////////////////////////////////////////////////// | |
17 | // // | |
18 | // // | |
19 | // TRD module global track (GTU) // | |
20 | // // | |
21 | // // | |
22 | /////////////////////////////////////////////////////////////////////////////// | |
23 | ||
24 | #include <TMatrixD.h> | |
25 | #include <TObjArray.h> | |
26 | ||
6d50f529 | 27 | #include "AliLog.h" |
28 | ||
e3b2b5e5 | 29 | #include "AliTRDgeometry.h" |
30 | #include "AliTRDcalibDB.h" | |
e3b2b5e5 | 31 | #include "AliTRDltuTracklet.h" |
e3b2b5e5 | 32 | #include "AliTRDgtuTrack.h" |
6d50f529 | 33 | #include "Cal/AliTRDCalPIDLQ.h" |
e3b2b5e5 | 34 | |
35 | ClassImp(AliTRDgtuTrack) | |
36 | ||
37 | //_____________________________________________________________________________ | |
38 | AliTRDgtuTrack::AliTRDgtuTrack() | |
6d50f529 | 39 | :TObject() |
40 | ,fTracklets(new TObjArray(400)) | |
41 | ,fYproj(0) | |
42 | ,fZproj(0) | |
43 | ,fSlope(0) | |
44 | ,fDetector(-1) | |
45 | ,fNtracklets(0) | |
46 | ,fNplanes(0) | |
47 | ,fNclusters(0) | |
48 | ,fPt(0) | |
49 | ,fPhi(0) | |
50 | ,fEta(0) | |
51 | ,fLabel(-1) | |
52 | ,fPID(0) | |
53 | ,fIsElectron(kFALSE) | |
e3b2b5e5 | 54 | { |
55 | // | |
56 | // Default constructor | |
57 | // | |
58 | ||
e3b2b5e5 | 59 | } |
60 | ||
61 | //_____________________________________________________________________________ | |
6d50f529 | 62 | AliTRDgtuTrack::AliTRDgtuTrack(const AliTRDgtuTrack& t) |
63 | :TObject(t) | |
64 | ,fTracklets(NULL) | |
65 | ,fYproj(t.fYproj) | |
66 | ,fZproj(t.fZproj) | |
67 | ,fSlope(t.fSlope) | |
68 | ,fDetector(t.fDetector) | |
69 | ,fNtracklets(t.fNtracklets) | |
70 | ,fNplanes(t.fNplanes) | |
71 | ,fNclusters(t.fNclusters) | |
72 | ,fPt(t.fPt) | |
73 | ,fPhi(t.fPhi) | |
74 | ,fEta(t.fEta) | |
75 | ,fLabel(t.fLabel) | |
76 | ,fPID(t.fPID) | |
77 | ,fIsElectron(t.fIsElectron) | |
e3b2b5e5 | 78 | { |
79 | // | |
6d50f529 | 80 | // Copy contructor |
e3b2b5e5 | 81 | // |
82 | ||
83 | } | |
84 | ||
85 | //_____________________________________________________________________________ | |
86 | AliTRDgtuTrack &AliTRDgtuTrack::operator=(const AliTRDgtuTrack &t) | |
87 | { | |
88 | // | |
6d50f529 | 89 | // Assignment operator |
e3b2b5e5 | 90 | // |
91 | ||
92 | if (this != &t) ((AliTRDgtuTrack &) t).Copy(*this); | |
93 | return *this; | |
94 | ||
6d50f529 | 95 | } |
e3b2b5e5 | 96 | |
97 | //_____________________________________________________________________________ | |
98 | void AliTRDgtuTrack::Copy(TObject &t) const | |
99 | { | |
100 | // | |
6d50f529 | 101 | // Copy function |
e3b2b5e5 | 102 | // |
103 | ||
104 | ((AliTRDgtuTrack &) t).fTracklets = NULL; | |
105 | ((AliTRDgtuTrack &) t).fYproj = fYproj; | |
106 | ((AliTRDgtuTrack &) t).fZproj = fZproj; | |
107 | ((AliTRDgtuTrack &) t).fSlope = fSlope; | |
108 | ((AliTRDgtuTrack &) t).fDetector = fDetector; | |
109 | ((AliTRDgtuTrack &) t).fNtracklets = fNtracklets; | |
110 | ((AliTRDgtuTrack &) t).fNplanes = fNplanes; | |
111 | ((AliTRDgtuTrack &) t).fNclusters = fNclusters; | |
112 | ((AliTRDgtuTrack &) t).fPt = fPt; | |
113 | ((AliTRDgtuTrack &) t).fPhi = fPhi; | |
114 | ((AliTRDgtuTrack &) t).fEta = fEta; | |
115 | ((AliTRDgtuTrack &) t).fLabel = fLabel; | |
116 | ((AliTRDgtuTrack &) t).fPID = fPID; | |
117 | ((AliTRDgtuTrack &) t).fIsElectron = fIsElectron; | |
118 | ||
119 | } | |
120 | ||
121 | //_____________________________________________________________________________ | |
122 | AliTRDgtuTrack::~AliTRDgtuTrack() | |
123 | { | |
124 | // | |
6d50f529 | 125 | // Destructor |
e3b2b5e5 | 126 | // |
127 | ||
6d50f529 | 128 | if (fTracklets) { |
129 | fTracklets->Delete(); | |
130 | delete fTracklets; | |
131 | } | |
132 | ||
e3b2b5e5 | 133 | } |
134 | ||
135 | //_____________________________________________________________________________ | |
136 | void AliTRDgtuTrack::AddTracklet(AliTRDltuTracklet *trk) | |
137 | { | |
138 | // | |
139 | // Add a LTU tracklet to this track | |
140 | // | |
141 | ||
142 | Tracklets()->Add(trk); | |
143 | ||
144 | } | |
145 | ||
146 | //_____________________________________________________________________________ | |
147 | AliTRDltuTracklet* AliTRDgtuTrack::GetTracklet(Int_t pos) const | |
148 | { | |
149 | // | |
150 | // Return LTU tracklet at position "pos" | |
151 | // | |
152 | ||
6d50f529 | 153 | if (fTracklets == 0) { |
154 | return 0; | |
155 | } | |
156 | void *trk = fTracklets->UncheckedAt(pos); | |
157 | if (trk == 0) { | |
158 | return 0; | |
159 | } | |
e3b2b5e5 | 160 | |
6d50f529 | 161 | return (AliTRDltuTracklet *) trk; |
e3b2b5e5 | 162 | |
163 | } | |
164 | ||
165 | //_____________________________________________________________________________ | |
166 | Int_t AliTRDgtuTrack::Compare(const TObject * o) const | |
167 | { | |
168 | // | |
169 | // Compare function for sorting the tracks | |
170 | // | |
171 | ||
172 | AliTRDgtuTrack *gtutrack = (AliTRDgtuTrack*)o; | |
173 | ||
174 | if (fYproj < gtutrack->GetYproj()) return -1; | |
175 | if (fYproj == gtutrack->GetYproj()) return 0; | |
176 | ||
177 | return +1; | |
178 | ||
179 | } | |
180 | ||
181 | //_____________________________________________________________________________ | |
182 | void AliTRDgtuTrack::Reset() | |
183 | { | |
184 | // | |
185 | // Reset the track information | |
186 | // | |
187 | ||
6d50f529 | 188 | fYproj = 0.0; |
189 | fZproj = 0.0; | |
190 | fSlope = 0.0; | |
191 | fDetector = -1; | |
e3b2b5e5 | 192 | fNtracklets = 0; |
6d50f529 | 193 | fNplanes = 0; |
194 | fNclusters = 0; | |
195 | fPt = 0.0; | |
196 | fPhi = 0.0; | |
197 | fEta = 0.0; | |
198 | fLabel = -1; | |
199 | fPID = 0.0; | |
e3b2b5e5 | 200 | fIsElectron = kFALSE; |
201 | ||
202 | } | |
203 | ||
204 | //_____________________________________________________________________________ | |
205 | void AliTRDgtuTrack::Track(Float_t xpl, Float_t field) | |
206 | { | |
207 | // | |
208 | // Calculate the kinematics of the found track | |
209 | // | |
210 | ||
6d50f529 | 211 | Int_t i = 0; |
212 | Int_t iDet = 0; | |
213 | Int_t nDet = 0; | |
214 | Bool_t newDetector; | |
215 | ||
e3b2b5e5 | 216 | AliTRDltuTracklet *trk; |
217 | Int_t nTracklets = GetNtracklets(); | |
218 | Float_t fC[kNmaxTrk][3]; // X, Y, Z coordinates of segments | |
219 | ||
6d50f529 | 220 | fYproj = 0.0; |
221 | fZproj = 0.0; | |
222 | fSlope = 0.0; | |
223 | fNclusters = 0; | |
224 | fNplanes = 0; | |
e3b2b5e5 | 225 | fNtracklets = GetNtracklets(); |
226 | Int_t inDetector[kNplan]; | |
6d50f529 | 227 | for (i = 0; i < kNplan; i++) { |
228 | inDetector[i] = -1; | |
229 | } | |
230 | ||
231 | for (i = 0; i < nTracklets; i++) { | |
e3b2b5e5 | 232 | |
233 | trk = GetTracklet(i); | |
234 | fYproj += trk->GetYproj(xpl); | |
235 | fZproj += trk->GetZproj(xpl); | |
236 | fSlope += trk->GetSlope(); | |
237 | fNclusters += trk->GetNclusters(); | |
238 | iDet = trk->GetDetector(); | |
239 | ||
240 | newDetector = kTRUE; | |
241 | for (Int_t id = 0; id < nDet; id++) { | |
242 | if (iDet == inDetector[id]) { | |
243 | newDetector = kFALSE; | |
244 | break; | |
245 | } | |
246 | } | |
247 | if (newDetector) { | |
248 | inDetector[nDet++] = iDet; | |
249 | fNplanes++; | |
250 | } | |
251 | ||
252 | fC[i][0] = trk->GetTime0(); | |
253 | fC[i][1] = trk->GetOffset(); | |
254 | fC[i][2] = trk->GetRowz(); | |
255 | ||
256 | } | |
257 | fYproj /= (Float_t)nTracklets; | |
258 | fZproj /= (Float_t)nTracklets; | |
259 | fSlope /= (Float_t)nTracklets; | |
260 | ||
261 | Float_t x[kNmaxTrk+1], y[kNmaxTrk+1], z[kNmaxTrk+1]; | |
262 | Bool_t count[kNmaxTrk]; | |
263 | for (Int_t i = 0; i < kNmaxTrk; i++) count[i] = kFALSE; | |
264 | ||
265 | Int_t iXmin = -1; | |
266 | Int_t j = 0; | |
267 | x[0] = y[0] = z[0] = 0.0; | |
268 | while (j < nTracklets) { | |
269 | iXmin = -1; | |
270 | for (Int_t i = 0; i < nTracklets; i++) { | |
271 | if (count[i]) continue; | |
272 | if (iXmin == -1) { | |
273 | iXmin = i; | |
274 | continue; | |
275 | } | |
276 | if (fC[i][0] < fC[iXmin][0]) iXmin = i; | |
277 | } | |
278 | x[j+1] = fC[iXmin][0]; | |
279 | y[j+1] = fC[iXmin][1]; | |
280 | z[j+1] = fC[iXmin][2]; | |
281 | j++; | |
282 | count[iXmin] = kTRUE; | |
283 | } | |
284 | ||
285 | TMatrixD smatrix(2,2); | |
286 | TMatrixD sums(2,1); | |
287 | TMatrixD res(2,1); | |
288 | Double_t xv, yv; | |
289 | Float_t a, b; | |
290 | ||
291 | smatrix.Zero(); | |
292 | sums.Zero(); | |
6d50f529 | 293 | for (i = 0; i < nTracklets; i++) { |
e3b2b5e5 | 294 | xv = (Double_t)x[i+1]; |
295 | yv = (Double_t)y[i+1]; | |
296 | smatrix(0,0) += 1.0; | |
297 | smatrix(1,1) += xv*xv; | |
298 | smatrix(0,1) += xv; | |
299 | smatrix(1,0) += xv; | |
300 | sums(0,0) += yv; | |
301 | sums(1,0) += xv*yv; | |
302 | } | |
303 | res = smatrix.Invert() * sums; | |
304 | a = res(0,0); | |
305 | b = res(1,0); | |
306 | ||
6d50f529 | 307 | Float_t dist = AliTRDgeometry::GetTime0(1) - AliTRDgeometry::GetTime0(0); |
308 | Float_t fx1 = x[1] + dist * (Float_t)(nTracklets-1)/6.0; | |
309 | Float_t fy1 = a + b * fx1; | |
310 | Float_t fx2 = x[nTracklets] - dist * (Float_t)(nTracklets-1)/6.0; | |
311 | Float_t fy2 = a + b * fx2; | |
312 | Float_t d12 = TMath::Sqrt((fx2-fx1)*(fx2-fx1)+(fy2-fy1)*(fy2-fy1)); | |
e3b2b5e5 | 313 | Float_t alpha = TMath::ATan(fy2/fx2) - TMath::ATan(fy1/fx1); |
6d50f529 | 314 | Float_t r = (d12/2.0)/TMath::Sin(alpha); |
e3b2b5e5 | 315 | |
316 | fPt = 0.3 * field * 0.01 * r; | |
317 | ||
318 | Float_t d1 = fx1*fx1+fy1*fy1; | |
319 | Float_t d2 = fx2*fx2+fy2*fy2; | |
320 | Float_t d = fx1*fy2-fx2*fy1; | |
321 | ||
322 | Float_t xc = (d1*fy2-d2*fy1)/(2*d); | |
323 | Float_t yc = (d2*fx1-d1*fx2)/(2*d); | |
324 | ||
325 | if (yc != 0.0) { | |
326 | fPhi = TMath::ATan(xc/yc); | |
6d50f529 | 327 | } |
328 | else { | |
e3b2b5e5 | 329 | fPhi = TMath::PiOver2(); |
330 | } | |
331 | ||
332 | fPhi *= 180.0/TMath::Pi(); | |
333 | ||
334 | smatrix.Zero(); | |
335 | sums.Zero(); | |
6d50f529 | 336 | for (i = 0; i < nTracklets+1; i++) { |
e3b2b5e5 | 337 | xv = (Double_t)z[i]; |
338 | yv = (Double_t)x[i]; | |
339 | smatrix(0,0) += 1.0; | |
340 | smatrix(1,1) += xv*xv; | |
341 | smatrix(0,1) += xv; | |
342 | smatrix(1,0) += xv; | |
343 | sums(0,0) += yv; | |
344 | sums(1,0) += xv*yv; | |
345 | } | |
346 | res = smatrix.Invert() * sums; | |
347 | a = res(0,0); | |
348 | b = res(1,0); | |
349 | Float_t theta = TMath::ATan(b); | |
350 | ||
6d50f529 | 351 | if (theta < 0.0) { |
352 | theta = TMath::Pi() + theta; | |
353 | } | |
e3b2b5e5 | 354 | if (theta == 0.0) { |
355 | fEta = 0.0; | |
6d50f529 | 356 | } |
357 | else { | |
e3b2b5e5 | 358 | fEta = -TMath::Log(TMath::Tan(theta/2.0)); |
359 | } | |
360 | ||
361 | } | |
362 | ||
363 | //_____________________________________________________________________________ | |
364 | void AliTRDgtuTrack::MakePID() | |
365 | { | |
366 | // | |
367 | // Electron likelihood signal | |
368 | // | |
369 | ||
6d50f529 | 370 | Int_t i = 0; |
371 | ||
e3b2b5e5 | 372 | AliTRDcalibDB* calibration = AliTRDcalibDB::Instance(); |
373 | if (!calibration) | |
374 | { | |
6d50f529 | 375 | AliError("No instance of AliTRDcalibDB."); |
e3b2b5e5 | 376 | return; |
377 | } | |
378 | const AliTRDCalPIDLQ *pd = calibration->GetPIDLQObject(); | |
379 | ||
380 | AliTRDltuTracklet *trk; | |
381 | Int_t nTracklets = GetNtracklets(); | |
382 | Int_t det, pla; | |
383 | Float_t sl, th, q, probPio = 1.0, probEle = 1.0; | |
6d50f529 | 384 | for (i = 0; i < nTracklets; i++) { |
e3b2b5e5 | 385 | |
386 | trk = GetTracklet(i); | |
387 | ||
388 | sl = TMath::Abs(trk->GetSlope()); // tracklet inclination in X-y plane | |
389 | th = trk->GetRowz()/trk->GetTime0(); // tracklet inclination in X-z plane | |
390 | th = TMath::ATan(TMath::Abs(th)); | |
391 | ||
392 | q = trk->GetQ() | |
393 | * TMath::Cos(sl/180.0*TMath::Pi()) | |
394 | * TMath::Cos(th/180.0*TMath::Pi()); | |
395 | ||
396 | det = trk->GetDetector(); | |
397 | pla = trk->GetPlane(det); | |
398 | ||
399 | // unclear yet factor to match the PS distributions = 5.8 | |
400 | // not explained only by the tail filter ... | |
401 | ||
402 | // AliRoot v4-03-07 , v4-03-Release | |
403 | //q = q * 5.8; | |
404 | ||
4c8471bd | 405 | // HEAD28Mar06 |
e3b2b5e5 | 406 | // Temporary (B. Vulpescu): |
407 | // The charge distributions do not match the new changes in simulation (A. Bercuci), | |
408 | // which are nevertheless now in agreement with the beam tests. | |
409 | // Some tricks will be used to still have reasonable results | |
410 | // To match the existing charge distributions, the charge per layer has to be modified | |
411 | // as folows: | |
412 | /* | |
413 | if (k == 0) { | |
414 | // electrons | |
415 | q = 4.3 * q + 95.0; | |
416 | } else { | |
417 | // others | |
418 | q = 4.2 * q + 70.0; | |
419 | } | |
420 | */ | |
421 | // Since at tracking time we have no information on the particle type, we will modify | |
422 | // instead the charge distributions accordingly. This will slow down the sampling. | |
423 | // The modified distributions are in TRDdEdxHistogramsV1_BV.root and the CDB has | |
424 | // been regenerated with AliTRDCreateDummyCDB.C | |
425 | // The new PIDLQ data base has the version : | |
426 | // I-AliCDBLocal::Get: CDB object retrieved: path "TRD/Calib/PIDLQ"; run range [0,0]; | |
427 | // version v0_s1 | |
428 | ||
4c8471bd | 429 | // HEAD28Mar06 new distributions: factor = 6.0 |
430 | ||
431 | probEle *= pd->GetProbability(0,TMath::Abs(fPt),q*6.0); | |
432 | probPio *= pd->GetProbability(2,TMath::Abs(fPt),q*6.0); | |
e3b2b5e5 | 433 | |
434 | } | |
435 | ||
436 | if ((probEle+probPio) > 0.0) { | |
437 | fPID = probEle/(probEle+probPio); | |
6d50f529 | 438 | } |
439 | else { | |
e3b2b5e5 | 440 | fPID = 0.0; |
441 | } | |
442 | ||
443 | // Thresholds for LQ cut at 90% electron efficiency (from AliRoot v4-03-07) | |
444 | // P [GeV/c] fPIDcut (between 0 and 1) | |
445 | // 2 0.925 | |
446 | // 3 0.915 | |
447 | // 4 0.875 | |
448 | // 5 0.855 | |
449 | // 6 0.845 | |
450 | // 8 0.785 | |
451 | // 10 0.735 | |
452 | // | |
453 | // PIDcut = 0.978 - 0.024 * P[GeV/c] | |
454 | //Float_t PIDcut = 0.978 - 0.024 * TMath::Abs(fPt); | |
455 | ||
456 | // HEAD28Mar06 with modified distributions (A. Bercuci changes, P. Shukla distributions) | |
4c8471bd | 457 | //Float_t fPIDcut = 0.829 - 0.032 * TMath::Abs(fPt); |
458 | ||
459 | // HEAD28Mar06 with new generated distributions (pol2 fit) | |
460 | Float_t absPt = TMath::Abs(fPt); | |
461 | //Float_t fPIDcut = 0.9575 - 0.0832 * absPt + 0.0037 * absPt*absPt; // 800 bins in dEdx | |
462 | Float_t fPIDcut = 0.9482 - 0.0795 * absPt + 0.0035 * absPt*absPt; // 200 bins in dEdx | |
e3b2b5e5 | 463 | |
464 | fIsElectron = kFALSE; | |
465 | if (fPID >= fPIDcut) { | |
466 | fIsElectron = kTRUE; | |
467 | } | |
468 | ||
469 | } | |
470 | ||
471 | //_____________________________________________________________________________ | |
472 | void AliTRDgtuTrack::CookLabel() | |
473 | { | |
474 | // | |
475 | // Cook the track label from tracklets labels | |
476 | // | |
477 | ||
478 | AliTRDltuTracklet *trk; | |
479 | ||
480 | const Int_t kMaxTracks = 10; | |
481 | Int_t trackLabel[kMaxTracks]; | |
482 | Int_t trackCount[kMaxTracks]; | |
483 | for (Int_t it = 0; it < kMaxTracks; it++) { | |
484 | trackLabel[it] = -1; | |
485 | trackCount[it] = 0; | |
486 | } | |
487 | ||
488 | Bool_t counted; | |
489 | Int_t label, nTracks = 0; | |
490 | for (Int_t itrk = 0; itrk < fNtracklets; itrk++) { | |
491 | ||
492 | trk = GetTracklet(itrk); | |
493 | ||
494 | if (trk->GetLabel() == -1) continue; | |
495 | ||
496 | label = trk->GetLabel(); | |
497 | ||
498 | counted = kFALSE; | |
499 | for (Int_t it = 0; it < nTracks; it++) { | |
500 | if (label == trackLabel[it]) { | |
501 | trackCount[it]++; | |
502 | counted = kTRUE; | |
503 | break; | |
504 | } | |
505 | } | |
506 | if (!counted) { | |
507 | trackLabel[nTracks] = label; | |
508 | trackCount[nTracks]++; | |
509 | nTracks++; | |
510 | if (nTracks == kMaxTracks) { | |
511 | Warning("CookLabel","Too many tracks for this tracklet."); | |
512 | nTracks--; | |
513 | break; | |
514 | } | |
515 | } | |
516 | ||
517 | } | |
518 | ||
519 | Float_t frac = 4.0/5.0; | |
520 | for (Int_t it = 0; it < kMaxTracks; it++) { | |
521 | if (trackCount[it] >= (Int_t)(frac*fNtracklets)) { | |
522 | fLabel = trackLabel[it]; | |
523 | break; | |
524 | } | |
525 | } | |
526 | ||
527 | } | |
528 | ||
6d50f529 | 529 | //_____________________________________________________________________________ |
530 | void AliTRDgtuTrack::ResetTracklets() | |
531 | { | |
532 | // | |
533 | // Resets the list of tracklets | |
534 | // | |
535 | ||
536 | if (fTracklets) { | |
537 | fTracklets->Delete(); | |
538 | } | |
539 | ||
540 | } | |
541 | ||
542 | //_____________________________________________________________________________ | |
543 | TObjArray* AliTRDgtuTrack::Tracklets() | |
544 | { | |
545 | // | |
546 | // Returns the list of tracklets | |
547 | // | |
548 | ||
549 | if (!fTracklets) { | |
550 | fTracklets = new TObjArray(400); | |
551 | } | |
552 | ||
553 | return fTracklets; | |
554 | ||
555 | } | |
556 | ||
557 | //_____________________________________________________________________________ | |
558 | Int_t AliTRDgtuTrack::GetNtracklets() const | |
559 | { | |
560 | // | |
561 | // Returns the number of tracklets | |
562 | // | |
563 | ||
564 | if (fTracklets) { | |
565 | return fTracklets->GetEntriesFast(); | |
566 | } | |
567 | ||
568 | return 0; | |
569 | ||
570 | } |