1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 ///////////////////////////////////////////////////////////////////////////////
20 // particle id probability densities //
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. //
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 //
36 // The implementation of this class is based on the note ... //
37 // by Iouri Belikov and Karel Safarik. //
39 ///////////////////////////////////////////////////////////////////////////////
45 #include <TDatabasePDG.h>
52 Float_t AliPID::fgkParticleMass[AliPID::kSPECIESN+1] = {
62 0.00000, // electron conversion
66 const char* AliPID::fgkParticleName[AliPID::kSPECIESN+1] = {
80 const Int_t AliPID::fgkParticleCode[AliPID::kSPECIESN+1] = {
95 Double_t AliPID::fgPrior[kSPECIESN] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
98 //_______________________________________________________________________
101 // set default values (= equal probabilities)
103 for (Int_t i = 0; i < kSPECIESN; i++) {
104 fProbDensity[i] = 1./kSPECIESN;
108 //_______________________________________________________________________
109 AliPID::AliPID(const Double_t* probDensity, Bool_t charged)
111 // set given probability densities
114 for (Int_t i = 0; i < kSPECIES; i++) {
115 fProbDensity[i] = probDensity[i];
117 for (Int_t i = kSPECIES; i < kSPECIESN; i++) {
118 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
122 //_______________________________________________________________________
123 AliPID::AliPID(const Float_t* probDensity, Bool_t charged)
125 // set given probability densities
128 for (Int_t i = 0; i < kSPECIES; i++) {
129 fProbDensity[i] = probDensity[i];
131 for (Int_t i = kSPECIES; i < kSPECIESN; i++) {
132 fProbDensity[i] = ((charged) ? 0 : probDensity[i]);
136 //_______________________________________________________________________
137 AliPID::AliPID(const AliPID& pid) :
139 fCharged(pid.fCharged)
143 for (Int_t i = 0; i < kSPECIESN; i++) {
144 fProbDensity[i] = pid.fProbDensity[i];
148 //_______________________________________________________________________
149 AliPID& AliPID::operator = (const AliPID& pid)
151 // assignment operator
153 fCharged = pid.fCharged;
154 for (Int_t i = 0; i < kSPECIESN; i++) {
155 fProbDensity[i] = pid.fProbDensity[i];
161 //_____________________________________________________________________________
162 Double_t AliPID::GetProbability(EParticleType iType,
163 const Double_t* prior) const
165 // get the probability to be a particle of type "iType"
166 // assuming the a priori probabilities "prior"
169 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
170 for (Int_t i = 0; i < nSpecies; i++) {
171 sum += fProbDensity[i] * prior[i];
174 AliError("Invalid probability densities or priors");
177 return fProbDensity[iType] * prior[iType] / sum;
180 //_____________________________________________________________________________
181 Double_t AliPID::GetProbability(EParticleType iType) const
183 // get the probability to be a particle of type "iType"
184 // assuming the globaly set a priori probabilities
186 return GetProbability(iType, fgPrior);
189 //_____________________________________________________________________________
190 void AliPID::GetProbabilities(Double_t* probabilities,
191 const Double_t* prior) const
193 // get the probabilities to be a particle of given type
194 // assuming the a priori probabilities "prior"
197 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
198 for (Int_t i = 0; i < nSpecies; i++) {
199 sum += fProbDensity[i] * prior[i];
202 AliError("Invalid probability densities or priors");
203 for (Int_t i = 0; i < nSpecies; i++) probabilities[i] = -1;
206 for (Int_t i = 0; i < nSpecies; i++) {
207 probabilities[i] = fProbDensity[i] * prior[i] / sum;
211 //_____________________________________________________________________________
212 void AliPID::GetProbabilities(Double_t* probabilities) const
214 // get the probabilities to be a particle of given type
215 // assuming the globaly set a priori probabilities
217 GetProbabilities(probabilities, fgPrior);
220 //_____________________________________________________________________________
221 AliPID::EParticleType AliPID::GetMostProbable(const Double_t* prior) const
223 // get the most probable particle id hypothesis
224 // assuming the a priori probabilities "prior"
227 EParticleType id = kPion;
228 Int_t nSpecies = ((fCharged) ? kSPECIES : kSPECIESN);
229 for (Int_t i = 0; i < nSpecies; i++) {
230 Double_t prob = fProbDensity[i] * prior[i];
233 id = EParticleType(i);
237 AliError("Invalid probability densities or priors");
242 //_____________________________________________________________________________
243 AliPID::EParticleType AliPID::GetMostProbable() const
245 // get the most probable particle id hypothesis
246 // assuming the globaly set a priori probabilities
248 return GetMostProbable(fgPrior);
252 //_____________________________________________________________________________
253 void AliPID::SetPriors(const Double_t* prior, Bool_t charged)
255 // use the given priors as global a priori probabilities
258 for (Int_t i = 0; i < kSPECIESN; i++) {
259 if (charged && (i >= kSPECIES)) {
263 AliWarningClass(Form("negative prior (%g) for %ss. "
264 "Using 0 instead.", prior[i],
265 fgkParticleName[i]));
268 fgPrior[i] = prior[i];
274 AliWarningClass("all priors are zero.");
278 //_____________________________________________________________________________
279 void AliPID::SetPrior(EParticleType iType, Double_t prior)
281 // use the given prior as global a priori probability for particles
285 AliWarningClass(Form("negative prior (%g) for %ss. Using 0 instead.",
286 prior, fgkParticleName[iType]));
289 fgPrior[iType] = prior;
293 //_____________________________________________________________________________
296 // initialize the mass values from the PDG database
298 for (Int_t i = 0; i < kSPECIESN; i++) {
300 TDatabasePDG::Instance()->GetParticle(fgkParticleCode[i])->Mass();
305 //_____________________________________________________________________________
306 AliPID& AliPID::operator *= (const AliPID& pid)
308 // combine this probability densities with the one of "pid"
310 for (Int_t i = 0; i < kSPECIESN; i++) {
311 fProbDensity[i] *= pid.fProbDensity[i];
316 //_____________________________________________________________________________
317 AliPID operator * (const AliPID& pid1, const AliPID& pid2)
319 // combine the two probability densities