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