b0f03c34 |
1 | /************************************************************************** |
0d83b3a5 |
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 | **************************************************************************/ |
b0f03c34 |
15 | |
dab811d0 |
16 | /* $Id$ */ |
17 | |
b52cb1b6 |
18 | //////////////////////////////////////////////////////////////////////////// |
19 | // // |
20 | // Implementation of the TRD PID class // |
21 | // // |
22 | // Assigns the electron and pion likelihoods to each ESD track. // |
c8ab4518 |
23 | // The function MakePID(AliESDEvent *event) calculates the probability // |
b52cb1b6 |
24 | // of having dedx and a maximum timbin at a given // |
25 | // momentum (mom) and particle type k // |
26 | // from the precalculated distributions. // |
27 | // // |
dab811d0 |
28 | // Authors : // |
c8ab4518 |
29 | // Prashant Shukla <shukla@pi0.physi.uni-heidelberg.de> (orig. version) // |
30 | // Alex Bercuci (a.bercuci@gsi.de) // |
b52cb1b6 |
31 | // // |
32 | //////////////////////////////////////////////////////////////////////////// |
b0f03c34 |
33 | |
af885e0f |
34 | #include "AliESDEvent.h" |
b0f03c34 |
35 | #include "AliESDtrack.h" |
c6011b06 |
36 | #include "AliTracker.h" |
b52cb1b6 |
37 | |
38 | #include "AliTRDpidESD.h" |
39 | #include "AliTRDgeometry.h" |
cc7cef99 |
40 | #include "AliTRDcalibDB.h" |
4d6aee34 |
41 | #include "Cal/AliTRDCalPID.h" |
b0f03c34 |
42 | |
43 | ClassImp(AliTRDpidESD) |
44 | |
c8ab4518 |
45 | Bool_t AliTRDpidESD::fgCheckTrackStatus = kTRUE; |
46 | Bool_t AliTRDpidESD::fgCheckKinkStatus = kFALSE; |
47 | Int_t AliTRDpidESD::fgMinPlane = 0; |
df34b21e |
48 | |
b52cb1b6 |
49 | //_____________________________________________________________________________ |
dab811d0 |
50 | AliTRDpidESD::AliTRDpidESD() |
c8ab4518 |
51 | :TObject() |
4d6aee34 |
52 | ,fTrack(NULL) |
b0f03c34 |
53 | { |
54 | // |
b52cb1b6 |
55 | // Default constructor |
b0f03c34 |
56 | // |
b52cb1b6 |
57 | |
b0f03c34 |
58 | } |
59 | |
b52cb1b6 |
60 | //_____________________________________________________________________________ |
dab811d0 |
61 | AliTRDpidESD::AliTRDpidESD(const AliTRDpidESD &p) |
c8ab4518 |
62 | :TObject(p) |
4d6aee34 |
63 | ,fTrack(NULL) |
eab5961e |
64 | { |
b0f03c34 |
65 | // |
b52cb1b6 |
66 | // AliTRDpidESD copy constructor |
b0f03c34 |
67 | // |
eab5961e |
68 | |
b52cb1b6 |
69 | ((AliTRDpidESD &) p).Copy(*this); |
70 | |
71 | } |
72 | |
73 | //_____________________________________________________________________________ |
c6011b06 |
74 | AliTRDpidESD::~AliTRDpidESD() |
75 | { |
76 | // |
77 | // Destructor |
78 | // |
c8ab4518 |
79 | |
80 | if(fTrack) delete fTrack; |
81 | |
c6011b06 |
82 | } |
83 | |
84 | //_____________________________________________________________________________ |
b52cb1b6 |
85 | AliTRDpidESD &AliTRDpidESD::operator=(const AliTRDpidESD &p) |
86 | { |
87 | // |
88 | // Assignment operator |
89 | // |
90 | |
91 | if (this != &p) ((AliTRDpidESD &) p).Copy(*this); |
92 | return *this; |
93 | |
94 | } |
95 | |
96 | //_____________________________________________________________________________ |
97 | void AliTRDpidESD::Copy(TObject &p) const |
98 | { |
99 | // |
100 | // Copy function |
101 | // |
102 | |
c8ab4518 |
103 | ((AliTRDpidESD &) p).fgCheckTrackStatus = fgCheckTrackStatus; |
104 | ((AliTRDpidESD &) p).fgCheckKinkStatus = fgCheckKinkStatus; |
105 | ((AliTRDpidESD &) p).fgMinPlane = fgMinPlane; |
4d6aee34 |
106 | ((AliTRDpidESD &) p).fTrack = NULL; |
0d83b3a5 |
107 | |
b0f03c34 |
108 | } |
109 | |
b52cb1b6 |
110 | //_____________________________________________________________________________ |
14a65137 |
111 | Int_t AliTRDpidESD::MakePID(AliESDEvent * const event) |
b0f03c34 |
112 | { |
113 | // |
b52cb1b6 |
114 | // This function calculates the PID probabilities based on TRD signals |
b0f03c34 |
115 | // |
dab811d0 |
116 | // The method produces probabilities based on the charge |
117 | // and the position of the maximum time bin in each layer. |
118 | // The dE/dx information can be used as global charge or 2 to 3 |
720a0a16 |
119 | // slices. Check AliTRDCalPID and AliTRDCalPIDRefMaker for the actual |
dab811d0 |
120 | // implementation. |
121 | // |
122 | // Author |
123 | // Alex Bercuci (A.Bercuci@gsi.de) 2nd May 2007 |
c8ab4518 |
124 | // |
dab811d0 |
125 | |
0d83b3a5 |
126 | AliTRDcalibDB *calibration = AliTRDcalibDB::Instance(); |
127 | if (!calibration) { |
128 | AliErrorGeneral("AliTRDpidESD::MakePID()" |
129 | ,"No access to calibration data"); |
130 | return -1; |
131 | } |
132 | |
3a039a31 |
133 | // AliTRDrecoParam *rec = AliTRDReconstructor::RecoParam(); |
134 | // if (!rec) { |
135 | // AliErrorGeneral("AliTRDpidESD::MakePID()", "No TRD reco param."); |
136 | // return 0x0; |
137 | // } |
4ba1d6ae |
138 | |
0d83b3a5 |
139 | // Retrieve the CDB container class with the probability distributions |
140 | const AliTRDCalPID *pd = calibration->GetPIDObject(AliTRDpidUtil::kLQ); |
141 | if (!pd) { |
142 | AliErrorGeneral("AliTRDpidESD::MakePID()" |
143 | ,"No access to AliTRDCalPID"); |
144 | return -1; |
145 | } |
146 | |
147 | // Loop through all ESD tracks |
148 | Double_t p[10]; |
4d6aee34 |
149 | AliESDtrack *t = NULL; |
150 | Float_t dedx[AliTRDCalPID::kNSlicesLQ], dEdx; |
0d83b3a5 |
151 | Int_t timebin; |
152 | Float_t mom, length; |
153 | Int_t nPlanePID; |
154 | for (Int_t i=0; i<event->GetNumberOfTracks(); i++) { |
155 | t = event->GetTrack(i); |
156 | |
157 | // Check track |
158 | if(!CheckTrack(t)) continue; |
159 | |
160 | |
161 | // Skip tracks which have no TRD signal at all |
d8069611 |
162 | if (t->GetTRDsignal()<1.e-5) continue; |
0d83b3a5 |
163 | |
164 | // Loop over detector layers |
165 | mom = 0.; |
166 | length = 0.; |
167 | nPlanePID = 0; |
168 | for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) |
c8ab4518 |
169 | p[iSpecies] = 1./AliPID::kSPECIES; |
170 | |
0d83b3a5 |
171 | for (Int_t iLayer = 0; iLayer < AliTRDgeometry::kNlayer; iLayer++) { |
172 | // read data for track segment |
4d6aee34 |
173 | for(int iSlice=0; iSlice<AliTRDCalPID::kNSlicesLQ; iSlice++) |
0d83b3a5 |
174 | dedx[iSlice] = t->GetTRDslice(iLayer, iSlice); |
175 | dEdx = t->GetTRDslice(iLayer, -1); |
176 | timebin = t->GetTRDTimBin(iLayer); |
177 | |
178 | // check data |
179 | if ((dEdx <= 0.) || (timebin <= -1.)) continue; |
180 | |
181 | // retrive kinematic info for this track segment |
182 | if(!RecalculateTrackSegmentKine(t, iLayer, mom, length)){ |
183 | // information is not fully reliable especialy for length |
184 | // estimation. To be used in the future. |
185 | } |
186 | |
187 | // this track segment has fulfilled all requierments |
188 | nPlanePID++; |
189 | |
190 | // Get the probabilities for the different particle species |
191 | for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) { |
192 | p[iSpecies] *= pd->GetProbability(iSpecies, mom, dedx, length, iLayer); |
193 | //p[iSpecies] *= pd->GetProbabilityT(iSpecies, mom, timebin); |
194 | } |
195 | } |
196 | if(nPlanePID == 0) continue; |
197 | |
198 | // normalize probabilities |
199 | Double_t probTotal = 0.; |
200 | for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) probTotal += p[iSpecies]; |
201 | if(probTotal <= 0.){ |
202 | AliWarning(Form("The total probability (%e) over all species <= 0 in ESD track %d." |
203 | , probTotal, i)); |
204 | AliWarning("This may be caused by some error in reference data."); |
205 | AliWarning("Calculation continues but results might be corrupted."); |
206 | continue; |
207 | } |
208 | for(Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) p[iSpecies] /= probTotal; |
209 | |
210 | // book PID to the track |
211 | t->SetTRDpid(p); |
ed15ef4f |
212 | t->SetTRDntracklets(nPlanePID<<3); |
0d83b3a5 |
213 | } |
214 | |
215 | return 0; |
c8ab4518 |
216 | |
dab811d0 |
217 | } |
b52cb1b6 |
218 | |
dab811d0 |
219 | //_____________________________________________________________________________ |
14a65137 |
220 | Bool_t AliTRDpidESD::CheckTrack(AliESDtrack * const t) |
dab811d0 |
221 | { |
222 | // |
223 | // Check if track is eligible for PID calculations |
224 | // |
0d83b3a5 |
225 | |
226 | // Check the ESD track status |
227 | if (fgCheckTrackStatus) { |
228 | if (((t->GetStatus() & AliESDtrack::kTRDout ) == 0) && |
229 | ((t->GetStatus() & AliESDtrack::kTRDrefit) == 0)) return kFALSE; |
230 | } |
b52cb1b6 |
231 | |
0d83b3a5 |
232 | // Check for ESD kink tracks |
233 | if (fgCheckKinkStatus && (t->GetKinkIndex(0) != 0)) return kFALSE; |
b52cb1b6 |
234 | |
0d83b3a5 |
235 | return kTRUE; |
c8ab4518 |
236 | |
dab811d0 |
237 | } |
b52cb1b6 |
238 | |
dab811d0 |
239 | //_____________________________________________________________________________ |
14a65137 |
240 | Bool_t AliTRDpidESD::RecalculateTrackSegmentKine(AliESDtrack * const esd |
0d83b3a5 |
241 | , Int_t layer |
242 | , Float_t &mom |
243 | , Float_t &length) |
dab811d0 |
244 | { |
245 | // |
246 | // Retrive momentum "mom" and track "length" in TRD chamber from plane |
247 | // "plan" according to information stored in AliESDtrack "t". |
c6011b06 |
248 | // |
249 | // Origin |
250 | // Alex Bercuci (A.Bercuci@gsi.de) |
c8ab4518 |
251 | // |
dab811d0 |
252 | |
0d83b3a5 |
253 | const Float_t kAmHalfWidth = AliTRDgeometry::AmThick() / 2.; |
f162af62 |
254 | const Float_t kDrWidth = AliTRDgeometry::DrThick(); |
0d83b3a5 |
255 | const Float_t kTime0 = AliTRDgeometry::GetTime0(layer); |
256 | |
257 | // set initial length value to chamber height |
258 | length = 2 * kAmHalfWidth + kDrWidth; |
259 | |
260 | // retrive track's outer param |
261 | const AliExternalTrackParam *op = esd->GetOuterParam(); |
262 | if(!op){ |
263 | mom = esd->GetP(); |
264 | return kFALSE; |
265 | } |
266 | |
4d6aee34 |
267 | AliExternalTrackParam *param = NULL; |
0d83b3a5 |
268 | if(!fTrack){ |
269 | fTrack = new AliExternalTrackParam(*op); |
270 | param = fTrack; |
271 | } else param = new(fTrack) AliExternalTrackParam(*op); |
272 | |
273 | // retrive the magnetic field |
274 | Double_t xyz0[3]; |
275 | op->GetXYZ(xyz0); |
276 | Float_t field = AliTracker::GetBz(xyz0); // Bz in kG at point xyz0 |
277 | Double_t s, t; |
278 | |
279 | // propagate to chamber entrance |
280 | if(!param->PropagateTo(kTime0-kAmHalfWidth-kDrWidth, field)){ |
281 | mom = op->GetP(); |
282 | s = op->GetSnp(); |
283 | t = op->GetTgl(); |
bfd20868 |
284 | if (s < 1.) length /= TMath::Sqrt((1.-s)*(1.+s) / (1. + t*t)); |
0d83b3a5 |
285 | return kFALSE; |
286 | } |
287 | mom = param->GetP(); |
288 | s = param->GetSnp(); |
289 | t = param->GetTgl(); |
bfd20868 |
290 | if (s < 1.) length /= TMath::Sqrt((1.-s)*(1.+s) / (1. + t*t)); |
0d83b3a5 |
291 | |
292 | // check if track is crossing tracking sector by propagating to chamber exit- maybe is too much :) |
293 | Double_t alpha = param->GetAlpha(); |
294 | if(!param->PropagateTo(kTime0+kAmHalfWidth, field)) return kFALSE; |
295 | |
296 | // mark track segments which are crossing SM boundaries along chamber |
297 | if(TMath::Abs(alpha-param->GetAlpha())>.01) return kFALSE; |
298 | |
299 | return kTRUE; |
dab811d0 |
300 | |
c8ab4518 |
301 | } |