]>
Commit | Line | Data |
---|---|---|
6b91e8c0 | 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 | // class for light nuclei identification | |
17 | // author: Eulogio Serradilla <eulogio.serradilla@cern.ch> | |
18 | ||
19 | #include <Riostream.h> | |
20 | #include <AliExternalTrackParam.h> | |
21 | #include <TParticle.h> | |
22 | #include <AliESDtrack.h> | |
23 | #include <AliPID.h> | |
24 | #include <AliITSPIDResponse.h> | |
25 | #include <AliTPCPIDResponse.h> | |
26 | #include <TPDGCode.h> | |
5ad23888 | 27 | #include <AliAODMCParticle.h> |
6b91e8c0 | 28 | #include "AliLnID.h" |
29 | ||
30 | ClassImp(AliLnID) | |
31 | ||
32 | AliLnID::AliLnID() | |
33 | : TObject() | |
34 | , fPidProcedure(kBayes) | |
6b91e8c0 | 35 | , fRange(5.) |
78a09943 | 36 | , fZexp(2) |
6b91e8c0 | 37 | , fITSpid(0) |
38 | , fTPCpid(0) | |
39 | { | |
40 | // | |
41 | // Default constructor | |
42 | // | |
43 | fSpecies[0] = AliPID::kElectron; | |
44 | fSpecies[1] = AliPID::kMuon; | |
45 | fSpecies[2] = AliPID::kPion; | |
46 | fSpecies[3] = AliPID::kKaon; | |
47 | fSpecies[4] = AliPID::kProton; | |
48 | fSpecies[5] = AliPID::kDeuteron; | |
49 | fSpecies[6] = AliPID::kTriton; | |
50 | fSpecies[7] = AliPID::kHe3; | |
51 | fSpecies[8] = AliPID::kAlpha; | |
52 | ||
53 | // equal prior probabilities for all particle species | |
2e693567 | 54 | for(Int_t i=0; i<kSPECIES; ++i) fPrior[i]=1./kSPECIES; |
6b91e8c0 | 55 | |
56 | // ALEPH Bethe Bloch parameters for ITS | |
57 | Double_t param[] = { 0.13, 15.77/0.95, 4.95, 0.312, 2.14, 0.82}; | |
58 | fITSpid = new AliITSPIDResponse(¶m[0]); | |
59 | ||
60 | fTPCpid = new AliTPCPIDResponse(); | |
61 | fTPCpid->SetSigma(0.06,0); | |
62 | } | |
63 | ||
64 | AliLnID::AliLnID(const AliLnID& other) | |
65 | : TObject(other) | |
66 | , fPidProcedure(other.fPidProcedure) | |
6b91e8c0 | 67 | , fRange(other.fRange) |
78a09943 | 68 | , fZexp(other.fZexp) |
6b91e8c0 | 69 | , fITSpid(0) |
70 | , fTPCpid(0) | |
71 | { | |
72 | // | |
73 | // Copy constructor | |
74 | // | |
2e693567 | 75 | for(Int_t i=0; i < kSPECIES; ++i) |
6b91e8c0 | 76 | { |
77 | fSpecies[i] = other.fSpecies[i]; | |
78 | fPrior[i] = other.fPrior[i]; | |
79 | } | |
80 | ||
81 | fITSpid = new AliITSPIDResponse(*(other.fITSpid)); | |
82 | fTPCpid = new AliTPCPIDResponse(*(other.fTPCpid)); | |
83 | } | |
84 | ||
85 | AliLnID& AliLnID::operator=(const AliLnID& other) | |
86 | { | |
87 | // | |
88 | // Assignment operator | |
89 | // | |
90 | if(&other == this) return *this; // check for self-assignment | |
91 | ||
92 | fPidProcedure = other.fPidProcedure; | |
78a09943 | 93 | fRange = other.fRange; |
94 | fZexp = other.fZexp; | |
6b91e8c0 | 95 | |
96 | // deallocate memory | |
97 | delete fITSpid; | |
98 | delete fTPCpid; | |
99 | ||
100 | // copy | |
101 | TObject::operator=(other); | |
102 | ||
2e693567 | 103 | for(Int_t i=0; i < kSPECIES; ++i) |
6b91e8c0 | 104 | { |
105 | fSpecies[i] = other.fSpecies[i]; | |
106 | fPrior[i] = other.fPrior[i]; | |
107 | } | |
108 | ||
109 | fITSpid = new AliITSPIDResponse(*(other.fITSpid)); | |
110 | fTPCpid = new AliTPCPIDResponse(*(other.fTPCpid)); | |
111 | ||
112 | return *this; | |
113 | } | |
114 | ||
115 | void AliLnID::SetPriorProbabilities(Double_t e, Double_t mu, Double_t pi, Double_t k, Double_t p, Double_t d, Double_t t, Double_t he3, Double_t alpha) | |
116 | { | |
117 | // | |
118 | // Set prior probabilities | |
119 | // | |
120 | fPrior[0] = e; // electron | |
121 | fPrior[1] = mu; // muon | |
122 | fPrior[2] = pi; // pion | |
123 | fPrior[3] = k; // kaon | |
124 | fPrior[4] = p; // proton | |
125 | fPrior[5] = d; // deuteron | |
126 | fPrior[6] = t; // triton | |
127 | fPrior[7] = he3; // he3 | |
128 | fPrior[8] = alpha; // alpha | |
129 | } | |
130 | ||
131 | void AliLnID::SetPriorProbabilities(const Double_t* prob) | |
132 | { | |
133 | // | |
134 | // Set prior probabilities | |
135 | // | |
2e693567 | 136 | for(Int_t i=0; i < kSPECIES; ++i) fPrior[i] = prob[i]; |
6b91e8c0 | 137 | } |
138 | ||
139 | void AliLnID::SetITSBetheBlochParams(const Double_t* par, Double_t res) | |
140 | { | |
141 | // | |
142 | // Set ALEPH Bethe Bloch parameters for ITS | |
143 | // | |
144 | delete fITSpid; | |
145 | Double_t param[] = { res, par[0], par[1], par[2], par[3], par[4]}; | |
146 | fITSpid = new AliITSPIDResponse(¶m[0]); | |
147 | } | |
148 | ||
149 | void AliLnID::SetTPCBetheBlochParams(const Double_t* par, Double_t mip, Double_t res) | |
150 | { | |
151 | // | |
152 | // Set ALEPH Bethe Bloch parameters for TPC | |
153 | // | |
154 | fTPCpid->SetMip(mip); | |
155 | fTPCpid->SetSigma(res,0); | |
156 | fTPCpid->SetBetheBlochParameters(par[0], par[1], par[2], par[3], par[4]); | |
157 | } | |
158 | ||
159 | void AliLnID::SetTPCBetheBlochParams(Double_t c0, Double_t c1, Double_t c2, Double_t c3, Double_t c4, Double_t mip, Double_t res) | |
160 | { | |
161 | // | |
162 | // Set ALEPH Bethe Bloch parameters for TPC | |
163 | // | |
164 | fTPCpid->SetMip(mip); | |
165 | fTPCpid->SetSigma(res,0); | |
166 | fTPCpid->SetBetheBlochParameters(c0, c1, c2, c3, c4); | |
167 | } | |
168 | ||
169 | AliLnID::~AliLnID() | |
170 | { | |
171 | // | |
172 | // Default destructor | |
173 | // | |
174 | delete fITSpid; | |
175 | delete fTPCpid; | |
176 | } | |
177 | ||
178 | Int_t AliLnID::GetPID(const TParticle* p) const | |
179 | { | |
180 | // | |
181 | // Montecarlo PID | |
5ad23888 | 182 | // |
183 | return this->GetPID(p->GetPdgCode()); | |
184 | } | |
185 | ||
186 | Int_t AliLnID::GetPID(const AliAODMCParticle* p) const | |
187 | { | |
188 | // | |
189 | // Montecarlo PID | |
190 | // | |
191 | return this->GetPID(p->GetPdgCode()); | |
192 | } | |
193 | ||
194 | Int_t AliLnID::GetPID(Int_t pdgCode) const | |
195 | { | |
196 | // | |
197 | // Montecarlo PID | |
6b91e8c0 | 198 | // |
199 | enum { kDeuteron=1000010020, kTriton=1000010030, kHelium3=1000020030, kAlpha=1000020040 }; | |
200 | ||
5ad23888 | 201 | switch(TMath::Abs(pdgCode)) |
6b91e8c0 | 202 | { |
203 | case kElectron: return AliPID::kElectron; | |
204 | case kMuonMinus: return AliPID::kMuon; | |
205 | case kPiPlus: return AliPID::kPion; | |
206 | case kKPlus: return AliPID::kKaon; | |
207 | case kProton: return AliPID::kProton; | |
208 | case kDeuteron: return AliPID::kDeuteron; | |
209 | case kTriton: return AliPID::kTriton; | |
210 | case kHelium3: return AliPID::kHe3; | |
211 | case kAlpha: return AliPID::kAlpha; | |
212 | } | |
213 | ||
214 | return -1; | |
215 | } | |
216 | ||
217 | Int_t AliLnID::GetPID(Int_t pidCode, Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t pTPC, Double_t dEdxTPC, Int_t nPointsTPC, Double_t pTOF, Double_t beta, Double_t nSigITS, Double_t nSigTPC, Double_t nSigTOF) const | |
218 | { | |
219 | // | |
f4d6dd11 | 220 | // PID according to the selected procedure |
6b91e8c0 | 221 | // |
222 | if(fPidProcedure == kBayes) | |
223 | { | |
224 | return this->GetBayesPID(pITS, dEdxITS, nPointsITS, pTPC, dEdxTPC, nPointsTPC, pTOF, beta); | |
225 | } | |
226 | else if(fPidProcedure == kMaxLikelihood) | |
227 | { | |
228 | return this->GetMaxLikelihoodPID(pITS, dEdxITS, nPointsITS, pTPC, dEdxTPC, nPointsTPC, pTOF, beta); | |
229 | } | |
5ad23888 | 230 | else if(fPidProcedure == kITS) |
231 | { | |
232 | return this->GetITSpid(pidCode, pITS, dEdxITS, nPointsITS, nSigITS); | |
233 | } | |
6b91e8c0 | 234 | else if(fPidProcedure == kTPC) |
235 | { | |
236 | return this->GetTPCpid(pidCode, pTPC, dEdxTPC, nPointsTPC, nSigTPC); | |
237 | } | |
238 | else if(fPidProcedure == kITSTPC) | |
239 | { | |
240 | return this->GetITSTPCpid(pidCode, pITS, dEdxITS, nPointsITS, nSigITS, pTPC, dEdxTPC, nPointsTPC, nSigTPC); | |
241 | } | |
242 | else if(fPidProcedure == kTPCTOF) | |
243 | { | |
244 | return this->GetTPCTOFpid(pidCode, pTPC, dEdxTPC, nPointsTPC, nSigTPC, pTOF, beta, nSigTOF); | |
245 | } | |
246 | ||
247 | return -1; | |
248 | } | |
249 | ||
5ad23888 | 250 | Int_t AliLnID::GetITSpid(Int_t pidCode, Double_t pITS, Double_t dEdxITS, Double_t nPointsITS, Double_t nSigmaITS) const |
251 | { | |
252 | // | |
253 | // Check if particle with the given pid code is within | |
254 | // +/- nSigma around the expected dEdx in the ITS | |
255 | // | |
256 | if( this->GetITSmatch(pidCode, pITS, dEdxITS, static_cast<Int_t>(nPointsITS), nSigmaITS)) return pidCode; | |
257 | ||
258 | return -1; | |
259 | } | |
260 | ||
6b91e8c0 | 261 | Int_t AliLnID::GetTPCpid(Int_t pidCode, Double_t pTPC, Double_t dEdxTPC, Double_t nPointsTPC, Double_t nSigmaTPC) const |
262 | { | |
263 | // | |
264 | // Check if particle with the given pid code is within | |
265 | // +/- nSigma around the expected dEdx in the TPC | |
266 | // | |
267 | if( this->GetTPCmatch(pidCode, pTPC, dEdxTPC, nPointsTPC, nSigmaTPC)) return pidCode; | |
268 | ||
269 | return -1; | |
270 | } | |
271 | ||
272 | Int_t AliLnID::GetTPCTOFpid(Int_t pidCode, Double_t pTPC, Double_t dEdxTPC, Double_t nPointsTPC, Double_t nSigmaTPC, Double_t pTOF, Double_t beta, Double_t nSigmaTOF) const | |
273 | { | |
274 | // | |
275 | // Check if particle with the given pid code is within | |
276 | // +/- nSigmaTPC around the expected dEdx in the TPC | |
277 | // AND +/- nSigmaTOF around the expected beta in the TOF (when available) | |
278 | // | |
279 | if( beta > 0 ) | |
280 | { | |
281 | if( this->GetTPCmatch(pidCode, pTPC, dEdxTPC, nPointsTPC, nSigmaTPC) | |
282 | && this->GetTOFmatch(pidCode, pTOF, beta, nSigmaTOF)) | |
283 | { | |
284 | return pidCode; | |
285 | } | |
286 | } | |
287 | else | |
288 | { | |
289 | if( this->GetTPCmatch(pidCode, pTPC, dEdxTPC, nPointsTPC, nSigmaTPC)) | |
290 | { | |
291 | return pidCode; | |
292 | } | |
293 | } | |
294 | ||
295 | return -1; | |
296 | } | |
297 | ||
298 | Int_t AliLnID::GetITSTPCpid(Int_t pidCode, Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t nSigmaITS, Double_t pTPC, Double_t dEdxTPC, Double_t nPointsTPC, Double_t nSigmaTPC) const | |
299 | { | |
300 | // | |
301 | // Check if particle with the given pid code is within | |
302 | // +/- nSigmaITS around the expected dEdx in the ITS | |
303 | // AND +/- nSigmaTPC around the expected dEdx in the TPC | |
304 | // | |
305 | if( this->GetITSmatch(pidCode, pITS, dEdxITS, nPointsITS, nSigmaITS) | |
306 | && this->GetTPCmatch(pidCode, pTPC, dEdxTPC, nPointsTPC, nSigmaTPC)) | |
307 | { | |
308 | return pidCode; | |
309 | } | |
310 | ||
311 | return -1; | |
312 | } | |
313 | ||
314 | Int_t AliLnID::GetIndexOfMaxValue(const Double_t* w) const | |
315 | { | |
316 | // | |
2e693567 | 317 | // Index with maximum value in the array of size kSPECIES |
6b91e8c0 | 318 | // |
319 | Double_t wmax= 0; | |
320 | Int_t imax = -1; | |
2e693567 | 321 | for(Int_t i=0; i < kSPECIES; ++i) |
6b91e8c0 | 322 | { |
323 | if(w[i] > wmax) | |
324 | { | |
325 | wmax = w[i]; | |
326 | imax = i; | |
327 | } | |
328 | } | |
329 | ||
330 | return imax; | |
331 | } | |
332 | ||
333 | Bool_t AliLnID::GetLikelihood(Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t pTPC, Double_t dEdxTPC, Int_t nPointsTPC, Double_t pTOF, Double_t beta, Double_t* r) const | |
334 | { | |
335 | // | |
336 | // Fill r array with the combined likelihood for ITS, TPC and TOF when possible | |
337 | // return 1 if success | |
338 | // | |
2e693567 | 339 | Double_t its[kSPECIES]; |
340 | Double_t tpc[kSPECIES]; | |
341 | Double_t tof[kSPECIES]; | |
6b91e8c0 | 342 | |
343 | Bool_t itsPid = this->GetITSlikelihood(pITS, dEdxITS, nPointsITS, its); | |
344 | Bool_t tpcPid = this->GetTPClikelihood(pTPC, dEdxTPC, nPointsTPC, tpc); | |
345 | Bool_t tofPid = this->GetTOFlikelihood(pTOF, beta, tof); | |
346 | ||
347 | if(!itsPid && !tpcPid && !tofPid) return kFALSE; | |
348 | ||
349 | // Combine detector responses | |
350 | ||
2e693567 | 351 | for(Int_t i=0; i<kSPECIES; ++i) r[i]=1.; |
6b91e8c0 | 352 | |
353 | if(itsPid) | |
354 | { | |
2e693567 | 355 | for(Int_t i=0; i < kSPECIES; ++i) r[i] *= its[i]; |
6b91e8c0 | 356 | } |
357 | if(tpcPid) | |
358 | { | |
2e693567 | 359 | for(Int_t i=0; i < kSPECIES; ++i) r[i] *= tpc[i]; |
6b91e8c0 | 360 | } |
361 | if(tofPid) | |
362 | { | |
2e693567 | 363 | for(Int_t i=0; i < kSPECIES; ++i) r[i] *= tof[i]; |
6b91e8c0 | 364 | } |
365 | ||
366 | return kTRUE; | |
367 | } | |
368 | ||
369 | Int_t AliLnID::GetMaxLikelihoodPID(Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t pTPC, Double_t dEdxTPC, Int_t nPointsTPC, Double_t pTOF, Double_t beta) const | |
370 | { | |
371 | // | |
372 | // Maximum likelihood principle | |
373 | // | |
2e693567 | 374 | Double_t r[kSPECIES]; |
6b91e8c0 | 375 | |
376 | if(!this->GetLikelihood(pITS, dEdxITS, nPointsITS, pTPC, dEdxTPC, nPointsTPC, pTOF, beta, r)) return -1; | |
377 | ||
378 | Int_t imax = this->GetIndexOfMaxValue(r); | |
379 | ||
380 | if(imax < 0) return -1; | |
381 | ||
382 | return fSpecies[imax]; | |
383 | } | |
384 | ||
385 | Int_t AliLnID::GetBayesPID(Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t pTPC, Double_t dEdxTPC, Int_t nPointsTPC, Double_t pTOF, Double_t beta) const | |
386 | { | |
387 | // | |
388 | // Bayesian inference | |
389 | // | |
2e693567 | 390 | Double_t r[kSPECIES]; |
6b91e8c0 | 391 | |
392 | if(!this->GetLikelihood(pITS, dEdxITS, nPointsITS, pTPC, dEdxTPC, nPointsTPC, pTOF, beta, r)) return -1; | |
393 | ||
394 | // Bayes' rule | |
395 | ||
2e693567 | 396 | Double_t w[kSPECIES] = {0}; |
397 | for(Int_t i = 0; i < kSPECIES; ++i) w[i] = r[i]*fPrior[i]; // no need to normalize | |
6b91e8c0 | 398 | |
399 | Int_t imax = this->GetIndexOfMaxValue(w); | |
400 | ||
401 | if(imax < 0) return -1; | |
402 | ||
403 | return fSpecies[imax]; | |
404 | } | |
405 | ||
406 | Bool_t AliLnID::GetITSlikelihood(Double_t pITS, Double_t dEdx, Int_t nPointsITS, Double_t* r) const | |
407 | { | |
408 | // | |
409 | // Probability of dEdx in the ITS for each particle species. | |
410 | // Adapted from STEER/ESD/AliESDpid.cxx | |
411 | // (truncated mean method) | |
412 | // | |
413 | if( pITS <= 0) return kFALSE; | |
414 | if( dEdx < 1.) return kFALSE; | |
415 | if( nPointsITS < 3) return kFALSE; | |
416 | ||
417 | Bool_t mismatch = kTRUE; | |
418 | ||
419 | Double_t sum = 0; | |
2e693567 | 420 | for (Int_t i=0; i<kSPECIES; ++i) |
6b91e8c0 | 421 | { |
422 | Double_t mass = AliPID::ParticleMass(fSpecies[i]); | |
2e693567 | 423 | Double_t p = (fSpecies[i] > AliPID::kTriton) ? 2.*pITS : pITS; // correct by Z |
424 | Double_t expDedx = (fSpecies[i] > AliPID::kTriton) ? 4.*fITSpid->BetheAleph(p, mass) : fITSpid->BetheAleph(p, mass); // correct by Z^2 | |
6b91e8c0 | 425 | Double_t sigma = fITSpid->GetResolution(expDedx, nPointsITS); |
426 | ||
6b91e8c0 | 427 | if (TMath::Abs(dEdx - expDedx) > fRange*sigma) |
428 | { | |
429 | r[i]=TMath::Exp(-0.5*fRange*fRange)/sigma; | |
430 | } | |
431 | else | |
432 | { | |
433 | r[i]=TMath::Exp(-0.5*(dEdx-expDedx)*(dEdx-expDedx)/(sigma*sigma))/sigma; | |
434 | mismatch = kFALSE; | |
435 | } | |
436 | ||
437 | sum += r[i]; | |
438 | } | |
439 | ||
440 | if(sum <= 0. || mismatch) | |
441 | { | |
442 | return kFALSE; | |
443 | } | |
444 | ||
2e693567 | 445 | for(Int_t i=0; i < kSPECIES; ++i) r[i] /= sum; |
6b91e8c0 | 446 | |
447 | return kTRUE; | |
448 | } | |
449 | ||
77dac0a6 | 450 | Bool_t AliLnID::GetTPClikelihood(Double_t pTPC, Double_t dEdx, Int_t /*nPointsTPC*/, Double_t* r) const |
6b91e8c0 | 451 | { |
452 | // | |
453 | // Probability of dEdx for each particle species in the TPC. | |
454 | // Adapted from STEER/ESD/AliESDpid.cxx | |
455 | // | |
456 | if( pTPC <= 0) return kFALSE; | |
457 | if( dEdx < 1.) return kFALSE; | |
458 | ||
459 | Bool_t mismatch = kTRUE; | |
460 | ||
461 | Double_t sum = 0; | |
2e693567 | 462 | for(Int_t i=0; i < kSPECIES; ++i) |
6b91e8c0 | 463 | { |
77dac0a6 | 464 | Double_t m = AliPID::ParticleMass(fSpecies[i]); |
2e693567 | 465 | Double_t p = (fSpecies[i] > AliPID::kTriton) ? 2.*pTPC : pTPC; // correct by Z |
78a09943 | 466 | Double_t expDedx = (fSpecies[i] > AliPID::kTriton) ? TMath::Power(2.,fZexp)*fTPCpid->Bethe(p/m) : fTPCpid->Bethe(p/m); // correct by Z^X (as in AliTPCPIDResponse) |
77dac0a6 | 467 | Double_t sigma = fTPCpid->GetRes0()*expDedx; |
6b91e8c0 | 468 | |
6b91e8c0 | 469 | if(TMath::Abs(dEdx - expDedx) > fRange*sigma) |
470 | { | |
471 | r[i] = TMath::Exp(-0.5*fRange*fRange)/sigma; | |
472 | } | |
473 | else | |
474 | { | |
475 | r[i] = TMath::Exp(-0.5*(dEdx-expDedx)*(dEdx-expDedx)/(sigma*sigma))/sigma; | |
476 | mismatch=kFALSE; | |
477 | } | |
478 | ||
479 | sum += r[i]; | |
480 | } | |
481 | ||
482 | if(sum <= 0. || mismatch) | |
483 | { | |
484 | return kFALSE; | |
485 | } | |
486 | ||
2e693567 | 487 | for(Int_t i=0; i < kSPECIES; ++i) r[i] /= sum; |
6b91e8c0 | 488 | |
489 | return kTRUE; | |
490 | } | |
491 | ||
492 | Bool_t AliLnID::GetTOFlikelihood(Double_t pTOF, Double_t beta, Double_t* r) const | |
493 | { | |
494 | // | |
495 | // Probability of beta for each particle species | |
496 | // | |
497 | if( pTOF <= 0) return kFALSE; | |
498 | if( beta <= 0) return kFALSE; | |
499 | ||
500 | Double_t mismatch = kTRUE; | |
501 | ||
502 | Double_t sum = 0; | |
2e693567 | 503 | for(Int_t i=0; i < kSPECIES; ++i) |
6b91e8c0 | 504 | { |
505 | Double_t mass = AliPID::ParticleMass(fSpecies[i]); | |
2e693567 | 506 | Double_t p = (fSpecies[i] > AliPID::kTriton) ? 2.*pTOF : pTOF; // correct by Z |
6b91e8c0 | 507 | Double_t expBeta = this->Beta(p,mass); |
508 | Double_t sigma = this->GetBetaExpectedSigma(p,mass); | |
509 | ||
510 | if(TMath::Abs(beta-expBeta) > fRange*sigma) | |
511 | { | |
512 | r[i] = TMath::Exp(-0.5*fRange*fRange)/sigma; | |
513 | } | |
514 | else | |
515 | { | |
516 | r[i] = TMath::Exp(-0.5*(beta-expBeta)*(beta-expBeta)/(sigma*sigma))/sigma; | |
517 | mismatch = kFALSE; | |
518 | } | |
519 | ||
520 | sum += r[i]; | |
521 | } | |
522 | ||
523 | if(sum <= 0. || mismatch) | |
524 | { | |
525 | return kFALSE; | |
526 | } | |
527 | ||
2e693567 | 528 | for(Int_t i=0; i < kSPECIES; ++i) r[i] /= sum; |
6b91e8c0 | 529 | |
530 | return kTRUE; | |
531 | } | |
532 | ||
533 | Double_t AliLnID::Beta(Double_t p, Double_t m) const | |
534 | { | |
535 | // | |
536 | // Expected beta for mass hypothesis m | |
537 | // | |
538 | return p/TMath::Sqrt(p*p+m*m); | |
539 | } | |
540 | ||
541 | Double_t AliLnID::GetBetaExpectedSigma(Double_t p, Double_t m) const | |
542 | { | |
543 | // | |
544 | // Expected sigma for the given mass hypothesis | |
545 | // | |
546 | const Double_t kC0 = 0.0131203; | |
547 | const Double_t kC1 = 0.00670148; | |
548 | ||
549 | Double_t kappa = kC0*m*m/(p*(p*p+m*m)) + kC1; | |
550 | return kappa*Beta(p,m); | |
551 | } | |
552 | ||
6b91e8c0 | 553 | Bool_t AliLnID::GetITSmatch(Int_t pid, Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t nSigma) const |
554 | { | |
555 | // | |
556 | // Check if the signal is less than nSigma from the expected ITS dEdx | |
557 | // | |
558 | Double_t mass = AliPID::ParticleMass(pid); | |
2e693567 | 559 | Double_t p = (pid > AliPID::kTriton) ? 2.*pITS : pITS; // correct by Z |
560 | Double_t expDedx = (pid > AliPID::kTriton) ? 4.*fITSpid->BetheAleph(p, mass) : fITSpid->BetheAleph(p, mass); // correct by Z^2 | |
6b91e8c0 | 561 | Double_t sigma = fITSpid->GetResolution(expDedx, nPointsITS); |
562 | ||
6b91e8c0 | 563 | if(TMath::Abs(dEdxITS-expDedx) < nSigma*sigma) |
564 | { | |
565 | return kTRUE; | |
566 | } | |
567 | ||
568 | return kFALSE; | |
569 | } | |
570 | ||
77dac0a6 | 571 | Bool_t AliLnID::GetTPCmatch(Int_t pid, Double_t pTPC, Double_t dEdxTPC, Double_t /*nPointsTPC*/, Double_t nSigma) const |
6b91e8c0 | 572 | { |
573 | // | |
574 | // Check if the signal is less than nSigma from the expected TPC dEdx | |
575 | // | |
77dac0a6 | 576 | Double_t m = AliPID::ParticleMass(pid); |
2e693567 | 577 | Double_t p = (pid > AliPID::kTriton) ? 2.*pTPC : pTPC; // correct by Z |
78a09943 | 578 | Double_t expDedx = (pid > AliPID::kTriton) ? TMath::Power(2.,fZexp)*fTPCpid->Bethe(p/m) : fTPCpid->Bethe(p/m); // correct by Z^X (as in AliTPCPIDResponse) |
77dac0a6 | 579 | Double_t sigma = fTPCpid->GetRes0()*expDedx; |
6b91e8c0 | 580 | |
6b91e8c0 | 581 | if(TMath::Abs(dEdxTPC-expDedx) < nSigma*sigma) |
582 | { | |
583 | return kTRUE; | |
584 | } | |
585 | ||
586 | return kFALSE; | |
587 | } | |
588 | ||
589 | Bool_t AliLnID::GetTOFmatch(Int_t pid, Double_t pTOF, Double_t beta, Double_t nSigma) const | |
590 | { | |
591 | // | |
592 | // Check if the signal is less than nSigma from the expected velocity | |
593 | // | |
594 | Double_t mass = AliPID::ParticleMass(pid); | |
2e693567 | 595 | Double_t p = (pid > AliPID::kTriton) ? 2.*pTOF : pTOF; |
6b91e8c0 | 596 | Double_t expBeta = this->Beta(p, mass); |
597 | Double_t sigma = this->GetBetaExpectedSigma(p, mass); | |
598 | ||
599 | if(TMath::Abs(beta-expBeta) < nSigma*sigma) | |
600 | { | |
601 | return kTRUE; | |
602 | } | |
603 | ||
604 | return kFALSE; | |
605 | } | |
606 | ||
6b91e8c0 | 607 | Bool_t AliLnID::IsITSTPCmismatch(Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t pTPC, Double_t dEdxTPC, Int_t nPointsTPC, Double_t nSigma) const |
608 | { | |
609 | // | |
610 | // Check track TPC mismatch with ITS | |
611 | // | |
2e693567 | 612 | for(Int_t i=0; i<kSPECIES; ++i) |
6b91e8c0 | 613 | { |
614 | if(this->GetTPCmatch(fSpecies[i], pTPC, dEdxTPC, nPointsTPC, nSigma) && | |
615 | this->GetITSmatch(fSpecies[i], pITS, dEdxITS, nPointsITS, 5.)) | |
616 | { | |
617 | return kFALSE; | |
618 | } | |
619 | } | |
620 | ||
621 | return kTRUE; | |
622 | } | |
623 | ||
624 | Bool_t AliLnID::IsITSTOFmismatch(Double_t pITS, Double_t dEdxITS, Int_t nPointsITS, Double_t pTOF, Double_t beta, Double_t nSigma) const | |
625 | { | |
626 | // | |
627 | // Check track TOF mismatch with ITS | |
628 | // | |
2e693567 | 629 | for(Int_t i=0; i<kSPECIES; ++i) |
6b91e8c0 | 630 | { |
631 | if(this->GetTOFmatch(fSpecies[i], pTOF, beta, nSigma) && | |
632 | this->GetITSmatch(fSpecies[i], pITS, dEdxITS, nPointsITS, 3.)) | |
633 | { | |
634 | return kFALSE; | |
635 | } | |
636 | } | |
637 | ||
638 | return kTRUE; | |
639 | } | |
640 | ||
641 | Bool_t AliLnID::IsTPCTOFmismatch(Double_t pTPC, Double_t dEdxTPC, Int_t nPointsTPC, Double_t pTOF, Double_t beta, Double_t nSigma) const | |
642 | { | |
643 | // | |
644 | // Check track TOF mismatch with TPC | |
645 | // | |
2e693567 | 646 | for(Int_t i=0; i<kSPECIES; ++i) |
6b91e8c0 | 647 | { |
648 | if(this->GetTOFmatch(fSpecies[i], pTOF, beta, nSigma) && | |
649 | this->GetTPCmatch(fSpecies[i], pTPC, dEdxTPC, nPointsTPC, 3.)) | |
650 | { | |
651 | return kFALSE; | |
652 | } | |
653 | } | |
654 | ||
655 | return kTRUE; | |
656 | } |