22 #include "AliVEvent.h"
23 #include "AliAODEvent.h"
24 #include "AliMCEvent.h"
25 #include "AliMCEventHandler.h"
30 #include "AliVTrack.h"
31 #include "TParticle.h"
32 #include "AliAODMCParticle.h"
33 #include "AliPIDResponse.h"
34 #include "AliPIDCombined.h"
35 #include "AliAnalysisManager.h"
36 #include "AliInputEventHandler.h"
38 using namespace AliHelperPIDNameSpace;
47 AliHelperPID::
AliHelperPID() :
TNamed("HelperPID", "PID
object"),fisMC(0), fPIDType(
kNSigmaTPCTOF), fNSigmaPID(3), fBayesCut(0.8), fPIDResponse(0x0), fPIDCombined(0x0),fOutputList(0x0),fRequestTOFPID(1),fRemoveTracksT0Fill(0),fUseExclusiveNSigma(0),fPtTOFPID(.6),fHasTOFPID(0){
50 Bool_t oldStatus = TH1::AddDirectoryStatus();
51 TH1::AddDirectory(kFALSE);
55 fnsigmas[ipart][ipid]=999.;
57 for(
Int_t ipart=0;ipart<
kNSpecies;ipart++)fHasDoubleCounting[ipart]=kFALSE;
59 fOutputList =
new TList;
60 fOutputList->SetOwner();
61 fOutputList->SetName(
"OutputList");
68 if(ipid==kNSigmaTPCTOF){miny=0;maxy=50;}
69 TH2F *fHistoNSigma=
new TH2F(Form(
"NSigma_%d_%d",ipart,ipid),Form(
"n#sigma %s %s",
kParticleSpeciesName[ipart],
kPIDTypeName[ipid]),200,0,10,500,miny,maxy);
70 fHistoNSigma->GetXaxis()->SetTitle(
"P_{T} (GeV / c)");
72 fOutputList->Add(fHistoNSigma);
81 if(ipid==kNSigmaTPCTOF){miny=0;maxy=20;}
82 TH2F *fHistoNSigma=
new TH2F(Form(
"NSigmaRec_%d_%d",ipart,ipid),
84 fHistoNSigma->GetXaxis()->SetTitle(
"P_{T} (GeV / c)");
86 fOutputList->Add(fHistoNSigma);
94 TH2F *fHistoBayes=
new TH2F(Form(
"BayesRec_%d",ipart),
96 fHistoBayes->GetXaxis()->SetTitle(
"P_{T} (GeV / c)");
98 fOutputList->Add(fHistoBayes);
106 if(ipid==kNSigmaTPCTOF){miny=0;maxy=20;}
107 TH2F *fHistoNSigma=
new TH2F(Form(
"NSigmaDC_%d_%d",ipart,ipid),
109 fHistoNSigma->GetXaxis()->SetTitle(
"P_{T} (GeV / c)");
111 fOutputList->Add(fHistoNSigma);
120 if(ipid==kNSigmaTPCTOF){miny=0;maxy=50;}
121 TH2F *fHistoNSigma=
new TH2F(Form(
"NSigmaMC_%d_%d",ipart,ipid),
123 fHistoNSigma->GetXaxis()->SetTitle(
"P_{T} (GeV / c)");
125 fOutputList->Add(fHistoNSigma);
133 if(idet==
kTOF)maxy=1.1;
134 TH2F *fHistoPID=
new TH2F(Form(
"PID_%d_%d",idet,ipart),Form(
"%s signal - %s",
kDetectorName[idet],
kParticleSpeciesName[ipart]),200,0,10,500,-maxy,maxy);
135 fHistoPID->GetXaxis()->SetTitle(
"P (GeV / c)");
136 fHistoPID->GetYaxis()->SetTitle(Form(
"%s signal",
kDetectorName[idet]));
137 fOutputList->Add(fHistoPID);
143 if(idet==
kTOF)maxy=1.1;
144 TH2F *fHistoPID=
new TH2F(Form(
"PIDAll_%d",idet),Form(
"%s signal",
kDetectorName[idet]),200,0,10,500,-maxy,maxy);
145 fHistoPID->GetXaxis()->SetTitle(
"P (GeV / c)");
146 fHistoPID->GetYaxis()->SetTitle(Form(
"%s signal",
kDetectorName[idet]));
147 fOutputList->Add(fHistoPID);
149 TH1::AddDirectory(oldStatus);
157 return (
TH2F*) fOutputList->FindObject(name);
171 AliInputEventHandler* inputHandler = (AliInputEventHandler*)(man->GetInputEventHandler());
172 fPIDResponse = inputHandler->GetPIDResponse();
175 AliFatal(
"Cannot get pid response");
179 CalculateNSigmas(trk,FIllQAHistos);
186 fPIDCombined=
new AliPIDCombined;
187 fPIDCombined->SetDefaultTPCPriors();
188 fPIDCombined->SetDetectorMask(AliPIDResponse::kDetTPC+AliPIDResponse::kDetTOF);
191 AliFatal(
"PIDCombined object not found");
194 ID = GetIDBayes(trk,FIllQAHistos);
198 ID=FindMinNSigma(trk,FIllQAHistos);
200 if(fUseExclusiveNSigma){
202 HasDC=GetDoubleCounting(trk,FIllQAHistos);
213 TH2F *h=GetHistogram2D(Form(
"PID_%d_%d",idet,ID));
214 if(idet==
kITS)h->Fill(trk->P(),trk->GetITSsignal()*trk->Charge());
215 if(idet==
kTPC)h->Fill(trk->P(),trk->GetTPCsignal()*trk->Charge());
216 if(idet==
kTOF && fHasTOFPID)h->Fill(trk->P(),TOFBetaCalc(trk)*trk->Charge());
221 TH2F *h=GetHistogram2D(Form(
"PIDAll_%d",idet));
222 if(idet==
kITS)h->Fill(trk->P(),trk->GetITSsignal()*trk->Charge());
223 if(idet==
kTPC)h->Fill(trk->P(),trk->GetTPCsignal()*trk->Charge());
224 if(idet==
kTOF && fHasTOFPID)h->Fill(trk->P(),TOFBetaCalc(trk)*trk->Charge());
234 switch(TMath::Abs(part->PdgCode())){
253 Bool_t *IDs=GetAllCompatibleIdentitiesNSigma(trk,FIllQAHistos);
255 Double_t probBayes[AliPID::kSPECIES];
259 if(fHasTOFPID && trk->Pt()>fPtTOFPID){
260 detUsed = CalcPIDCombined(trk, fPIDResponse, AliPIDResponse::kDetTOF|AliPIDResponse::kDetTPC, probBayes);
261 if(detUsed != (AliPIDResponse::kDetTOF|AliPIDResponse::kDetTPC))
return kSpUndefined;
263 detUsed = CalcPIDCombined(trk, fPIDResponse,AliPIDResponse::kDetTPC, probBayes);
264 if(detUsed != AliPIDResponse::kDetTPC)
return kSpUndefined;
269 for(
Int_t ipart=0;ipart<AliPID::kSPECIES;ipart++)sump+=probBayes[ipart];
270 if(sump<.99 && sump>1.01){
271 AliFatal(
"Bayesian probability not normalized to one");
275 if(probBayes[AliPID::kPion]>fBayesCut && IDs[
kSpPion]==1){
276 TH2F *h=GetHistogram2D(Form(
"BayesRec_%d",
kSpPion));
277 h->Fill(trk->Pt(),probBayes[AliPID::kPion]);
280 else if(probBayes[AliPID::kKaon]>fBayesCut && IDs[
kSpKaon]==1){
281 TH2F *h=GetHistogram2D(Form(
"BayesRec_%d",
kSpKaon));
282 h->Fill(trk->Pt(),probBayes[AliPID::kKaon]);
301 for(
Int_t i=0;i<AliPID::kSPECIES;i++)
305 fPIDCombined->SetDetectorMask(detMask);
307 return fPIDCombined->ComputeProbabilities((AliVTrack*)track, PIDResponse, prob);
316 AliVParticle *inEvHMain =
dynamic_cast<AliVParticle *
>(trk);
319 Double_t nsigmaTPCkKaon = fPIDResponse->NumberOfSigmasTPC(inEvHMain, AliPID::kKaon);
320 Double_t nsigmaTPCkPion = fPIDResponse->NumberOfSigmasTPC(inEvHMain, AliPID::kPion);
322 Double_t nsigmaTOFkProton=999.,nsigmaTOFkKaon=999.,nsigmaTOFkPion=999.;
323 Double_t nsigmaTPCTOFkProton=999.,nsigmaTPCTOFkKaon=999.,nsigmaTPCTOFkPion=999.;
327 if(fHasTOFPID && trk->Pt()>fPtTOFPID){
328 nsigmaTOFkProton = fPIDResponse->NumberOfSigmasTOF(inEvHMain,
AliPID::kProton);
329 nsigmaTOFkKaon = fPIDResponse->NumberOfSigmasTOF(inEvHMain, AliPID::kKaon);
330 nsigmaTOFkPion = fPIDResponse->NumberOfSigmasTOF(inEvHMain, AliPID::kPion);
331 Double_t d2Proton=nsigmaTPCkProton * nsigmaTPCkProton + nsigmaTOFkProton * nsigmaTOFkProton;
332 Double_t d2Kaon=nsigmaTPCkKaon * nsigmaTPCkKaon + nsigmaTOFkKaon * nsigmaTOFkKaon;
333 Double_t d2Pion=nsigmaTPCkPion * nsigmaTPCkPion + nsigmaTOFkPion * nsigmaTOFkPion;
352 nsigmaTPCTOFkProton = TMath::Sqrt(d2Proton);
353 nsigmaTPCTOFkKaon = TMath::Sqrt(d2Kaon);
354 nsigmaTPCTOFkPion = TMath::Sqrt(d2Pion);
358 nsigmaTPCTOFkProton = TMath::Abs(nsigmaTPCkProton);
359 nsigmaTPCTOFkKaon = TMath::Abs(nsigmaTPCkKaon);
360 nsigmaTPCTOFkPion = TMath::Abs(nsigmaTPCkPion);
378 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && trk->Pt()<fPtTOFPID)
continue;
379 TH2F *h=GetHistogram2D(Form(
"NSigma_%d_%d",ipart,ipid));
380 h->Fill(trk->Pt(),fnsigmas[ipart][ipid]);
391 if(fRequestTOFPID && (!fHasTOFPID) && trk->Pt()>fPtTOFPID)
return kSpUndefined;
394 Double_t nsigmaPion=999., nsigmaKaon=999., nsigmaProton=999.;
398 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTPC]) ;
399 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTPC]) ;
403 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTOF]) ;
404 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTOF]) ;
408 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTPCTOF]) ;
409 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTPCTOF]) ;
412 nsigmaProton = TMath::Abs(fnsigmas[
kSpProton][kNSigmaTPCTOF]);
413 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTPCTOF]) ;
414 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTPCTOF]) ;
419 if( ( nsigmaKaon==nsigmaPion ) && ( nsigmaKaon==nsigmaProton ))
return kSpUndefined;
421 if( ( nsigmaKaon < nsigmaPion ) && ( nsigmaKaon < nsigmaProton ) && (nsigmaKaon < fNSigmaPID)){
424 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && (trk->Pt()<fPtTOFPID))
continue;
425 TH2F *h=GetHistogram2D(Form(
"NSigmaRec_%d_%d",
kSpKaon,ipid));
426 h->Fill(trk->Pt(),fnsigmas[
kSpKaon][ipid]);
431 if( ( nsigmaPion < nsigmaKaon ) && ( nsigmaPion < nsigmaProton ) && (nsigmaPion < fNSigmaPID)){
434 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && (trk->Pt()<fPtTOFPID))
continue;
435 TH2F *h=GetHistogram2D(Form(
"NSigmaRec_%d_%d",
kSpPion,ipid));
436 h->Fill(trk->Pt(),fnsigmas[
kSpPion][ipid]);
441 if( ( nsigmaProton < nsigmaKaon ) && ( nsigmaProton < nsigmaPion ) && (nsigmaProton < fNSigmaPID)){
444 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && (trk->Pt()<fPtTOFPID))
continue;
445 TH2F *h=GetHistogram2D(Form(
"NSigmaRec_%d_%d",
kSpProton,ipid));
446 h->Fill(trk->Pt(),fnsigmas[
kSpProton][ipid]);
460 for(
Int_t ipart=0;ipart<
kNSpecies;ipart++)fHasDoubleCounting[ipart]=kFALSE;
462 Int_t MinNSigma=FindMinNSigma(trk,kFALSE);
468 Double_t nsigmaPion=999., nsigmaKaon=999., nsigmaProton=999.;
472 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTPC]) ;
473 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTPC]) ;
477 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTOF]) ;
478 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTOF]) ;
482 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTPCTOF]) ;
483 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTPCTOF]) ;
486 nsigmaProton = TMath::Abs(fnsigmas[
kSpProton][kNSigmaTPCTOF]);
487 nsigmaKaon = TMath::Abs(fnsigmas[
kSpKaon][kNSigmaTPCTOF]) ;
488 nsigmaPion = TMath::Abs(fnsigmas[
kSpPion][kNSigmaTPCTOF]) ;
491 if(nsigmaPion<fNSigmaPID && MinNSigma!=
kSpPion)fHasDoubleCounting[
kSpPion]=kTRUE;
492 if(nsigmaKaon<fNSigmaPID && MinNSigma!=
kSpKaon)fHasDoubleCounting[
kSpKaon]=kTRUE;
493 if(nsigmaProton<fNSigmaPID && MinNSigma!=
kSpProton)fHasDoubleCounting[
kSpProton]=kTRUE;
498 if(fHasDoubleCounting[ipart]){
500 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && (trk->Pt()<fPtTOFPID))
continue;
501 TH2F *h=GetHistogram2D(Form(
"NSigmaDC_%d_%d",ipart,ipid));
502 h->Fill(trk->Pt(),fnsigmas[ipart][ipid]);
507 return fHasDoubleCounting;
514 Bool_t *IDs=GetDoubleCounting(trk,FIllQAHistos);
515 IDs[FindMinNSigma(trk,FIllQAHistos)]=kTRUE;
526 if(!fisMC)AliFatal(
"Error: AliHelperPID::GetMCParticleSpecie called on data\n");
531 TString nameoftrack(event->ClassName());
532 if(!nameoftrack.CompareTo(
"AliESDEvent"))isESD=kTRUE;
533 else if(!nameoftrack.CompareTo(
"AliAODEvent"))isAOD=kTRUE;
534 else AliFatal(
"Not processing AODs nor ESDs") ;
537 TClonesArray *arrayMC = 0;
538 arrayMC = (TClonesArray*) event->GetList()->FindObject(AliAODMCParticle::StdBranchName());
539 if (!arrayMC)AliFatal(
"Error: MC particles branch not found!\n");
540 AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(TMath::Abs(trk->GetLabel()));
542 AliError(
"Cannot get MC particle");
545 code=partMC->GetPdgCode();
549 AliMCEventHandler* eventHandler =
dynamic_cast<AliMCEventHandler*
> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
550 if (!eventHandler) AliFatal(
"ERROR: Could not retrieve MC event handler");
551 AliMCEvent* mcEvent = eventHandler->MCEvent();
552 if (!mcEvent)AliFatal(
"ERROR: Could not retrieve MC event");
553 stack = mcEvent->Stack();
554 if (!stack) AliFatal(
"ERROR: stack not available\n");
556 part = (TParticle*)stack->Particle(TMath::Abs(trk->GetLabel()));
558 AliError(
"Cannot get MC particle");
561 code = part->GetPdgCode();
563 switch(TMath::Abs(code)){
567 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && (trk->Pt()<fPtTOFPID))
continue;
568 TH2F *h=GetHistogram2D(Form(
"NSigmaMC_%d_%d",
kSpProton,ipid));
569 h->Fill(trk->Pt(),fnsigmas[
kSpProton][ipid]);
577 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && (trk->Pt()<fPtTOFPID))
continue;
578 TH2F *h=GetHistogram2D(Form(
"NSigmaMC_%d_%d",
kSpKaon,ipid));
579 h->Fill(trk->Pt(),fnsigmas[
kSpKaon][ipid]);
587 if((ipid!=
kNSigmaTPC) && (!fHasTOFPID) && (trk->Pt()<fPtTOFPID))
continue;
588 TH2F *h=GetHistogram2D(Form(
"NSigmaMC_%d_%d",
kSpPion,ipid));
589 h->Fill(trk->Pt(),fnsigmas[
kSpPion][ipid]);
608 else fHasTOFPID=kTRUE;
611 if(trk->Pt()<fPtTOFPID)fHasTOFPID=kFALSE;
613 if(fRemoveTracksT0Fill)
615 Int_t startTimeMask = fPIDResponse->GetTOFResponse().GetStartTimeMask(trk->P());
616 if (startTimeMask < 0)fHasTOFPID=kFALSE;
624 Double_t tofTime=track->GetTOFsignal();
627 Float_t startTime = fPIDResponse->GetTOFResponse().GetStartTime(((AliVTrack*)track)->
P());
628 Double_t length= fPIDResponse->GetTOFResponse().GetExpectedSignal(track,AliPID::kElectron)*1E-3*
c;
629 tofTime -= startTime;
640 if (
id ==
kSpProton) { mass=9.38271999999999995e-01; }
641 if (
id ==
kSpKaon) { mass=4.93676999999999977e-01; }
642 if (
id ==
kSpPion) { mass=1.39570000000000000e-01; }
657 TIterator* iter = list->MakeIterator();
662 while ((obj = iter->Next())) {
667 collections.Add(outputlist);
670 fOutputList->Merge(&collections);
const char * kDetectorName[]
TH2F * GetHistogram2D(const char *name)
Int_t GetIDBayes(AliVTrack *trk, Bool_t FIllQAHistos)
Int_t GetParticleSpecies(AliVTrack *trk, Bool_t FIllQAHistos)
Int_t FindMinNSigma(AliVTrack *trk, Bool_t FIllQAHistos)
Bool_t * GetAllCompatibleIdentitiesNSigma(AliVTrack *trk, Bool_t FIllQAHistos)
Double_t GetMass(AliHelperParticleSpecies_t id) const
AliHelperParticleSpecies_t
Int_t GetMCParticleSpecie(AliVEvent *event, AliVTrack *trk, Bool_t FIllQAHistos)
void CalculateNSigmas(AliVTrack *trk, Bool_t FIllQAHistos)
Double_t TOFBetaCalc(AliVTrack *track) const
const char * kPIDTypeName[]
Bool_t * GetDoubleCounting(AliVTrack *trk, Bool_t FIllQAHistos)
UInt_t CalcPIDCombined(const AliVTrack *track, const AliPIDResponse *PIDResponse, Int_t detMask, Double_t *prob) const
Long64_t Merge(TCollection *list)
void CheckTOF(AliVTrack *trk)
const char * kParticleSpeciesName[]
const Int_t kNSigmaPIDType