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