]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliPID.cxx
Adding the light nuclei as requested in Savannah ticket #72834 (E. Serradilla)
[u/mrichter/AliRoot.git] / STEER / AliPID.cxx
CommitLineData
304864ab 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/* $Id$ */
17
18///////////////////////////////////////////////////////////////////////////////
19// //
20// particle id probability densities //
21// //
22// The AliPID class stores the probability densities for the different //
23// particle type hypotheses electron, muon, pion, kaon, proton, photon, //
24// pi0, neutron, K0 and electron conversion. These probability densities //
25// are determined from the detector response functions. //
26// The * and *= operators are overloaded for AliPID to combine the PIDs //
27// from different detectors. //
28// //
29// The Bayesian probability to be a particle of a given type can be //
30// calculated from the probability densities, if the a priori probabilities //
31// (or abundences, concentrations) of particle species are known. These //
32// priors can be given as argument to the GetProbability or GetMostProbable //
33// method or they can be set globally by calling the static method //
34// SetPriors(). //
35// //
36// The implementation of this class is based on the note ... //
37// by Iouri Belikov and Karel Safarik. //
38// //
39///////////////////////////////////////////////////////////////////////////////
40
a9bbb414 41#include <TClass.h>
42#include <TDatabasePDG.h>
43#include <TPDGCode.h>
304864ab 44
304864ab 45#include "AliLog.h"
a9bbb414 46#include "AliPID.h"
304864ab 47
90e48c0c 48#define M(PID) TDatabasePDG::Instance()->GetParticle(fgkParticleCode[(PID)])->Mass()
304864ab 49
50ClassImp(AliPID)
51
288a4024 52const char* AliPID::fgkParticleName[AliPID::kSPECIESN+AliPID::kSPECIESLN+1] = {
304864ab 53 "electron",
54 "muon",
55 "pion",
56 "kaon",
57 "proton",
58 "photon",
59 "pi0",
60 "neutron",
61 "kaon0",
62 "eleCon",
288a4024 63 "deuteron",
64 "triton",
65 "helium-3",
66 "alpha",
304864ab 67 "unknown"
68};
69
288a4024 70const char* AliPID::fgkParticleShortName[AliPID::kSPECIESN+AliPID::kSPECIESLN+1] = {
91dbd0dc 71 "e",
72 "mu",
73 "pi",
74 "K",
75 "p",
76 "photon",
77 "pi0",
78 "n",
79 "K0",
80 "eleCon",
288a4024 81 "d",
82 "t",
83 "he3",
84 "alpha",
91dbd0dc 85 "unknown"
86};
87
288a4024 88const char* AliPID::fgkParticleLatexName[AliPID::kSPECIESN+AliPID::kSPECIESLN+1] = {
91dbd0dc 89 "e",
90 "#mu",
91 "#pi",
92 "K",
93 "p",
94 "#gamma",
95 "#pi_{0}",
96 "n",
97 "K_{0}",
98 "eleCon",
288a4024 99 "d",
100 "t",
101 "he3",
102 "#alpha",
91dbd0dc 103 "unknown"
104};
105
288a4024 106const Int_t AliPID::fgkParticleCode[AliPID::kSPECIESN+AliPID::kSPECIESLN+1] = {
304864ab 107 ::kElectron,
108 ::kMuonMinus,
109 ::kPiPlus,
110 ::kKPlus,
111 ::kProton,
112 ::kGamma,
113 ::kPi0,
114 ::kNeutron,
115 ::kK0,
0133aa88 116 ::kElectron,
288a4024 117 1000010020,
118 1000010030,
119 1000020030,
120 1000020040,
304864ab 121 0
122};
123
288a4024 124/*const*/ Float_t AliPID::fgkParticleMass[AliPID::kSPECIESN+AliPID::kSPECIESLN+1] = {
125 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
a9bbb414 126 /*
90e48c0c 127 M(kElectron), // electron
128 M(kMuon), // muon
129 M(kPion), // pion
130 M(kKaon), // kaon
131 M(kProton), // proton
132 M(kPhoton), // photon
133 M(kPi0), // pi0
134 M(kNeutron), // neutron
135 M(kKaon0), // kaon0
136 M(kEleCon), // electron conversion
288a4024 137 M(kDeuteron), // deuteron
138 M(kTriton), // triton
139 M(kHe3), // he3
140 M(kAlpha), // alpha
90e48c0c 141 0.00000 // unknown
a9bbb414 142 */
90e48c0c 143};
304864ab 144
145Double_t AliPID::fgPrior[kSPECIESN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
146
147
148//_______________________________________________________________________
90e48c0c 149AliPID::AliPID() :
150 TObject(),
151 fCharged(0)
304864ab 152{
a9bbb414 153 //
154 // Default constructor
155 //
156 Init();
157 // set default values (= equal probabilities)
158 for (Int_t i = 0; i < kSPECIESN; i++)
304864ab 159 fProbDensity[i] = 1./kSPECIESN;
304864ab 160}
161
162//_______________________________________________________________________
90e48c0c 163AliPID::AliPID(const Double_t* probDensity, Bool_t charged) :
164 TObject(),
165 fCharged(charged)
304864ab 166{
90e48c0c 167 //
a9bbb414 168 // Standard constructor
90e48c0c 169 //
a9bbb414 170 Init();
171 // set given probability densities
172 for (Int_t i = 0; i < kSPECIES; i++)
304864ab 173 fProbDensity[i] = probDensity[i];
a9bbb414 174
175 for (Int_t i = kSPECIES; i < kSPECIESN; i++)
304864ab 176 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
304864ab 177}
178
179//_______________________________________________________________________
90e48c0c 180AliPID::AliPID(const Float_t* probDensity, Bool_t charged) :
181 TObject(),
182 fCharged(charged)
304864ab 183{
90e48c0c 184 //
a9bbb414 185 // Standard constructor
90e48c0c 186 //
a9bbb414 187 Init();
188 // set given probability densities
189 for (Int_t i = 0; i < kSPECIES; i++)
304864ab 190 fProbDensity[i] = probDensity[i];
a9bbb414 191
192 for (Int_t i = kSPECIES; i < kSPECIESN; i++)
304864ab 193 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
304864ab 194}
195
196//_______________________________________________________________________
197AliPID::AliPID(const AliPID& pid) :
198 TObject(pid),
199 fCharged(pid.fCharged)
200{
90e48c0c 201 //
202 // copy constructor
203 //
a9bbb414 204 // We do not call init here, MUST already be done
205 for (Int_t i = 0; i < kSPECIESN; i++)
304864ab 206 fProbDensity[i] = pid.fProbDensity[i];
304864ab 207}
208
3088e2dd 209//_______________________________________________________________________
210void AliPID::SetProbabilities(const Double_t* probDensity, Bool_t charged)
211{
212 //
213 // Set the probability densities
214 //
215 for (Int_t i = 0; i < kSPECIES; i++)
216 fProbDensity[i] = probDensity[i];
217
218 for (Int_t i = kSPECIES; i < kSPECIESN; i++)
219 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
220}
221
304864ab 222//_______________________________________________________________________
223AliPID& AliPID::operator = (const AliPID& pid)
224{
225// assignment operator
226
227 fCharged = pid.fCharged;
228 for (Int_t i = 0; i < kSPECIESN; i++) {
229 fProbDensity[i] = pid.fProbDensity[i];
230 }
231 return *this;
232}
233
a9bbb414 234//_______________________________________________________________________
235void AliPID::Init()
236{
237 //
238 // Initialise the masses
239 //
240 // Initialise only once...
288a4024 241 if(!fgkParticleMass[0])
242 for (Int_t i = 0; i < kSPECIESN + kSPECIESLN; i++)
374ef46b 243 fgkParticleMass[i] = M(i);
a9bbb414 244}
304864ab 245
246//_____________________________________________________________________________
247Double_t AliPID::GetProbability(EParticleType iType,
248 const Double_t* prior) const
249{
a9bbb414 250 //
251 // Get the probability to be a particle of type "iType"
252 // assuming the a priori probabilities "prior"
253 //
304864ab 254 Double_t sum = 0.;
255 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
256 for (Int_t i = 0; i < nSpecies; i++) {
257 sum += fProbDensity[i] * prior[i];
258 }
259 if (sum <= 0) {
260 AliError("Invalid probability densities or priors");
261 return -1;
262 }
263 return fProbDensity[iType] * prior[iType] / sum;
264}
265
266//_____________________________________________________________________________
267Double_t AliPID::GetProbability(EParticleType iType) const
268{
269// get the probability to be a particle of type "iType"
270// assuming the globaly set a priori probabilities
271
272 return GetProbability(iType, fgPrior);
273}
274
275//_____________________________________________________________________________
276void AliPID::GetProbabilities(Double_t* probabilities,
277 const Double_t* prior) const
278{
279// get the probabilities to be a particle of given type
280// assuming the a priori probabilities "prior"
281
282 Double_t sum = 0.;
283 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
284 for (Int_t i = 0; i < nSpecies; i++) {
285 sum += fProbDensity[i] * prior[i];
286 }
287 if (sum <= 0) {
288 AliError("Invalid probability densities or priors");
289 for (Int_t i = 0; i < nSpecies; i++) probabilities[i] = -1;
290 return;
291 }
292 for (Int_t i = 0; i < nSpecies; i++) {
293 probabilities[i] = fProbDensity[i] * prior[i] / sum;
294 }
295}
296
297//_____________________________________________________________________________
298void AliPID::GetProbabilities(Double_t* probabilities) const
299{
300// get the probabilities to be a particle of given type
301// assuming the globaly set a priori probabilities
302
303 GetProbabilities(probabilities, fgPrior);
304}
305
306//_____________________________________________________________________________
307AliPID::EParticleType AliPID::GetMostProbable(const Double_t* prior) const
308{
309// get the most probable particle id hypothesis
310// assuming the a priori probabilities "prior"
311
312 Double_t max = 0.;
313 EParticleType id = kPion;
314 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
315 for (Int_t i = 0; i < nSpecies; i++) {
316 Double_t prob = fProbDensity[i] * prior[i];
317 if (prob > max) {
318 max = prob;
319 id = EParticleType(i);
320 }
321 }
322 if (max == 0) {
323 AliError("Invalid probability densities or priors");
324 }
325 return id;
326}
327
328//_____________________________________________________________________________
329AliPID::EParticleType AliPID::GetMostProbable() const
330{
331// get the most probable particle id hypothesis
332// assuming the globaly set a priori probabilities
333
334 return GetMostProbable(fgPrior);
335}
336
337
338//_____________________________________________________________________________
339void AliPID::SetPriors(const Double_t* prior, Bool_t charged)
340{
341// use the given priors as global a priori probabilities
342
343 Double_t sum = 0;
344 for (Int_t i = 0; i < kSPECIESN; i++) {
345 if (charged && (i >= kSPECIES)) {
346 fgPrior[i] = 0;
347 } else {
348 if (prior[i] < 0) {
349 AliWarningClass(Form("negative prior (%g) for %ss. "
350 "Using 0 instead.", prior[i],
351 fgkParticleName[i]));
352 fgPrior[i] = 0;
353 } else {
354 fgPrior[i] = prior[i];
355 }
356 }
357 sum += prior[i];
358 }
359 if (sum == 0) {
360 AliWarningClass("all priors are zero.");
361 }
362}
363
364//_____________________________________________________________________________
365void AliPID::SetPrior(EParticleType iType, Double_t prior)
366{
367// use the given prior as global a priori probability for particles
368// of type "iType"
369
370 if (prior < 0) {
371 AliWarningClass(Form("negative prior (%g) for %ss. Using 0 instead.",
372 prior, fgkParticleName[iType]));
373 prior = 0;
374 }
375 fgPrior[iType] = prior;
376}
377
378
304864ab 379//_____________________________________________________________________________
380AliPID& AliPID::operator *= (const AliPID& pid)
381{
382// combine this probability densities with the one of "pid"
383
384 for (Int_t i = 0; i < kSPECIESN; i++) {
385 fProbDensity[i] *= pid.fProbDensity[i];
386 }
387 return *this;
388}
389
390//_____________________________________________________________________________
391AliPID operator * (const AliPID& pid1, const AliPID& pid2)
392{
393// combine the two probability densities
394
395 AliPID result;
396 result *= pid1;
397 result *= pid2;
398 return result;
399}