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 **************************************************************************/
16 // PID Response class for the TRD detector
17 // Based on 1D Likelihood approach
18 // Calculation of probabilities using Bayesian approach
19 // Attention: This method is only used to separate electrons from pions
22 // Markus Fasel <M.Fasel@gsi.de>
23 // Anton Andronic <A.Andronic@gsi.de>
30 #include <TObjArray.h>
34 #include <TDirectory.h>
38 #include "AliTRDPIDReference.h"
39 #include "AliTRDPIDResponse.h"
41 ClassImp(AliTRDPIDResponse)
43 //____________________________________________________________
44 AliTRDPIDResponse::AliTRDPIDResponse():
47 ,fGainNormalisationFactor(1.)
51 // Default constructor
55 //____________________________________________________________
56 AliTRDPIDResponse::AliTRDPIDResponse(const AliTRDPIDResponse &ref):
58 ,fkPIDReference(ref.fkPIDReference)
59 ,fGainNormalisationFactor(ref.fGainNormalisationFactor)
60 ,fPIDmethod(ref.fPIDmethod)
67 //____________________________________________________________
68 AliTRDPIDResponse &AliTRDPIDResponse::operator=(const AliTRDPIDResponse &ref){
70 // Assignment operator
72 if(this == &ref) return *this;
75 TObject::operator=(ref);
76 fGainNormalisationFactor = ref.fGainNormalisationFactor;
77 fkPIDReference = ref.fkPIDReference;
78 fPIDmethod = ref.fPIDmethod;
83 //____________________________________________________________
84 AliTRDPIDResponse::~AliTRDPIDResponse(){
88 if(IsOwner()) delete fkPIDReference;
91 //____________________________________________________________
92 Bool_t AliTRDPIDResponse::Load(const Char_t * filename, const Char_t *refName){
94 // Load References into the toolkit
96 AliDebug(1, "Loading reference histos from root file");
97 TDirectory *owd = gDirectory;// store old working directory
100 filename = Form("%s/STEER/LQ1dRef_v1.root",gSystem->ExpandPathName("$ALICE_ROOT"));
101 TFile *in = TFile::Open(filename);
103 AliError("Ref file not available.");
108 fkPIDReference = dynamic_cast<const AliTRDPIDReference *>(in->Get(refName)->Clone());
109 in->Close(); delete in;
111 SetBit(kIsOwner, kTRUE);
112 AliDebug(2, Form("Successfully loaded References for %d Momentum bins", fkPIDReference->GetNumberOfMomentumBins()));
116 //____________________________________________________________
117 Bool_t AliTRDPIDResponse::GetResponse(Int_t n, const Double_t * const dedx, const Float_t * const p, Double_t prob[AliPID::kSPECIES], Bool_t kNorm) const
120 // Calculate TRD likelihood values for the track based on dedx and
121 // momentum values. The likelihoods are calculated by query the
122 // reference data depending on the PID method selected
125 // n - number of dedx slices/chamber
126 // dedx - array of dedx slices organized layer wise
127 // p - array of momentum measurements organized layer wise
130 // prob - probabilities allocated by TRD for particle specis
131 // kNorm - switch to normalize probabilities to 1. By default true. If false return not normalized prob.
134 // true if calculation success
138 AliWarning("Missing reference data. PID calculation not possible.");
142 for(Int_t is(AliPID::kSPECIES); is--;) prob[is]=.2;
143 Double_t prLayer[AliPID::kSPECIES];
144 Double_t dE[10], s(0.);
145 for(Int_t il(kNlayer); il--;){
146 memset(prLayer, 0, AliPID::kSPECIES*sizeof(Double_t));
147 if(!CookdEdx(n, &dedx[il*n], &dE[0])) continue;
150 for(Int_t is(AliPID::kSPECIES); is--;){
151 if((dE[0] > 0.) && (p[il] > 0.)) prLayer[is] = GetProbabilitySingleLayer(is, p[il], dE[0]);
152 AliDebug(3, Form("Probability for Species %d in Layer %d: %f", is, il, prLayer[is]));
156 AliDebug(2, Form("Null all species prob layer[%d].", il));
159 for(Int_t is(AliPID::kSPECIES); is--;){
160 if(kNorm) prLayer[is] /= s;
161 prob[is] *= prLayer[is];
164 if(!kNorm) return kTRUE;
167 for(Int_t is(AliPID::kSPECIES); is--;) s+=prob[is];
169 AliDebug(2, "Null total prob.");
172 for(Int_t is(AliPID::kSPECIES); is--;) prob[is]/=s;
176 //____________________________________________________________
177 Double_t AliTRDPIDResponse::GetProbabilitySingleLayer(Int_t species, Double_t plocal, Double_t dEdx) const {
179 // Get the non-normalized probability for a certain particle species as coming
180 // from the reference histogram
181 // Interpolation between momentum bins
183 AliDebug(1, Form("Make Probability for Species %d with Momentum %f", species, plocal));
184 Float_t pLower, pUpper;
185 Double_t probLayer = 0.;
186 TH1 *refUpper = dynamic_cast<TH1 *>(fkPIDReference->GetUpperReference((AliPID::EParticleType)species, plocal, pUpper)),
187 *refLower = dynamic_cast<TH1 *>(fkPIDReference->GetLowerReference((AliPID::EParticleType)species, plocal, pLower));
188 // Do Interpolation exept for underflow and overflow
189 if(refLower && refUpper){
190 Double_t probLower = refLower->GetBinContent(refLower->GetXaxis()->FindBin(dEdx));
191 Double_t probUpper = refUpper->GetBinContent(refUpper->GetXaxis()->FindBin(dEdx));
193 probLayer = probLower + (probUpper - probLower)/(pUpper-pLower) * (plocal - pLower);
196 probLayer = refLower->GetBinContent(refLower->GetXaxis()->FindBin(dEdx));
199 probLayer = refUpper->GetBinContent(refUpper->GetXaxis()->FindBin(dEdx));
201 AliError("No references available");
203 AliDebug(1, Form("Probability %f", probLayer));
207 //____________________________________________________________
208 void AliTRDPIDResponse::SetOwner(){
210 // Make Deep Copy of the Reference Histograms
212 if(!fkPIDReference || IsOwner()) return;
213 const AliTRDPIDReference *tmp = fkPIDReference;
214 fkPIDReference = dynamic_cast<const AliTRDPIDReference *>(tmp->Clone());
215 SetBit(kIsOwner, kTRUE);
218 //____________________________________________________________
219 Bool_t AliTRDPIDResponse::CookdEdx(Int_t nSlice, const Double_t * const in, Double_t *out) const
231 for(Int_t islice = 0; islice < nSlice; islice++) out[0] += in[islice] * fGainNormalisationFactor;
232 if(out[0] < 1e-6) return kFALSE;