]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/hfe/AliHFEpidTPC.cxx
Update of the HFE package
[u/mrichter/AliRoot.git] / PWG3 / hfe / AliHFEpidTPC.cxx
CommitLineData
809a4336 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**************************************************************************/
50685501 15//
16// Class for TPC PID
17// Implements the abstract base class AliHFEpidBase
18//
19// Class contains TPC specific cuts and QA histograms
20// Two selection strategies are offered: Selection of certain value
21// regions in the TPC dE/dx (by IsSelected), and likelihoods
22//
23// Authors:
24//
25// Markus Fasel <M.Fasel@gsi.de>
26// Markus Heide <mheide@uni-muenster.de>
27//
faee3b18 28#include <TF1.h>
809a4336 29#include <TList.h>
30#include <TMath.h>
faee3b18 31#include <THnSparse.h>
809a4336 32
722347d8 33#include "AliAODTrack.h"
34#include "AliAODMCParticle.h"
809a4336 35#include "AliESDtrack.h"
36#include "AliExternalTrackParam.h"
37#include "AliLog.h"
722347d8 38#include "AliMCParticle.h"
809a4336 39#include "AliPID.h"
10d100d4 40#include "AliESDpid.h"
809a4336 41
70da6c5a 42#include "AliHFEcollection.h"
809a4336 43#include "AliHFEpidTPC.h"
44
faee3b18 45ClassImp(AliHFEpidTPC)
809a4336 46
47//___________________________________________________________________
48AliHFEpidTPC::AliHFEpidTPC(const char* name) :
49 // add a list here
9bcfd1ab 50 AliHFEpidBase(name)
51 , fLineCrossingType(0)
809a4336 52 , fLineCrossingsEnabled(0)
faee3b18 53 , fUpperSigmaCut(NULL)
54 , fLowerSigmaCut(NULL)
75d81601 55 , fNsigmaTPC(3)
0792aa82 56 , fRejectionEnabled(0)
75d81601 57 , fPID(NULL)
75d81601 58 , fQAList(NULL)
809a4336 59{
60 //
61 // default constructor
62 //
809a4336 63 memset(fLineCrossingSigma, 0, sizeof(Double_t) * AliPID::kSPECIES);
722347d8 64 memset(fPAsigCut, 0, sizeof(Float_t) * 2);
65 memset(fNAsigmaTPC, 0, sizeof(Float_t) * 2);
809a4336 66 fPID = new AliPID;
809a4336 67}
68
69//___________________________________________________________________
70AliHFEpidTPC::AliHFEpidTPC(const AliHFEpidTPC &ref) :
9bcfd1ab 71 AliHFEpidBase("")
72 , fLineCrossingType(0)
809a4336 73 , fLineCrossingsEnabled(0)
faee3b18 74 , fUpperSigmaCut(NULL)
75 , fLowerSigmaCut(NULL)
809a4336 76 , fNsigmaTPC(2)
0792aa82 77 , fRejectionEnabled(0)
75d81601 78 , fPID(NULL)
75d81601 79 , fQAList(NULL)
809a4336 80{
81 //
82 // Copy constructor
83 //
84 ref.Copy(*this);
85}
86
87//___________________________________________________________________
88AliHFEpidTPC &AliHFEpidTPC::operator=(const AliHFEpidTPC &ref){
89 //
90 // Assignment operator
91 //
92 if(this != &ref){
93 ref.Copy(*this);
94 }
95 return *this;
96}
75d81601 97//___________________________________________________________________
809a4336 98void AliHFEpidTPC::Copy(TObject &o) const{
99 //
100 // Copy function
101 // called in copy constructor and assigment operator
102 //
103 AliHFEpidTPC &target = dynamic_cast<AliHFEpidTPC &>(o);
104
105 target.fLineCrossingsEnabled = fLineCrossingsEnabled;
faee3b18 106 target.fUpperSigmaCut = fUpperSigmaCut;
107 target.fLowerSigmaCut = fLowerSigmaCut;
809a4336 108 target.fNsigmaTPC = fNsigmaTPC;
0792aa82 109 target.fRejectionEnabled = fRejectionEnabled;
809a4336 110 target.fPID = new AliPID(*fPID);
70da6c5a 111 target.fQAList = new AliHFEcollection(*fQAList);
75d81601 112 memcpy(target.fLineCrossingSigma, fLineCrossingSigma, sizeof(Double_t) * AliPID::kSPECIES);
722347d8 113 memcpy(target.fPAsigCut, fPAsigCut, sizeof(Float_t) * 2);
114 memcpy(target.fNAsigmaTPC, fNAsigmaTPC, sizeof(Float_t) * 2);
115
809a4336 116 AliHFEpidBase::Copy(target);
117}
118
119//___________________________________________________________________
120AliHFEpidTPC::~AliHFEpidTPC(){
121 //
122 // Destructor
123 //
124 if(fPID) delete fPID;
809a4336 125 if(fQAList){
809a4336 126 delete fQAList;
127 }
128}
129
130//___________________________________________________________________
131Bool_t AliHFEpidTPC::InitializePID(){
132 //
133 // Add TPC dE/dx Line crossings
134 //
75d81601 135 //AddTPCdEdxLineCrossing(AliPID::kKaon, 0.3, 0.018);
136 //AddTPCdEdxLineCrossing(AliPID::kProton, 0.9, 0.054);
809a4336 137 return kTRUE;
138}
139
140//___________________________________________________________________
722347d8 141Int_t AliHFEpidTPC::IsSelected(AliHFEpidObject *track)
809a4336 142{
143 //
144 // For the TPC pid we use the 2-sigma band around the bethe bloch curve
145 // for electrons
146 // exclusion of the crossing points
147 //
722347d8 148 if(track->fAnalysisType == AliHFEpidObject::kESDanalysis){
149 AliESDtrack *esdTrack = NULL;
150 if(!(esdTrack = dynamic_cast<AliESDtrack *>(track->fRecTrack))) return 0;
151 AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track->fMCtrack);
152 return MakePIDesd(esdTrack, mctrack);
153 }else{
154 AliAODTrack *aodtrack = NULL;
155 if(!(aodtrack = dynamic_cast<AliAODTrack *>(track->fRecTrack))) return 0;
156 AliAODMCParticle *aodmctrack = dynamic_cast<AliAODMCParticle *>(track->fMCtrack);
157 return MakePIDaod(aodtrack, aodmctrack);
158 }
159}
722347d8 160//___________________________________________________________________
161Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){
162 //
163 // Doing TPC PID as explained in IsSelected for ESD tracks
164 //
faee3b18 165 if(!fESDpid){
166 AliError("No ESD PID object available");
167 return kFALSE;
70da6c5a 168 }
faee3b18 169 Float_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron);
170 if(IsQAon()) FillTPChistograms(esdTrack, mctrack, kFALSE);
809a4336 171 // exclude crossing points:
172 // Determine the bethe values for each particle species
809a4336 173 Bool_t isLineCrossing = kFALSE;
9bcfd1ab 174 fLineCrossingType = 0; // default value
809a4336 175 for(Int_t ispecies = 0; ispecies < AliPID::kSPECIES; ispecies++){
75d81601 176 if(ispecies == AliPID::kElectron) continue;
809a4336 177 if(!(fLineCrossingsEnabled & 1 << ispecies)) continue;
10d100d4 178 if(TMath::Abs(fESDpid->NumberOfSigmasTPC(esdTrack, (AliPID::EParticleType)ispecies)) < fLineCrossingSigma[ispecies] && TMath::Abs(nsigma) < fNsigmaTPC){
9bcfd1ab 179 // Point in a line crossing region, no PID possible, but !PID still possible ;-)
70da6c5a 180 isLineCrossing = kTRUE;
9bcfd1ab 181 fLineCrossingType = ispecies;
809a4336 182 break;
183 }
184 }
185 if(isLineCrossing) return 0;
0792aa82 186
187 // Check particle rejection
188 if(HasParticleRejection()){
189 Int_t reject = Reject(esdTrack);
0792aa82 190 if(reject != 0) return reject;
191 }
722347d8 192
faee3b18 193 // Check if we have an asymmetric sigma model set
0792aa82 194 Int_t pdg = 0;
faee3b18 195 if(fUpperSigmaCut || fLowerSigmaCut){
196 pdg = CutSigmaModel(esdTrack) ? 11 : 0;
197 } else {
198 // Perform Asymmetric n-sigma cut if required, else perform symmetric TPC sigma cut
199 Float_t p = 0.;
200 if(HasAsymmetricSigmaCut() && (p = esdTrack->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){
201 if(nsigma >= fNAsigmaTPC[0] && nsigma <= fNAsigmaTPC[1]) pdg = 11;
202 } else {
203 if(TMath::Abs(nsigma) < fNsigmaTPC ) pdg = 11;
204 }
70da6c5a 205 }
faee3b18 206 if(IsQAon() && pdg != 0) FillTPChistograms(esdTrack, mctrack, kTRUE);
0792aa82 207 return pdg;
722347d8 208}
209
210//___________________________________________________________________
211Int_t AliHFEpidTPC::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /*mctrack*/){
212 AliError("AOD PID not yet implemented");
809a4336 213 return 0;
214}
215
faee3b18 216//___________________________________________________________________
217Bool_t AliHFEpidTPC::CutSigmaModel(AliESDtrack *track){
218 //
219 // N SigmaCut using parametrization of the cuts
220 //
221 Bool_t isSelected = kTRUE;
222 Float_t nsigma = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron);
223 Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
224 if(fUpperSigmaCut && nsigma > fUpperSigmaCut->Eval(p)) isSelected = kFALSE;
225 if(fLowerSigmaCut && nsigma < fLowerSigmaCut->Eval(p)) isSelected = kFALSE;
226 return isSelected;
227}
228
0792aa82 229//___________________________________________________________________
230Int_t AliHFEpidTPC::Reject(AliESDtrack *track){
231 //
232 // reject particles based on asymmetric sigma cut
233 //
234 Int_t pdc[AliPID::kSPECIES] = {11,13,211,321,2212};
235 Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P();
236 for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
237 if(!TESTBIT(fRejectionEnabled, ispec)) continue;
0792aa82 238 // Particle rejection enabled
239 if(p < fRejection[4*ispec] || p > fRejection[4*ispec+2]) continue;
10d100d4 240 Double_t sigma = fESDpid->NumberOfSigmasTPC(track, static_cast<AliPID::EParticleType>(ispec));
0792aa82 241 if(sigma >= fRejection[4*ispec+1] && sigma <= fRejection[4*ispec+3]) return pdc[ispec] * track->Charge();
242 }
243 return 0;
244}
245
809a4336 246//___________________________________________________________________
75d81601 247void AliHFEpidTPC::AddTPCdEdxLineCrossing(Int_t species, Double_t sigma){
809a4336 248 //
249 // Add exclusion point for the TPC PID where a dEdx line crosses the electron line
250 // Stores line center and line sigma
251 //
252 if(species >= AliPID::kSPECIES){
253 AliError("Species doesn't exist");
254 return;
255 }
256 fLineCrossingsEnabled |= 1 << species;
75d81601 257 fLineCrossingSigma[species] = sigma;
809a4336 258}
259
260//___________________________________________________________________
261Double_t AliHFEpidTPC::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig)
262{
263 //gives probability for track to come from a certain particle species;
264 //no priors considered -> probabilities for equal abundances of all species!
265 //optional restriction to r-sigma bands of different particle species; default: rsig = 2. (see below)
266
267 //IMPORTANT: Tracks which are judged to be outliers get negative likelihoods -> unusable for combination with further detectors!
268
269 if(!track) return -1.;
809a4336 270 Bool_t outlier = kTRUE;
271 // Check whether distance from the respective particle line is smaller than r sigma
75d81601 272 for(Int_t hypo = 0; hypo < AliPID::kSPECIES; hypo++){
10d100d4 273 if(TMath::Abs(fESDpid->NumberOfSigmasTPC(track, (AliPID::EParticleType)hypo)) > rsig)
75d81601 274 outlier = kTRUE;
275 else {
276 outlier = kFALSE;
277 break;
278 }
279 }
809a4336 280 if(outlier)
281 return -2.;
282
75d81601 283 Double_t tpcProb[5];
809a4336 284
75d81601 285 track->GetTPCpid(tpcProb);
809a4336 286
75d81601 287 return tpcProb[species];
809a4336 288}
809a4336 289
809a4336 290//___________________________________________________________________
291Double_t AliHFEpidTPC::Suppression(const AliESDtrack *track, Int_t species)
292{
293 //ratio of likelihoods to be whatever species/to be an electron;
294 //as a cross-check for possible particle type suppression compared to electrons
50685501 295 const Double_t kVerySmall = 1e-10;
809a4336 296 if(!track) return -20;
50685501 297 if((TMath::Abs(Likelihood(track,species) + 2) < kVerySmall)||(TMath::Abs(Likelihood(track,0) + 2 ) < kVerySmall))
809a4336 298 return -30;
50685501 299 if(TMath::Abs(Likelihood(track,species)) < kVerySmall)
809a4336 300 return -10;
50685501 301 if (TMath::Abs(Likelihood(track,0)) < kVerySmall)
809a4336 302 return 10.;
303 else
304 return TMath::Log10(Likelihood(track,species)/(Likelihood(track,0)));
305
306
307}
75d81601 308
809a4336 309//___________________________________________________________________
faee3b18 310void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected){
50685501 311 //
312 // Fill the QA histogtrams
809a4336 313 //
314 if(!track)
315 return;
316
75d81601 317 Double_t tpcSignal = track->GetTPCsignal();
809a4336 318 Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P();
faee3b18 319 Int_t species = -1;
320 THnSparse *hptr = NULL;
321 if(HasMCData() && mctrack){
722347d8 322 switch(TMath::Abs(mctrack->Particle()->GetPdgCode())){
faee3b18 323 case 11:
324 species = AliPID::kElectron;
325 if(!stepSelected){
326 Double_t contentElHist[4];
327 for(Int_t ispec = AliPID::kMuon; ispec < AliPID::kSPECIES; ispec++){
328 contentElHist[0] = ispec;
329 contentElHist[1] = p;
330 contentElHist[2] = -Suppression(track, ispec);
331 contentElHist[3] = Likelihood(track, ispec);
332 hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCel"));
333 hptr->Fill(contentElHist);
334 }
335 }
336 break;
337 case 13: species = AliPID::kMuon; break;
338 case 211: species = AliPID::kPion; break;
339 case 321: species = AliPID::kKaon; break;
340 case 2212: species = AliPID::kProton; break;
341 default: species = -1; break;
342 }
343 if(!stepSelected){
344 // Fill Probability Histogram
345 Double_t contentProb[3] = {species , p, Likelihood(track, 0)};
346 hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCprob"));
347 hptr->Fill(contentProb);
348 // Fill suppression Histogram
349 if(species > 0 && species < AliPID::kSPECIES){
350 Double_t contentSup[3] = {species, p, Suppression(track, species)};
351 hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCsuppression"));
352 hptr->Fill(contentSup);
353 }
809a4336 354 }
355 }
faee3b18 356
357 // Fill signal histogram
358 Double_t contentSignal[5] = {species, p, tpcSignal, fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron), stepSelected ? 1 : 0};
359 hptr = dynamic_cast<THnSparseF *>(fQAList->Get("fHistTPCsignal"));
360 hptr->Fill(contentSignal);
809a4336 361}
362
363//___________________________________________________________________
364void AliHFEpidTPC::AddQAhistograms(TList *qaList){
50685501 365 //
366 // Create QA histograms for TPC PID
367 //
faee3b18 368 fQAList = new AliHFEcollection("fQAhistosTPC", "TPC QA histos");
369
370 // First THnSparse we fill with the signal
371 const Int_t kNdimSignal = 5;
372 Int_t nBins[kNdimSignal];
373 Double_t binMin[kNdimSignal], binMax[kNdimSignal];
374 nBins[0] = AliPID::kSPECIES + 1; binMin[0] = -1.; binMax[0] = AliPID::kSPECIES; // MC Species;
375 nBins[1] = 1000; binMin[1] = 0.; binMax[1] = 20.;
376 nBins[2] = 6000; binMin[2] = 0.; binMax[2] = 600.;
377 nBins[3] = 1400; binMin[3] = -12.; binMax[3] = 12.;
378 nBins[4] = 2; binMin[4] = 0.; binMax[4] = nBins[4]; // Selected or not
379 fQAList->CreateTHnSparse("fHistTPCsignal", "TPC signal; Species; p [GeV/c]; TPC Signal [a.u.]; Normalized TPC distance to the electron Line [#sigma]; Selection Status", kNdimSignal, nBins, binMin, binMax);
380
381 const Int_t kNdimProbEl = 3;
382 nBins[2] = 200; binMin[2] = 0.; binMax[2] = 1.;
383 fQAList->CreateTHnSparse("fHistTPCprob", "TPC Likelihood to be an electron; Species; p [GeV/c]; TPC Likelihood [a.u.]", kNdimProbEl, nBins, binMin, binMax);
384
385 const Int_t kNdimSuppression = 3;
386 nBins[2] = 200; binMin[2] = -1.; binMax[2] = 5.8; // log10 of TPC Likelihood(species)/Likelihood(elec) for species i neq electron
387 fQAList->CreateTHnSparse("fHistTPCsuppression", "TPC non-electron Suppression; Species; p [GeV/c]; Suppression [a.u.]", kNdimSuppression, nBins, binMin, binMax);
388
389 const Int_t kNdimEle = 4;
390 nBins[0] = AliPID::kSPECIES - 1; binMin[0] = 1.; binMax[0] = AliPID::kSPECIES;
391 nBins[2] = 100; binMin[2] = -1.; binMax[2] = 5.8;
392 nBins[3] = 200; binMin[3] = 0.; binMax[3] = 1.;
393 fQAList->CreateTHnSparse("fHistTPCel", "TPC electron Histogram; Species; p [GeV/c]; Electron Enhancement:Electron Likelihood", kNdimEle, nBins, binMin, binMax);
70da6c5a 394
395 qaList->AddLast(fQAList->GetList());
396}
397