]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliPID.cxx
Typo fixed + warnings removed.
[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
304864ab 52const char* AliPID::fgkParticleName[AliPID::kSPECIESN+1] = {
53 "electron",
54 "muon",
55 "pion",
56 "kaon",
57 "proton",
58 "photon",
59 "pi0",
60 "neutron",
61 "kaon0",
62 "eleCon",
63 "unknown"
64};
65
91dbd0dc 66const char* AliPID::fgkParticleShortName[AliPID::kSPECIESN+1] = {
67 "e",
68 "mu",
69 "pi",
70 "K",
71 "p",
72 "photon",
73 "pi0",
74 "n",
75 "K0",
76 "eleCon",
77 "unknown"
78};
79
80const char* AliPID::fgkParticleLatexName[AliPID::kSPECIESN+1] = {
81 "e",
82 "#mu",
83 "#pi",
84 "K",
85 "p",
86 "#gamma",
87 "#pi_{0}",
88 "n",
89 "K_{0}",
90 "eleCon",
91 "unknown"
92};
93
304864ab 94const Int_t AliPID::fgkParticleCode[AliPID::kSPECIESN+1] = {
95 ::kElectron,
96 ::kMuonMinus,
97 ::kPiPlus,
98 ::kKPlus,
99 ::kProton,
100 ::kGamma,
101 ::kPi0,
102 ::kNeutron,
103 ::kK0,
0133aa88 104 ::kElectron,
304864ab 105 0
106};
107
a9bbb414 108/*const*/ Float_t AliPID::fgkParticleMass[AliPID::kSPECIESN+1] = {
109 0,0,0,0,0,0,0,0,0,0,0
110 /*
90e48c0c 111 M(kElectron), // electron
112 M(kMuon), // muon
113 M(kPion), // pion
114 M(kKaon), // kaon
115 M(kProton), // proton
116 M(kPhoton), // photon
117 M(kPi0), // pi0
118 M(kNeutron), // neutron
119 M(kKaon0), // kaon0
120 M(kEleCon), // electron conversion
121 0.00000 // unknown
a9bbb414 122 */
90e48c0c 123};
304864ab 124
125Double_t AliPID::fgPrior[kSPECIESN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
126
127
128//_______________________________________________________________________
90e48c0c 129AliPID::AliPID() :
130 TObject(),
131 fCharged(0)
304864ab 132{
a9bbb414 133 //
134 // Default constructor
135 //
136 Init();
137 // set default values (= equal probabilities)
138 for (Int_t i = 0; i < kSPECIESN; i++)
304864ab 139 fProbDensity[i] = 1./kSPECIESN;
304864ab 140}
141
142//_______________________________________________________________________
90e48c0c 143AliPID::AliPID(const Double_t* probDensity, Bool_t charged) :
144 TObject(),
145 fCharged(charged)
304864ab 146{
90e48c0c 147 //
a9bbb414 148 // Standard constructor
90e48c0c 149 //
a9bbb414 150 Init();
151 // set given probability densities
152 for (Int_t i = 0; i < kSPECIES; i++)
304864ab 153 fProbDensity[i] = probDensity[i];
a9bbb414 154
155 for (Int_t i = kSPECIES; i < kSPECIESN; i++)
304864ab 156 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
304864ab 157}
158
159//_______________________________________________________________________
90e48c0c 160AliPID::AliPID(const Float_t* probDensity, Bool_t charged) :
161 TObject(),
162 fCharged(charged)
304864ab 163{
90e48c0c 164 //
a9bbb414 165 // Standard constructor
90e48c0c 166 //
a9bbb414 167 Init();
168 // set given probability densities
169 for (Int_t i = 0; i < kSPECIES; i++)
304864ab 170 fProbDensity[i] = probDensity[i];
a9bbb414 171
172 for (Int_t i = kSPECIES; i < kSPECIESN; i++)
304864ab 173 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
304864ab 174}
175
176//_______________________________________________________________________
177AliPID::AliPID(const AliPID& pid) :
178 TObject(pid),
179 fCharged(pid.fCharged)
180{
90e48c0c 181 //
182 // copy constructor
183 //
a9bbb414 184 // We do not call init here, MUST already be done
185 for (Int_t i = 0; i < kSPECIESN; i++)
304864ab 186 fProbDensity[i] = pid.fProbDensity[i];
304864ab 187}
188
3088e2dd 189//_______________________________________________________________________
190void AliPID::SetProbabilities(const Double_t* probDensity, Bool_t charged)
191{
192 //
193 // Set the probability densities
194 //
195 for (Int_t i = 0; i < kSPECIES; i++)
196 fProbDensity[i] = probDensity[i];
197
198 for (Int_t i = kSPECIES; i < kSPECIESN; i++)
199 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
200}
201
304864ab 202//_______________________________________________________________________
203AliPID& AliPID::operator = (const AliPID& pid)
204{
205// assignment operator
206
207 fCharged = pid.fCharged;
208 for (Int_t i = 0; i < kSPECIESN; i++) {
209 fProbDensity[i] = pid.fProbDensity[i];
210 }
211 return *this;
212}
213
a9bbb414 214//_______________________________________________________________________
215void AliPID::Init()
216{
217 //
218 // Initialise the masses
219 //
220 // Initialise only once...
221 if(!fgkParticleMass[0])
222 for (Int_t i = 0; i < kSPECIESN; i++)
374ef46b 223 fgkParticleMass[i] = M(i);
a9bbb414 224}
304864ab 225
226//_____________________________________________________________________________
227Double_t AliPID::GetProbability(EParticleType iType,
228 const Double_t* prior) const
229{
a9bbb414 230 //
231 // Get the probability to be a particle of type "iType"
232 // assuming the a priori probabilities "prior"
233 //
304864ab 234 Double_t sum = 0.;
235 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
236 for (Int_t i = 0; i < nSpecies; i++) {
237 sum += fProbDensity[i] * prior[i];
238 }
239 if (sum <= 0) {
240 AliError("Invalid probability densities or priors");
241 return -1;
242 }
243 return fProbDensity[iType] * prior[iType] / sum;
244}
245
246//_____________________________________________________________________________
247Double_t AliPID::GetProbability(EParticleType iType) const
248{
249// get the probability to be a particle of type "iType"
250// assuming the globaly set a priori probabilities
251
252 return GetProbability(iType, fgPrior);
253}
254
255//_____________________________________________________________________________
256void AliPID::GetProbabilities(Double_t* probabilities,
257 const Double_t* prior) const
258{
259// get the probabilities to be a particle of given type
260// assuming the a priori probabilities "prior"
261
262 Double_t sum = 0.;
263 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
264 for (Int_t i = 0; i < nSpecies; i++) {
265 sum += fProbDensity[i] * prior[i];
266 }
267 if (sum <= 0) {
268 AliError("Invalid probability densities or priors");
269 for (Int_t i = 0; i < nSpecies; i++) probabilities[i] = -1;
270 return;
271 }
272 for (Int_t i = 0; i < nSpecies; i++) {
273 probabilities[i] = fProbDensity[i] * prior[i] / sum;
274 }
275}
276
277//_____________________________________________________________________________
278void AliPID::GetProbabilities(Double_t* probabilities) const
279{
280// get the probabilities to be a particle of given type
281// assuming the globaly set a priori probabilities
282
283 GetProbabilities(probabilities, fgPrior);
284}
285
286//_____________________________________________________________________________
287AliPID::EParticleType AliPID::GetMostProbable(const Double_t* prior) const
288{
289// get the most probable particle id hypothesis
290// assuming the a priori probabilities "prior"
291
292 Double_t max = 0.;
293 EParticleType id = kPion;
294 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
295 for (Int_t i = 0; i < nSpecies; i++) {
296 Double_t prob = fProbDensity[i] * prior[i];
297 if (prob > max) {
298 max = prob;
299 id = EParticleType(i);
300 }
301 }
302 if (max == 0) {
303 AliError("Invalid probability densities or priors");
304 }
305 return id;
306}
307
308//_____________________________________________________________________________
309AliPID::EParticleType AliPID::GetMostProbable() const
310{
311// get the most probable particle id hypothesis
312// assuming the globaly set a priori probabilities
313
314 return GetMostProbable(fgPrior);
315}
316
317
318//_____________________________________________________________________________
319void AliPID::SetPriors(const Double_t* prior, Bool_t charged)
320{
321// use the given priors as global a priori probabilities
322
323 Double_t sum = 0;
324 for (Int_t i = 0; i < kSPECIESN; i++) {
325 if (charged && (i >= kSPECIES)) {
326 fgPrior[i] = 0;
327 } else {
328 if (prior[i] < 0) {
329 AliWarningClass(Form("negative prior (%g) for %ss. "
330 "Using 0 instead.", prior[i],
331 fgkParticleName[i]));
332 fgPrior[i] = 0;
333 } else {
334 fgPrior[i] = prior[i];
335 }
336 }
337 sum += prior[i];
338 }
339 if (sum == 0) {
340 AliWarningClass("all priors are zero.");
341 }
342}
343
344//_____________________________________________________________________________
345void AliPID::SetPrior(EParticleType iType, Double_t prior)
346{
347// use the given prior as global a priori probability for particles
348// of type "iType"
349
350 if (prior < 0) {
351 AliWarningClass(Form("negative prior (%g) for %ss. Using 0 instead.",
352 prior, fgkParticleName[iType]));
353 prior = 0;
354 }
355 fgPrior[iType] = prior;
356}
357
358
304864ab 359//_____________________________________________________________________________
360AliPID& AliPID::operator *= (const AliPID& pid)
361{
362// combine this probability densities with the one of "pid"
363
364 for (Int_t i = 0; i < kSPECIESN; i++) {
365 fProbDensity[i] *= pid.fProbDensity[i];
366 }
367 return *this;
368}
369
370//_____________________________________________________________________________
371AliPID operator * (const AliPID& pid1, const AliPID& pid2)
372{
373// combine the two probability densities
374
375 AliPID result;
376 result *= pid1;
377 result *= pid2;
378 return result;
379}