1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////////
19 // TRD module global track (GTU) //
22 ///////////////////////////////////////////////////////////////////////////////
25 #include <TObjArray.h>
29 #include "AliTRDgeometry.h"
30 #include "AliTRDcalibDB.h"
31 #include "AliTRDltuTracklet.h"
32 #include "AliTRDgtuTrack.h"
33 #include "Cal/AliTRDCalPIDLQ.h"
35 ClassImp(AliTRDgtuTrack)
37 //_____________________________________________________________________________
38 AliTRDgtuTrack::AliTRDgtuTrack()
40 ,fTracklets(new TObjArray(400))
56 // Default constructor
61 //_____________________________________________________________________________
62 AliTRDgtuTrack::AliTRDgtuTrack(const AliTRDgtuTrack& t)
68 ,fDetector(t.fDetector)
69 ,fNtracklets(t.fNtracklets)
71 ,fNclusters(t.fNclusters)
77 ,fIsElectron(t.fIsElectron)
85 //_____________________________________________________________________________
86 AliTRDgtuTrack &AliTRDgtuTrack::operator=(const AliTRDgtuTrack &t)
89 // Assignment operator
92 if (this != &t) ((AliTRDgtuTrack &) t).Copy(*this);
97 //_____________________________________________________________________________
98 void AliTRDgtuTrack::Copy(TObject &t) const
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;
121 //_____________________________________________________________________________
122 AliTRDgtuTrack::~AliTRDgtuTrack()
129 fTracklets->Delete();
136 //_____________________________________________________________________________
137 void AliTRDgtuTrack::AddTracklet(AliTRDltuTracklet *trk)
140 // Add a LTU tracklet to this track
143 Tracklets()->Add(trk);
147 //_____________________________________________________________________________
148 AliTRDltuTracklet* AliTRDgtuTrack::GetTracklet(Int_t pos) const
151 // Return LTU tracklet at position "pos"
154 if (fTracklets == 0) {
157 void *trk = fTracklets->UncheckedAt(pos);
162 return (AliTRDltuTracklet *) trk;
166 //_____________________________________________________________________________
167 Int_t AliTRDgtuTrack::Compare(const TObject * o) const
170 // Compare function for sorting the tracks
173 AliTRDgtuTrack *gtutrack = (AliTRDgtuTrack *) o;
175 if (fYproj < gtutrack->GetYproj()) {
178 if (fYproj == gtutrack->GetYproj()) {
186 //_____________________________________________________________________________
187 void AliTRDgtuTrack::Reset()
190 // Reset the track information
205 fIsElectron = kFALSE;
209 //_____________________________________________________________________________
210 void AliTRDgtuTrack::Track(Float_t xpl, Float_t field)
213 // Calculate the kinematics of the found track
221 AliTRDltuTracklet *trk;
222 Int_t nTracklets = GetNtracklets();
223 Float_t fC[kNmaxTrk][3]; // X, Y, Z coordinates of segments
230 fNtracklets = GetNtracklets();
231 Int_t inDetector[kNplan];
232 for (i = 0; i < kNplan; i++) {
236 for (i = 0; i < nTracklets; i++) {
238 trk = GetTracklet(i);
239 fYproj += trk->GetYproj(xpl);
240 fZproj += trk->GetZproj(xpl);
241 fSlope += trk->GetSlope();
242 fNclusters += trk->GetNclusters();
243 iDet = trk->GetDetector();
246 for (Int_t id = 0; id < nDet; id++) {
247 if (iDet == inDetector[id]) {
248 newDetector = kFALSE;
253 inDetector[nDet++] = iDet;
257 fC[i][0] = trk->GetTime0();
258 fC[i][1] = trk->GetOffset();
259 fC[i][2] = trk->GetRowz();
262 fYproj /= (Float_t)nTracklets;
263 fZproj /= (Float_t)nTracklets;
264 fSlope /= (Float_t)nTracklets;
266 Float_t x[kNmaxTrk+1], y[kNmaxTrk+1], z[kNmaxTrk+1];
267 Bool_t count[kNmaxTrk];
268 for (Int_t i = 0; i < kNmaxTrk; i++) count[i] = kFALSE;
272 x[0] = y[0] = z[0] = 0.0;
273 while (j < nTracklets) {
275 for (Int_t i = 0; i < nTracklets; i++) {
276 if (count[i]) continue;
281 if (fC[i][0] < fC[iXmin][0]) iXmin = i;
283 x[j+1] = fC[iXmin][0];
284 y[j+1] = fC[iXmin][1];
285 z[j+1] = fC[iXmin][2];
287 count[iXmin] = kTRUE;
290 TMatrixD smatrix(2,2);
298 for (i = 0; i < nTracklets; i++) {
299 xv = (Double_t)x[i+1];
300 yv = (Double_t)y[i+1];
302 smatrix(1,1) += xv*xv;
308 res = smatrix.Invert() * sums;
312 Float_t dist = AliTRDgeometry::GetTime0(1) - AliTRDgeometry::GetTime0(0);
313 Float_t fx1 = x[1] + dist * (Float_t)(nTracklets-1)/6.0;
314 Float_t fy1 = a + b * fx1;
315 Float_t fx2 = x[nTracklets] - dist * (Float_t)(nTracklets-1)/6.0;
316 Float_t fy2 = a + b * fx2;
317 Float_t d12 = TMath::Sqrt((fx2-fx1)*(fx2-fx1)+(fy2-fy1)*(fy2-fy1));
318 Float_t alpha = TMath::ATan(fy2/fx2) - TMath::ATan(fy1/fx1);
319 Float_t r = (d12/2.0)/TMath::Sin(alpha);
321 fPt = 0.3 * field * 0.01 * r;
323 Float_t d1 = fx1*fx1+fy1*fy1;
324 Float_t d2 = fx2*fx2+fy2*fy2;
325 Float_t d = fx1*fy2-fx2*fy1;
327 Float_t xc = (d1*fy2-d2*fy1)/(2*d);
328 Float_t yc = (d2*fx1-d1*fx2)/(2*d);
331 fPhi = TMath::ATan(xc/yc);
334 fPhi = TMath::PiOver2();
337 fPhi *= 180.0/TMath::Pi();
341 for (i = 0; i < nTracklets+1; i++) {
345 smatrix(1,1) += xv*xv;
351 res = smatrix.Invert() * sums;
354 Float_t theta = TMath::ATan(b);
357 theta = TMath::Pi() + theta;
363 fEta = -TMath::Log(TMath::Tan(theta/2.0));
368 //_____________________________________________________________________________
369 void AliTRDgtuTrack::MakePID()
372 // Electron likelihood signal
377 AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
379 AliError("No instance of AliTRDcalibDB.");
382 const AliTRDCalPIDLQ *pd = calibration->GetPIDLQObject();
384 AliTRDltuTracklet *trk;
385 Int_t nTracklets = GetNtracklets();
391 Float_t probPio = 1.0;
392 Float_t probEle = 1.0;
394 for (i = 0; i < nTracklets; i++) {
396 trk = GetTracklet(i);
398 sl = TMath::Abs(trk->GetSlope()); // tracklet inclination in X-y plane
399 th = trk->GetRowz()/trk->GetTime0(); // tracklet inclination in X-z plane
400 th = TMath::ATan(TMath::Abs(th));
403 * TMath::Cos(sl/180.0*TMath::Pi())
404 * TMath::Cos(th/180.0*TMath::Pi());
406 det = trk->GetDetector();
407 pla = trk->GetPlane(det);
409 // unclear yet factor to match the PS distributions = 5.8
410 // not explained only by the tail filter ...
412 // AliRoot v4-03-07 , v4-03-Release
416 // Temporary (B. Vulpescu):
417 // The charge distributions do not match the new changes in simulation (A. Bercuci),
418 // which are nevertheless now in agreement with the beam tests.
419 // Some tricks will be used to still have reasonable results
420 // To match the existing charge distributions, the charge per layer has to be modified
431 // Since at tracking time we have no information on the particle type, we will modify
432 // instead the charge distributions accordingly. This will slow down the sampling.
433 // The modified distributions are in TRDdEdxHistogramsV1_BV.root and the CDB has
434 // been regenerated with AliTRDCreateDummyCDB.C
435 // The new PIDLQ data base has the version :
436 // I-AliCDBLocal::Get: CDB object retrieved: path "TRD/Calib/PIDLQ"; run range [0,0];
439 // HEAD28Mar06 new distributions: factor = 6.0
441 probEle *= pd->GetProbability(0,TMath::Abs(fPt),q*6.0);
442 probPio *= pd->GetProbability(2,TMath::Abs(fPt),q*6.0);
446 if ((probEle+probPio) > 0.0) {
447 fPID = probEle/(probEle+probPio);
453 // Thresholds for LQ cut at 90% electron efficiency (from AliRoot v4-03-07)
454 // P [GeV/c] fPIDcut (between 0 and 1)
463 // PIDcut = 0.978 - 0.024 * P[GeV/c]
464 //Float_t PIDcut = 0.978 - 0.024 * TMath::Abs(fPt);
466 // HEAD28Mar06 with modified distributions (A. Bercuci changes, P. Shukla distributions)
467 //Float_t fPIDcut = 0.829 - 0.032 * TMath::Abs(fPt);
469 // HEAD28Mar06 with new generated distributions (pol2 fit)
470 Float_t absPt = TMath::Abs(fPt);
471 //Float_t fPIDcut = 0.9575 - 0.0832 * absPt + 0.0037 * absPt*absPt; // 800 bins in dEdx
472 Float_t fPIDcut = 0.9482 - 0.0795 * absPt + 0.0035 * absPt*absPt; // 200 bins in dEdx
474 fIsElectron = kFALSE;
475 if (fPID >= fPIDcut) {
481 //_____________________________________________________________________________
482 void AliTRDgtuTrack::CookLabel()
485 // Cook the track label from tracklets labels
488 AliTRDltuTracklet *trk;
490 const Int_t kMaxTracks = 10;
491 Int_t trackLabel[kMaxTracks];
492 Int_t trackCount[kMaxTracks];
493 for (Int_t it = 0; it < kMaxTracks; it++) {
501 for (Int_t itrk = 0; itrk < fNtracklets; itrk++) {
503 trk = GetTracklet(itrk);
505 if (trk->GetLabel() == -1) {
509 label = trk->GetLabel();
512 for (Int_t it = 0; it < nTracks; it++) {
513 if (label == trackLabel[it]) {
520 trackLabel[nTracks] = label;
521 trackCount[nTracks]++;
523 if (nTracks == kMaxTracks) {
524 Warning("CookLabel","Too many tracks for this tracklet.");
532 Float_t frac = 4.0 / 5.0;
533 for (Int_t it = 0; it < kMaxTracks; it++) {
534 if (trackCount[it] >= (Int_t) (frac*fNtracklets)) {
535 fLabel = trackLabel[it];
542 //_____________________________________________________________________________
543 void AliTRDgtuTrack::ResetTracklets()
546 // Resets the list of tracklets
550 fTracklets->Delete();
555 //_____________________________________________________________________________
556 TObjArray *AliTRDgtuTrack::Tracklets()
559 // Returns the list of tracklets
563 fTracklets = new TObjArray(400);
570 //_____________________________________________________________________________
571 Int_t AliTRDgtuTrack::GetNtracklets() const
574 // Returns the number of tracklets
578 return fTracklets->GetEntriesFast();