From: sma Date: Fri, 20 Aug 2010 09:46:39 +0000 (+0000) Subject: Update of the HFE package X-Git-Url: http://git.uio.no/git/?a=commitdiff_plain;h=faee3b18888c1a191bdb5bfef8455437dc937df7;p=u%2Fmrichter%2FAliRoot.git Update of the HFE package --- diff --git a/PWG3/PWG3hfeLinkDef.h b/PWG3/PWG3hfeLinkDef.h index 6798bc89b50..efeba665a3d 100644 --- a/PWG3/PWG3hfeLinkDef.h +++ b/PWG3/PWG3hfeLinkDef.h @@ -16,10 +16,14 @@ #pragma link C++ class AliHFEsecVtx+; #pragma link C++ class AliHFEpriVtx+; #pragma link C++ class AliHFEelecbackground+; +#pragma link C++ class AliHFEspectrum+; +#pragma link C++ class AliHFEV0info+; #pragma link C++ class AliHFEV0pid+; +#pragma link C++ class AliHFEV0cuts+; #pragma link C++ class AliHFEV0pidMC+; #pragma link C++ class AliHFEpidQA+; +#pragma link C++ class AliHFEtrdPIDqa+; #pragma link C++ class AliHFEpid+; #pragma link C++ class AliHFEpidBase+; #pragma link C++ class AliHFEpidITS+; diff --git a/PWG3/hfe/AliAnalysisTaskDCA.cxx b/PWG3/hfe/AliAnalysisTaskDCA.cxx index e3cf8f2b3ad..a61a340de2c 100644 --- a/PWG3/hfe/AliAnalysisTaskDCA.cxx +++ b/PWG3/hfe/AliAnalysisTaskDCA.cxx @@ -34,14 +34,21 @@ #include +#include "AliAnalysisManager.h" + #include "AliCFManager.h" -#include "AliMCEvent.h" + #include "AliESDInputHandler.h" #include "AliESDtrack.h" -#include "AliAnalysisManager.h" +#include "AliVertexerTracks.h" +#include "AliESDVertex.h" + #include "AliMCEventHandler.h" +#include "AliMCEvent.h" #include "AliMCParticle.h" +#include "AliESDpid.h" +#include "AliHFEpid.h" #include "AliHFEcuts.h" #include "AliHFEdca.h" @@ -50,76 +57,117 @@ //____________________________________________________________ AliAnalysisTaskDCA::AliAnalysisTaskDCA(): - AliAnalysisTask("Impact Parameter Resolution and Pull Analysis", "") + AliAnalysisTaskSE("Impact Parameter Resolution and Pull Analysis") , fPlugins(0) - , fESD(0x0) - , fMC(0x0) , fCuts(0x0) + , fDefaultPID(0x0) + , fHFEpid(0x0) + , fPIDdetectors("") + , fPIDstrategy(0) , fCFM(0x0) , fDCA(0x0) - , fPixelStatus(0x0) , fNclustersITS(0x0) + , fMinNprimVtxContrbutor(0x0) , fNEvents(0x0) , fResidualList(0x0) , fPullList(0x0) + , fDcaList(0x0) + , fKfDcaList(0x0) + , fMcVertexList(0x0) + , fDataDcaList(0x0) + , fDataVertexList(0x0) + , fDataPullList(0x0) + , fMcPidList(0x0) + , fDataPidList(0x0) + , fHfeDcaList(0x0) + , fHfeDataDcaList(0x0) , fOutput(0x0) { // // Dummy constructor // DefineInput(0, TChain::Class()); - DefineOutput(0, TH1I::Class()); // event - DefineOutput(1, TList::Class()); // output + DefineOutput(1, TH1I::Class()); + DefineOutput(2, TList::Class()); - SetHasMCData(); + fDefaultPID = new AliESDpid; + fHFEpid = new AliHFEpid; } //____________________________________________________________ AliAnalysisTaskDCA::AliAnalysisTaskDCA(const char * name): - AliAnalysisTask(name, "") + AliAnalysisTaskSE(name) , fPlugins(0) - , fESD(0x0) - , fMC(0x0) , fCuts(0x0) + , fDefaultPID(0x0) + , fHFEpid(0x0) + , fPIDdetectors("") + , fPIDstrategy(0) , fCFM(0x0) , fDCA(0x0) - , fPixelStatus(0x0) , fNclustersITS(0x0) + , fMinNprimVtxContrbutor(0x0) , fNEvents(0x0) , fResidualList(0x0) , fPullList(0x0) + , fDcaList(0x0) + , fKfDcaList(0x0) + , fMcVertexList(0x0) + , fDataDcaList(0x0) + , fDataVertexList(0x0) + , fDataPullList(0x0) + , fMcPidList(0x0) + , fDataPidList(0x0) + , fHfeDcaList(0x0) + , fHfeDataDcaList(0x0) , fOutput(0x0) { // // Default constructor // DefineInput(0, TChain::Class()); - DefineOutput(0, TH1I::Class()); - DefineOutput(1, TList::Class()); + DefineOutput(1, TH1I::Class()); + DefineOutput(2, TList::Class()); + + fDefaultPID = new AliESDpid; + fHFEpid = new AliHFEpid; - SetHasMCData(); } //____________________________________________________________ AliAnalysisTaskDCA::AliAnalysisTaskDCA(const AliAnalysisTaskDCA &ref): - AliAnalysisTask(ref) + AliAnalysisTaskSE(ref) , fPlugins(ref.fPlugins) - , fESD(ref.fESD) - , fMC(ref.fMC) - , fCuts(ref.fCuts) + , fCuts(ref.fCuts) + , fDefaultPID(ref.fDefaultPID) + , fHFEpid(ref.fHFEpid) + , fPIDdetectors(ref.fPIDdetectors) + , fPIDstrategy(ref.fPIDstrategy) , fCFM(ref.fCFM) , fDCA(ref.fDCA) - , fPixelStatus(ref.fPixelStatus) , fNclustersITS(ref.fNclustersITS) + , fMinNprimVtxContrbutor(ref.fMinNprimVtxContrbutor) , fNEvents(ref.fNEvents) , fResidualList(ref.fResidualList) , fPullList(ref.fPullList) + , fDcaList(ref.fDcaList) + , fKfDcaList(ref.fKfDcaList) + , fMcVertexList(ref.fMcVertexList) + , fDataDcaList(ref.fDataDcaList) + , fDataVertexList(ref.fDataVertexList) + , fDataPullList(ref.fDataPullList) + , fMcPidList(ref.fMcPidList) + , fDataPidList(ref.fDataPidList) + , fHfeDcaList(ref.fHfeDcaList) + , fHfeDataDcaList(ref.fHfeDataDcaList) , fOutput(ref.fOutput) { // // Copy Constructor // + + ref.Copy(*this); } //____________________________________________________________ @@ -128,19 +176,31 @@ AliAnalysisTaskDCA &AliAnalysisTaskDCA::operator=(const AliAnalysisTaskDCA &ref) // Assignment operator // if(this == &ref) return *this; - AliAnalysisTask::operator=(ref); + AliAnalysisTaskSE::operator=(ref); fPlugins = ref.fPlugins; - fESD = ref.fESD; - fMC = ref.fMC; fCuts = ref.fCuts; + fDefaultPID = ref.fDefaultPID; + fHFEpid = ref.fHFEpid; + fPIDdetectors = ref.fPIDdetectors; + fPIDstrategy = ref.fPIDstrategy; fCFM = ref.fCFM; fDCA = ref.fDCA; - fPixelStatus = ref.fPixelStatus; fNclustersITS = ref.fNclustersITS; + fMinNprimVtxContrbutor = ref.fMinNprimVtxContrbutor; fNEvents = ref.fNEvents; - fOutput = ref.fOutput; fResidualList = ref.fResidualList; fPullList = ref.fPullList; + fDcaList = ref.fDcaList; + fKfDcaList = ref.fKfDcaList; + fMcVertexList = ref.fMcVertexList; + fDataDcaList = ref.fDataDcaList; + fDataVertexList = ref.fDataVertexList; + fDataPullList = ref.fDataPullList; + fMcPidList = ref.fMcPidList; + fDataPidList = ref.fDataPidList; + fHfeDcaList = ref.fHfeDcaList; + fHfeDataDcaList = ref.fHfeDataDcaList; + fOutput = ref.fOutput; return *this; } @@ -151,18 +211,11 @@ AliAnalysisTaskDCA::~AliAnalysisTaskDCA(){ // Destructor // - if(fESD) delete fESD; - if(fMC) delete fMC; - + if(fDefaultPID) delete fDefaultPID; + if(fHFEpid) delete fHFEpid; if(fCFM) delete fCFM; - if(fDCA) delete fDCA; - - if(fOutput){ - fOutput->Clear(); - delete fOutput; - } - + if(fNEvents) delete fNEvents; if(fResidualList){ fResidualList->Clear(); delete fResidualList; @@ -173,37 +226,79 @@ AliAnalysisTaskDCA::~AliAnalysisTaskDCA(){ delete fPullList; } - if(fNEvents) delete fNEvents; -} + if(fDcaList){ + fDcaList->Clear(); + delete fDcaList; + } + if(fKfDcaList){ + fKfDcaList->Clear(); + delete fKfDcaList; + } -//____________________________________________________________ -void AliAnalysisTaskDCA::ConnectInputData(Option_t *){ - // - // Connecting the input - - AliESDInputHandler *esdH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); - if(!esdH){ - AliError("No ESD input handler"); - return; - } else { - fESD = esdH->GetEvent(); + if(fMcVertexList){ + fMcVertexList->Clear(); + delete fMcVertexList; } - AliMCEventHandler *mcH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()); - if(!mcH){ - AliError("No MC truth handler"); - return; - } else { - fMC = mcH->MCEvent(); + + if(fDataDcaList){ + fDataDcaList->Clear(); + delete fDataDcaList; + } + + if(fDataVertexList){ + fDataVertexList->Clear(); + delete fDataVertexList; + } + if(fDataPullList){ + fDataPullList->Clear(); + delete fDataPullList; + } + + if(fMcPidList){ + fMcPidList -> Clear(); + delete fMcPidList; + } + if(fDataPidList){ + fDataPidList -> Clear(); + delete fDataPidList; + } + + if(fHfeDcaList) { + fHfeDcaList->Clear(); + delete fHfeDcaList; + } + + if(fHfeDataDcaList) { + fHfeDataDcaList->Clear(); + delete fHfeDataDcaList; + } + + if(fOutput){ + fOutput->Clear(); + delete fOutput; } + } //____________________________________________________________ -void AliAnalysisTaskDCA::CreateOutputObjects(){ +void AliAnalysisTaskDCA::UserCreateOutputObjects(){ // create output objects // fNEvents // residual and pull + + // Automatic determination of the analysis mode + AliVEventHandler *inputHandler = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); + + if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){ + SetAODAnalysis(); + } else { + SetESDAnalysis(); + if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()) + SetHasMCData(); + } + - fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 2, 0, 2); // Number of Events neccessary for the analysis and not a QA histogram + fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 5, -0.5, 4.5); // Number of Events neccessary for the analysis and not a QA histogram if(!fOutput) fOutput = new TList; // Initialize correction Framework and Cuts fCFM = new AliCFManager; @@ -217,56 +312,174 @@ void AliAnalysisTaskDCA::CreateOutputObjects(){ fCuts->CreateStandardCuts(); } - fCuts->SetCutITSpixel(fPixelStatus); fCuts->Initialize(fCFM); + if(!fHFEpid) printf("hallo, fHFEpid is not available\n"); + + if(fHFEpid && GetPlugin(kHFEpid)) { + fHFEpid->SetHasMCData(HasMCData()); + if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC"); + if(fPIDstrategy) + fHFEpid->InitializePID(Form("Strategy%d", fPIDstrategy)); + else + fHFEpid->InitializePID(fPIDdetectors.Data()); // Only restrictions to TPC allowed + } // dca study---------------------------------- + + if(!fDCA) fDCA = new AliHFEdca; if(!fResidualList) fResidualList = new TList(); if(!fPullList) fPullList = new TList(); - - fDCA->CreateHistogramsResidual(fResidualList); - fDCA->CreateHistogramsPull(fPullList); + if(!fDcaList) fDcaList = new TList(); + if(!fKfDcaList) fKfDcaList = new TList(); + if(!fMcVertexList) fMcVertexList = new TList(); + if(!fDataDcaList) fDataDcaList = new TList(); + if(!fDataVertexList) fDataVertexList = new TList(); + if(!fDataPullList) fDataPullList = new TList(); + if(!fMcPidList) fMcPidList = new TList(); + if(!fDataPidList) fDataPidList = new TList(); - // add output objects to the List - fOutput->AddAt(fResidualList,0); - fOutput->AddAt(fPullList,1); + if(!fHfeDcaList) fHfeDcaList = new TList(); + if(!fHfeDataDcaList) fHfeDataDcaList = new TList(); + + if(HasMCData()) { + if(GetPlugin(kImpactPar) ) { + fDCA->CreateHistogramsResidual(fResidualList); + fDCA->CreateHistogramsPull(fPullList); + fDCA->CreateHistogramsDca(fDcaList); + fOutput->AddAt(fResidualList,0); + fOutput->AddAt(fPullList,1); + fOutput->AddAt(fDcaList,2); + } + if(GetPlugin(kKFdca)){ + fDCA->CreateHistogramsKfDca(fKfDcaList); + fOutput->AddAt(fDcaList,3); + } + if(GetPlugin(kPrimVtx)){ + fDCA->CreateHistogramsVertex(fMcVertexList); + fOutput->AddAt(fMcVertexList,4); + } + if(GetPlugin(kCombinedPid)){ + fDCA->CreateHistogramsPid(fMcPidList); + fOutput->AddAt(fMcPidList, 5); + } + if(GetPlugin(kHFEpid)){ + fDCA->CreateHistogramsHfeDca(fHfeDcaList); + fOutput->AddAt(fHfeDcaList, 6); + } + } // mc case + + if(!HasMCData()) { + + if(GetPlugin(kPrimVtx)){ + fDCA->CreateHistogramsDataVertex(fDataVertexList); + fOutput->AddAt(fDataVertexList,0); + } + + if(GetPlugin(kCombinedPid)){ + fDCA->CreateHistogramsDataDca(fDataDcaList); + fDCA->CreateHistogramsDataPull(fDataPullList); + fDCA->CreateHistogramsDataPid(fDataPidList); + fOutput->AddAt(fDataDcaList,1); + fOutput->AddAt(fDataPullList,2); + fOutput->AddAt(fDataPidList, 3); + } + if(GetPlugin(kHFEpid)){ + fDCA->CreateHistogramsHfeDataDca(fHfeDataDcaList); + fOutput->AddAt(fHfeDataDcaList, 4); + } + + + } // data case + } //____________________________________________________________ -void AliAnalysisTaskDCA::Exec(Option_t *){ +void AliAnalysisTaskDCA::UserExec(Option_t *){ // // Run the analysis // AliDebug(3, "Processing ESD events"); - if(!fESD){ - AliError("No ESD Event"); + if(!fInputEvent){ + AliError("Reconstructed Event not available"); return; } - if(!fMC){ - AliError("No MC Event"); - return; + if(HasMCData()){ + AliDebug(4, Form("MC Event: %p", fMCEvent)); + if(!fMCEvent){ + AliError("No MC Event, but MC Data required"); + return; + } } + if(!fCuts){ AliError("HFE cuts not available"); return; } + + + // protection + if(IsESDanalysis() && HasMCData()){ + // Protect against missing MC trees + AliMCEventHandler *mcH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()); + if(!mcH->InitOk()) return; + if(!mcH->TreeK()) return; + if(!mcH->TreeTR()) return; + } + + if(!IsAODanalysis()) { + AliESDInputHandler *inH = dynamic_cast(fInputHandler); + AliESDpid *workingPID = inH->GetESDpid(); + if(workingPID){ + AliDebug(1, "Using ESD PID from the input handler"); + fHFEpid->SetESDpid(workingPID); + } else { + AliDebug(1, "Using default ESD PID"); + fHFEpid->SetESDpid(fDefaultPID); + } + ProcessDcaAnalysis(); + } + + + PostData(1, fNEvents); + PostData(2, fOutput); +} +//____________________________________________________________ +void AliAnalysisTaskDCA::ProcessDcaAnalysis(){ // // Loop ESD // + + AliMCEvent *fMC = 0x0; + AliESDEvent *fESD = dynamic_cast(fInputEvent); + if(HasMCData())fMC = dynamic_cast(fMCEvent); + + if(!fESD){ + AliError("ESD Event required for ESD Analysis") + return; + } + + fNEvents->Fill(1); // original event number before cut + fDCA->ApplyExtraCuts(fESD,fMinNprimVtxContrbutor); // cut on primVtx contributors + fNEvents->Fill(3); // events number after cut + AliESDtrack *track = 0x0; + AliMCParticle *mctrack = 0x0; + fCFM->SetRecEventInfo(fESD); + // event cut level if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return; for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){ - + track = fESD->GetTrack(itrack); + if(HasMCData())mctrack = dynamic_cast(fMC->GetTrack(TMath::Abs(track->GetLabel()))); // RecPrim: primary cuts if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue; @@ -275,20 +488,61 @@ void AliAnalysisTaskDCA::Exec(Option_t *){ // HFEcuts: ITS layers cuts if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue; - if(track->GetITSclusters(0)<=fNclustersITS) continue; // require 6 hits on all pixel layers - - if(GetPlugin(kImpactPar)) { - // Printf("analysis on impact parameter is ON"); - fDCA->FillHistograms(fESD, track, fMC); - } + if(track->GetITSclusters(0)<=fNclustersITS) continue; // require number of ITS clusters - } - fNEvents->Fill(1); - - PostData(0, fNEvents); - PostData(1, fOutput); + // track accepted, do PID + AliHFEpidObject hfetrack; + hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; + hfetrack.fRecTrack = track; + if(HasMCData()) hfetrack.fMCtrack = mctrack; + + if(HasMCData()){ + if(GetPlugin(kPrimVtx)) + fDCA->FillHistogramsVtx(fESD, fMC); + if(GetPlugin(kImpactPar)) + fDCA->FillHistogramsDca(fESD, track, fMC); + if(GetPlugin(kKFdca)) + fDCA->FillHistogramsKfDca(fESD, track, fMC); + if(GetPlugin(kCombinedPid)) + fDCA->FillHistogramsPid(track, fMC); + if(GetPlugin(kHFEpid)) { + if(fHFEpid->IsSelected(&hfetrack)) + fDCA->FillHistogramsHfeDca(fESD, track, fMC); + } // plugin for hfepid + } // MC + + if(!HasMCData()){ + if(GetPlugin(kPrimVtx)) + fDCA->FillHistogramsDataVtx(fESD); + if(GetPlugin(kCombinedPid)) { + + // method from Andrea D 28.05.2010 + AliVertexerTracks *vertexer = new AliVertexerTracks(fESD->GetMagneticField()); + vertexer->SetITSMode(); + vertexer->SetMinClusters(fNclustersITS); + Int_t skipped[2]; + skipped[0] = (Int_t)track->GetID(); + vertexer->SetSkipTracks(1,skipped); + AliESDVertex *vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESD); + delete vertexer; vertexer = NULL; + if(vtxESDSkip->GetNContributors()FillHistogramsDataDca(fESD, track, vtxESDSkip); + fDCA->FillHistogramsDataPid(track); + } + if(GetPlugin(kHFEpid)) { + if(fHFEpid->IsSelected(&hfetrack)) { + // printf("Found an electron in p+p collision! from HFE pid \n"); + fDCA->FillHistogramsHfeDataDca(fESD, track); + } + } // plugin for hfepid + } // data case + + } // track loop + } + //____________________________________________________________ void AliAnalysisTaskDCA::Terminate(Option_t *){ // @@ -316,13 +570,6 @@ void AliAnalysisTaskDCA::Load(TString filename){ return; } - /* - TH1 *htmp = dynamic_cast(input->Get("nEvents")); - if(htmp) - fNEvents = dynamic_cast(htmp->Clone()); - else - AliError("Event Counter histogram not found"); - */ input->Close(); delete input; @@ -335,7 +582,7 @@ void AliAnalysisTaskDCA::PostProcess(){ // should do fitting here for dca resolution // moved to an external macro to do the job - Load("impactPar.root"); + Load("HFEdca.root"); TCanvas *c1 = new TCanvas("c1", "number of analyzed events", 300, 400); fNEvents->Draw(); c1->SaveAs("temp.png"); @@ -352,8 +599,14 @@ void AliAnalysisTaskDCA::PrintStatus() const { // Print Analysis status // printf("\n\tAnalysis Settings\n\t========================================\n"); - printf("\timpact parameter analysis is %s\n", GetPlugin(kImpactPar)?"ON":"OFF"); - printf("\tcuts: %s\n", (fCuts != NULL) ? "YES" : "NO"); + printf("\t Running on %s\n", !HasMCData()?"p+p collision data":"MC sample"); + printf("\t Cuts: %s\n", (fCuts != NULL) ? "YES" : "NO"); + printf("\t Impact parameter analysis is %s\n", GetPlugin(kImpactPar)?"ON":"OFF"); + printf("\t Using AliKFParticle for analysis? %s\n", GetPlugin(kKFdca)?"ON":"OFF"); + printf("\t Primary vertex analysis is %s\n", GetPlugin(kPrimVtx)?"ON":"OFF"); + printf("\t Combined pid analysis is %s\n", GetPlugin(kCombinedPid)?"ON":"OFF"); + printf("\t HFE pid analysis is %s\n", GetPlugin(kHFEpid)?"ON":"OFF"); + printf("\t Post process analysis is %s\n", GetPlugin(kPostProcess)?"ON":"OFF"); printf("\t "); printf("\n"); } @@ -367,10 +620,22 @@ void AliAnalysisTaskDCA::SwitchOnPlugin(Int_t plug){ // - Post Processing switch(plug){ + case kPostProcess: + SETBIT(fPlugins, plug); + break; case kImpactPar: SETBIT(fPlugins, plug); break; - case kPostProcess: + case kPrimVtx: + SETBIT(fPlugins, plug); + break; + case kCombinedPid: + SETBIT(fPlugins, plug); + break; + case kHFEpid: + SETBIT(fPlugins, plug); + break; + case kKFdca: SETBIT(fPlugins, plug); break; default: @@ -423,7 +688,18 @@ void AliAnalysisTaskDCA::MakeParticleContainer(){ } - // add more containers for correction purpose - +} +//____________________________________________________________ +void AliAnalysisTaskDCA::AddPIDdetector(TString detector){ + + // + // Adding PID detector to the task + // + + if(!fPIDdetectors.Length()) + fPIDdetectors = detector; + else + fPIDdetectors += ":" + detector; } + diff --git a/PWG3/hfe/AliAnalysisTaskDCA.h b/PWG3/hfe/AliAnalysisTaskDCA.h index e6c2b0a548b..5c746b0dfba 100644 --- a/PWG3/hfe/AliAnalysisTaskDCA.h +++ b/PWG3/hfe/AliAnalysisTaskDCA.h @@ -20,32 +20,36 @@ #ifndef ALIANALYSISTASKDCA_H #define ALIANALYSISTASKDCA_H - -#ifndef ALIANALYSISTASK_H -#include "AliAnalysisTask.h" +#ifndef ALIANALYSISTASKSE_H +#include "AliAnalysisTaskSE.h" #endif class TH1I; class TH1F; class TList; class AliLog; - class AliCFManager; class AliESDEvent; class AliESDtrackCuts; class AliMCEvent; class AliVParticle; +class AliVEvent; +class AliVertexerTracks; class AliHFEpid; class AliHFEcuts; class AliHFEextraCuts; -class AliAnalysisTaskDCA : public AliAnalysisTask{ +class AliAnalysisTaskDCA : public AliAnalysisTaskSE{ public: typedef enum{ kPostProcess = 0, - kImpactPar = 1 + kImpactPar = 1, + kPrimVtx = 2, + kCombinedPid = 3, + kHFEpid = 4, + kKFdca = 5 }Switches_t; enum{ @@ -59,9 +63,8 @@ class AliAnalysisTaskDCA : public AliAnalysisTask{ AliAnalysisTaskDCA& operator=(const AliAnalysisTaskDCA &ref); virtual ~AliAnalysisTaskDCA(); - virtual void ConnectInputData(Option_t *); - virtual void CreateOutputObjects(); - virtual void Exec(Option_t *); + virtual void UserCreateOutputObjects(); + virtual void UserExec(Option_t *); virtual void Terminate(Option_t *); @@ -70,14 +73,21 @@ class AliAnalysisTaskDCA : public AliAnalysisTask{ void PostProcess(); void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; }; - void SetPixelStatus(Int_t pixelStatus){ fPixelStatus = pixelStatus;}; void SetNclustersITS(Int_t nITSclusters){ fNclustersITS = nITSclusters;}; - + void SetMinPrimVtxContrib( Int_t nPrimVtxContrib){ fMinNprimVtxContrbutor = nPrimVtxContrib; }; + Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); }; void SwitchOnPlugin(Int_t plug); - + + Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); }; + Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); }; Bool_t HasMCData() const { return TestBit(kHasMCdata); } void SetHasMCData(Bool_t hasMC = kTRUE) { SetBit(kHasMCdata, hasMC); }; + + void SetPIDdetectors(Char_t * const detectors){ fPIDdetectors = detectors; } + void SetPIDStrategy(UInt_t strategy) { fPIDstrategy = strategy; } + void AddPIDdetector(TString detector); + void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); }; void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); }; @@ -85,24 +95,40 @@ class AliAnalysisTaskDCA : public AliAnalysisTask{ private: void MakeParticleContainer(); - UShort_t fPlugins; // Enabled Plugins - AliESDEvent *fESD; //! The ESD Event - AliMCEvent *fMC; //! The MC Event + void ProcessDcaAnalysis(); + + UShort_t fPlugins; // Enabled Plugins + AliHFEcuts *fCuts; // Cut Collection - AliHFEcuts *fCuts; // Cut Collection - AliCFManager *fCFM; //! Correction Framework Manager - AliHFEdca *fDCA; // fDCA - - - Int_t fPixelStatus; // pixel layer - Int_t fNclustersITS; // ITS clusters - - TH1I *fNEvents; //! counter for the number of Events - TList *fResidualList; //! histograms for the residuals - TList *fPullList; //! histograms for the pull - TList *fOutput; //! Container for Task Output + AliESDpid *fDefaultPID; //! Default ESD PID + AliHFEpid *fHFEpid; //! PID + TString fPIDdetectors; // Detectors for Particle Identification + UInt_t fPIDstrategy; // PID Strategy + + AliCFManager *fCFM; //! Correction Framework Manager + AliHFEdca *fDCA; // fDCA - ClassDef(AliAnalysisTaskDCA, 1); // The DCA Analysis Task + Int_t fNclustersITS; // ITS clusters + Int_t fMinNprimVtxContrbutor; // minimum number of primary contributors + + TH1I *fNEvents; //! counter for the number of Events + TList *fResidualList; //! histograms for the residuals + TList *fPullList; //! histograms for the pull + TList *fDcaList; //! histograms for the dca + TList *fKfDcaList; //! histograms for the kf dca + TList *fMcVertexList; //! histograms for the MC vertex + TList *fDataDcaList; //! histograms for the data dca + TList *fDataVertexList; //! histograms for the data vertex + TList *fDataPullList; //! histograms for the data pull + TList *fMcPidList; //! pid - MC: ESD combined pid + TList *fDataPidList; //! pid -Data: ESD combined pid + + TList *fHfeDcaList; //! hfe pid: mc dca + TList *fHfeDataDcaList; //! hfe pid: data dca + + TList *fOutput; //! Container for Task Output + + ClassDef(AliAnalysisTaskDCA, 1); // The DCA Analysis Task }; #endif diff --git a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx index 1721ab655eb..3132add1fc1 100644 --- a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx +++ b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.cxx @@ -20,6 +20,7 @@ // // Authors: // Hongyan Yang +// Carlo Bombonati // #include @@ -33,56 +34,62 @@ #include #include #include - #include #include "AliCFManager.h" #include "AliMCEvent.h" #include "AliMCEventHandler.h" +#include "AliMCParticle.h" +#include "AliStack.h" + #include "AliESDEvent.h" #include "AliESDInputHandler.h" #include "AliESDtrack.h" -#include "AliAnalysisManager.h" -#include "AliMCParticle.h" +#include "AliESDpid.h" +#include "AliAnalysisManager.h" #include "AliHFEpid.h" #include "AliHFEcuts.h" +#include "AliHFEtools.h" #include "AliHFEdisplacedElectrons.h" - #include "AliAnalysisTaskDisplacedElectrons.h" //____________________________________________________________ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(): AliAnalysisTaskSE("Task for displaced electron study") - , fDebugLevel(0) - , fPIDdetectors("") - , fPIDstrategy(0) - , fPlugins(0) - , fESD(0x0) - , fMC(0x0) - , fCuts(0x0) - , fPID(0x0) - , fCFM(0x0) - , fNEvents(0x0) - , fElectronsPt(0x0) - , fOutput(0x0) - , fCorrection(0x0) + , fDeDebugLevel(0) + , fNminITSCluster(0) + , fNminPrimVtxContrib(0) + , fDePIDdetectors("") + , fDePIDstrategy(0) + , fDePlugins(0) + , fDeCuts(0x0) + , fDeDefaultPID(0x0) + , fDePID(0x0) + , fDeCFM(0x0) , fDisplacedElectrons(0x0) + , fDeNEvents(0x0) + , fElectronsMcPt(0x0) + , fElectronsEsdPt(0x0) + , fElectronsDataPt(0x0) + , fDeCorrection(0x0) + , fDeQA(0x0) , fHistDisplacedElectrons(0x0) { // // Dummy constructor // DefineInput(0, TChain::Class()); - DefineOutput(2, TList::Class()); // output - DefineOutput(1, TList::Class()); // output + DefineOutput(1, TList::Class()); // displacedElectron + DefineOutput(2, TList::Class()); // correction framework + DefineOutput(3, TList::Class()); // QA - SetHasMCData(); - // Initialize pid - fPID = new AliHFEpid; + + fDeDefaultPID = new AliESDpid; + fDePID = new AliHFEpid; } @@ -90,49 +97,59 @@ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(): //____________________________________________________________ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(const char * name): AliAnalysisTaskSE(name) - , fDebugLevel(0) - , fPIDdetectors("") - , fPIDstrategy(0) - , fPlugins(0) - , fESD(0x0) - , fMC(0x0) - , fCuts(0x0) - , fPID(0x0) - , fCFM(0x0) - , fNEvents(0x0) - , fElectronsPt(0x0) - , fOutput(0x0) - , fCorrection(0x0) + , fDeDebugLevel(0) + , fNminITSCluster(0) + , fNminPrimVtxContrib(0) + , fDePIDdetectors("") + , fDePIDstrategy(0) + , fDePlugins(0) + , fDeCuts(0x0) + , fDeDefaultPID(0x0) + , fDePID(0x0) + , fDeCFM(0x0) , fDisplacedElectrons(0x0) + , fDeNEvents(0x0) + , fElectronsMcPt(0x0) + , fElectronsEsdPt(0x0) + , fElectronsDataPt(0x0) + , fDeCorrection(0x0) + , fDeQA(0x0) , fHistDisplacedElectrons(0x0) { // // Default constructor // DefineInput(0, TChain::Class()); - DefineOutput(2, TList::Class()); DefineOutput(1, TList::Class()); + DefineOutput(2, TList::Class()); + DefineOutput(3, TList::Class()); + + // Initialize pid + fDeDefaultPID = new AliESDpid; + fDePID = new AliHFEpid; - SetHasMCData(); } //____________________________________________________________ AliAnalysisTaskDisplacedElectrons::AliAnalysisTaskDisplacedElectrons(const AliAnalysisTaskDisplacedElectrons &ref): AliAnalysisTaskSE(ref) - , fDebugLevel(ref.fDebugLevel) - , fPIDdetectors(ref.fPIDdetectors) - , fPIDstrategy(ref.fPIDstrategy) - , fPlugins(ref.fPlugins) - , fESD(ref.fESD) - , fMC(ref.fMC) - , fCuts(ref.fCuts) - , fPID(ref.fPID) - , fCFM(ref.fCFM) - , fNEvents(ref.fNEvents) - , fElectronsPt(ref.fElectronsPt) - , fOutput(ref.fOutput) - , fCorrection(ref.fCorrection) + , fDeDebugLevel(ref.fDeDebugLevel) + , fNminITSCluster(ref.fNminITSCluster) + , fNminPrimVtxContrib(ref.fNminPrimVtxContrib) + , fDePIDdetectors(ref.fDePIDdetectors) + , fDePIDstrategy(ref.fDePIDstrategy) + , fDePlugins(ref.fDePlugins) + , fDeCuts(ref.fDeCuts) + , fDeDefaultPID(ref.fDeDefaultPID) + , fDePID(ref.fDePID) + , fDeCFM(ref.fDeCFM) , fDisplacedElectrons(ref.fDisplacedElectrons) + , fDeNEvents(ref.fDeNEvents) + , fElectronsMcPt(ref.fElectronsMcPt) + , fElectronsEsdPt(ref.fElectronsEsdPt) + , fElectronsDataPt(ref.fElectronsDataPt) + , fDeCorrection(ref.fDeCorrection) + , fDeQA(ref.fDeQA) , fHistDisplacedElectrons(ref.fHistDisplacedElectrons) { // @@ -147,19 +164,23 @@ AliAnalysisTaskDisplacedElectrons &AliAnalysisTaskDisplacedElectrons::operator=( // if(this == &ref) return *this; AliAnalysisTask::operator=(ref); - fDebugLevel = ref.fDebugLevel; - fPIDdetectors = ref.fPIDdetectors; - fPIDstrategy = ref.fPIDstrategy; - fPlugins = ref.fPlugins; - fESD = ref.fESD; - fMC = ref.fMC; - fPID = ref.fPID; - fCuts = ref.fCuts; - fCFM = ref.fCFM; - fNEvents = ref.fNEvents; - fOutput = ref.fOutput; - fCorrection = ref.fCorrection; + fDeDebugLevel = ref.fDeDebugLevel; + fNminITSCluster = ref.fNminITSCluster; + fNminPrimVtxContrib = ref.fNminPrimVtxContrib; + fDePIDdetectors = ref.fDePIDdetectors; + fDePIDstrategy = ref.fDePIDstrategy; + fDePlugins = ref.fDePlugins; + fDeDefaultPID = ref.fDeDefaultPID; + fDePID = ref.fDePID; + fDeCuts = ref.fDeCuts; + fDeCFM = ref.fDeCFM; fDisplacedElectrons = ref.fDisplacedElectrons; + fDeNEvents = ref.fDeNEvents; + fElectronsMcPt = ref.fElectronsMcPt; + fElectronsEsdPt = ref.fElectronsEsdPt; + fElectronsDataPt = ref.fElectronsDataPt; + fDeCorrection = ref.fDeCorrection; + fDeQA = ref.fDeQA; fHistDisplacedElectrons = ref.fHistDisplacedElectrons; return *this; @@ -171,101 +192,105 @@ AliAnalysisTaskDisplacedElectrons::~AliAnalysisTaskDisplacedElectrons(){ // Destructor // - if(fPID) delete fPID; - - if(fESD) delete fESD; - if(fMC) delete fMC; - - if(fCFM) delete fCFM; - - if(fNEvents) delete fNEvents; - - if(fElectronsPt) delete fElectronsPt; - - if(fOutput){ - fOutput->Clear(); - delete fOutput; + if(fDeDefaultPID) delete fDeDefaultPID; + if(fDePID) delete fDePID; + if(fDeCFM) delete fDeCFM; + if(fDisplacedElectrons) delete fDisplacedElectrons; + + if(fDeNEvents) delete fDeNEvents; + if(fElectronsMcPt) delete fElectronsMcPt; + if(fElectronsEsdPt) delete fElectronsEsdPt; + if(fElectronsDataPt) delete fElectronsDataPt; + if(fDeCorrection){ + fDeCorrection->Clear(); + delete fDeCorrection; } - - - if(fCorrection){ - fCorrection->Clear(); - delete fCorrection; + if(fDeQA){ + fDeQA->Clear(); + delete fDeQA; } - - if(fDisplacedElectrons) delete fDisplacedElectrons; - if(fHistDisplacedElectrons){ fHistDisplacedElectrons->Clear(); delete fHistDisplacedElectrons; } - - } //____________________________________________________________ void AliAnalysisTaskDisplacedElectrons::UserCreateOutputObjects(){ // create output objects - // fNEvents + // fDeNEvents // MC and Data containers - fNEvents = new TH1I("nEvents", "Number of Events in the Analysis", 2, 0, 2); + + if(!fDeQA) fDeQA = new TList; + fDeQA->SetName("variousQAhistograms"); + + fDeNEvents = new TH1I("nDeEvents", "Number of Events in the DE Analysis", 2, 0, 2); const Int_t nBins = 14; const Float_t ptBins[nBins] = {0.0,0.5,1.0,1.5,2.0,2.5,3.0,4.0,5.0,7.0,9.0,12.0,16.0,20.0}; - fElectronsPt = new TH1F("esdPt", "p_{T} distribution of identified electrons (HFEpid);p_{T} (GeV/c);dN/dp_{T};", nBins-1, ptBins); - if(!fOutput) fOutput = new TList; - fOutput->SetName("results"); - fOutput->AddAt(fElectronsPt,0); - fOutput->AddAt(fNEvents,1); + fElectronsMcPt = new TH1F("mcElectronPt", "MC: p_{T} distribution of identified electrons (mcpid);p_{T} (GeV/c);Counts;", nBins-1, ptBins); + fElectronsEsdPt = new TH1F("esdElectronPt", "ESD: p_{T} distribution of identified electrons (hfepid);p_{T} (GeV/c);Counts;", nBins-1, ptBins); + fElectronsDataPt = new TH1F("dataElectronPt", "DATA: p_{T} distribution of identified electrons (hfepid);p_{T} (GeV/c);Counts;", nBins-1, ptBins); + + fDeQA->AddAt(fDeNEvents,0); + if(HasMCData()){ + fDeQA->AddAt(fElectronsMcPt, 1); + fDeQA->AddAt(fElectronsEsdPt, 2); + } + else + fDeQA->AddAt(fElectronsDataPt, 1); + // Initialize correction Framework and Cuts - fCFM = new AliCFManager; + fDeCFM = new AliCFManager; MakeEventContainer(); MakeParticleContainer(); - if(!fCorrection) fCorrection = new TList(); - fCorrection->SetName("corrections"); - fCorrection->AddAt(fCFM->GetEventContainer(), 0); - fCorrection->AddAt(fCFM->GetParticleContainer(), 1); - fCorrection->Print(); - - // Temporary fix: Initialize particle cuts with 0x0 - for(Int_t istep = 0; istep < fCFM->GetEventContainer()->GetNStep(); istep++) - fCFM->SetEventCutsList(istep, 0x0); - for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++) - fCFM->SetParticleCutsList(istep, 0x0); - if(!fCuts){ + if(!fDeCorrection) fDeCorrection = new TList(); + fDeCorrection->SetName("deCorrections"); + fDeCorrection->AddAt(fDeCFM->GetEventContainer(), 0); + fDeCorrection->AddAt(fDeCFM->GetParticleContainer(), 1); + fDeCorrection->Print(); + + for(Int_t istep = 0; istep < fDeCFM->GetEventContainer()->GetNStep(); istep++) + fDeCFM->SetEventCutsList(istep, 0x0); + for(Int_t istep = 0; istep < fDeCFM->GetParticleContainer()->GetNStep(); istep++) + fDeCFM->SetParticleCutsList(istep, 0x0); + + if(!fDeCuts){ AliWarning("Cuts not available. Default cuts will be used"); - fCuts = new AliHFEcuts; - fCuts->CreateStandardCuts(); - + fDeCuts = new AliHFEcuts; + fDeCuts->CreateStandardCuts(); } - fCuts->SetCutITSpixel(AliHFEextraCuts::kBoth); + fDeCuts->Initialize(fDeCFM); - fCuts->Initialize(fCFM); - - fPID->SetHasMCData(HasMCData()); - if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC"); - if(fPIDstrategy) - fPID->InitializePID(Form("Strategy%d", fPIDstrategy)); + if(GetPlugin(kDePidQA)){ + AliInfo("PID QA switched on"); + // fPID->SetDebugLevel(2); + fDePID->SetQAOn(); + fDeQA->Add(fDePID->GetQAhistograms()); + } + + fDePID->SetHasMCData(HasMCData()); + if(!fDePIDdetectors.Length() && ! fDePIDstrategy) AddPIDdetector("TPC"); + if(fDePIDstrategy) + fDePID->InitializePID(Form("Strategy%d", fDePIDstrategy)); else - fPID->InitializePID(fPIDdetectors.Data()); // Only restrictions to TPC allowed - + fDePID->InitializePID(fDePIDdetectors.Data()); // Only restrictions to TPC allowed + // displaced electron study---------------------------------- if(GetPlugin(kDisplacedElectrons)){ fDisplacedElectrons = new AliHFEdisplacedElectrons; - fDisplacedElectrons->SetDebugLevel(fDebugLevel); + fDisplacedElectrons->SetDebugLevel(fDeDebugLevel); fDisplacedElectrons->SetHasMCData(HasMCData()); - + fDisplacedElectrons->SetMinPrimVtxContrib(fNminPrimVtxContrib); + fDisplacedElectrons->SetNitsCluster(fNminITSCluster); + if(!fHistDisplacedElectrons) fHistDisplacedElectrons = new TList(); - fDisplacedElectrons->CreateOutputs(fHistDisplacedElectrons); - - fOutput->AddAt(fHistDisplacedElectrons, 2); } - - + } @@ -276,224 +301,368 @@ void AliAnalysisTaskDisplacedElectrons::UserExec(Option_t *){ // Run the analysis // - AliESDInputHandler *esdH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); - if(!esdH){ - AliError("No ESD input handler"); + if(fDeDebugLevel>=10) AliInfo("analyse single event"); + + if(!fInputEvent){ + AliError("Reconstructed Event not available"); return; - } else { - fESD = esdH->GetEvent(); } - AliMCEventHandler *mcH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()); - if(!mcH){ - AliError("No MC truth handler"); - return; - } else { - fMC = mcH->MCEvent(); - } - - if(fDebugLevel>=5)AliInfo("Processing ESD events"); - if(!fESD){ - AliError("No ESD Event"); - return; - } + // + AliESDInputHandler *inH = dynamic_cast(fInputHandler); + // pure MC analysis: + if(HasMCData()){ - if(fDebugLevel>=5)AliInfo(Form("MC Event: %p", fMC)); - if(!fMC){ + // Protect against missing MC trees + AliMCEventHandler *mcH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()); + if(!mcH->InitOk()) return; + if(!mcH->TreeK()) return; + if(!mcH->TreeTR()) return; + + AliDebug(4, Form("MC Event: %p", fMCEvent)); + if(!fMCEvent){ AliError("No MC Event, but MC Data required"); return; } + + ProcessMC(); } - if(!fCuts){ + + + // from now on, only ESD are analyzed + // using HFE pid, using HFE cuts + // using CORRFW + + AliESDpid *workingPID = inH->GetESDpid(); + if(workingPID){ + AliDebug(1, "Using ESD PID from the input handler"); + fDePID->SetESDpid(workingPID); + } else { + AliDebug(1, "Using default ESD PID"); + fDePID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); + } + + if(!fDeCuts){ AliError("HFE cuts not available"); return; } + + // ESD case with MC + if(HasMCData() && IsESDanalysis()) { + // Protect against missing MC trees + AliMCEventHandler *mcH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()); + if(!mcH->InitOk()) return; + if(!mcH->TreeK()) return; + if(!mcH->TreeTR()) return; + + AliDebug(4, Form("MC Event: %p", fMCEvent)); + if(!fMCEvent){ + AliError("No MC Event, but MC Data required"); + return; + } + + ProcessESD(); + } + + // now only for data ESDs without MC + if(!HasMCData() && IsESDanalysis()) { + ProcessData(); + } + + fDeNEvents->Fill(1); + PostData(1, fHistDisplacedElectrons); + PostData(2, fDeCorrection); + PostData(3, fDeQA); + +} + +//____________________________________________________________ +void AliAnalysisTaskDisplacedElectrons::ProcessMC(){ + // + // handel pure MC analysis + // + + Int_t nMCelectrons = 0; + AliESDEvent *fESD = dynamic_cast(fInputEvent); + + Double_t mcContainer[4]; // container for the output in THnSparse + memset(mcContainer, 0, sizeof(Double_t) * 4); + + fDeCFM->SetMCEventInfo(fMCEvent); + + Double_t nContributor = 0; + const AliVVertex *mcPrimVtx = fMCEvent->GetPrimaryVertex(); + if(mcPrimVtx) nContributor = mcPrimVtx->GetNContributors(); + + // + // cut at MC event level + // + + if(!fDeCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) return; + if(GetPlugin(kCorrection)) fDeCFM->GetEventContainer()->Fill(&nContributor,AliHFEcuts::kEventStepGenerated); + + AliStack *stack = 0x0; + + if(!fMCEvent->Stack())return; + stack = fMCEvent->Stack(); + Int_t nTracks = stack->GetNtrack(); + + AliMCParticle *mcTrack = 0x0; + + for(Int_t itrack = 0; itrackParticle(itrack))) continue; + if(mcTrack)mcTrack = 0x0; + mcTrack= dynamic_cast(fMCEvent->GetTrack(itrack)); + //TParticle *mcPart = stack->Particle(itrack); + + mcContainer[0] = mcTrack->Pt(); + mcContainer[1] = mcTrack->Eta(); + mcContainer[2] = mcTrack->Phi(); + mcContainer[3] = mcTrack->Charge(); + + + + if (!stack->IsPhysicalPrimary(mcTrack->GetLabel())) continue; + // no cut but require primary + if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(mcContainer, 0); + + // all pions for reference + if(TMath::Abs(mcTrack->Particle()->GetPdgCode())==AliHFEdisplacedElectrons::kPDGpion && GetPlugin(kCorrection)) + fDeCFM->GetParticleContainer()->Fill(mcContainer, 1); + + // cut for signal: all MC electrons + if(TMath::Abs(mcTrack->Particle()->GetPdgCode())==AliHFEdisplacedElectrons::kPDGelectron && GetPlugin(kCorrection)) + fDeCFM->GetParticleContainer()->Fill(mcContainer, 2); + + // cut at track level kinematics: pt and eta + if(TMath::Abs(mcContainer[1])>=0.8 || mcContainer[0]>20 || mcContainer[0]<0.1) continue; + + if(TMath::Abs(mcTrack->Particle()->GetPdgCode())==AliHFEdisplacedElectrons::kPDGelectron){ + nMCelectrons++; + fElectronsMcPt->Fill(mcContainer[0]); + } + + if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(mcContainer, 3); + + + // fill MC THnSparse + fDisplacedElectrons->FillMcOutput(fESD, fMCEvent, mcTrack); + + } // mc track loop + + if(fDeDebugLevel>=10) printf("there are %d electrons in this MC event", nMCelectrons); + +} + +//____________________________________________________________ +void AliAnalysisTaskDisplacedElectrons::ProcessESD(){ + + // this is to handel ESD tracks with MC information + // MC pid is only used when HFE pid is implemented, for comparison + // corrections are taken into account // process data: ESD tracks with MC information - Double_t container[8]; // container for the output in THnSparse - memset(container, 0, sizeof(Double_t) * 8); - Bool_t signal = kTRUE; + Double_t esdContainer[4]; // container for the output in THnSparse + memset(esdContainer, 0, sizeof(Double_t) * 4); + AliESDEvent *fESD = dynamic_cast(fInputEvent); + + fDeCFM->SetRecEventInfo(fESD); + Double_t nContrib = fESD->GetPrimaryVertex()->GetNContributors(); + Bool_t alreadyseen = kFALSE; LabelContainer cont(fESD->GetNumberOfTracks()); - - Int_t nElectrons=0; + Int_t nHFEelectrons=0; AliESDtrack *track = 0x0; - - Double_t nContrib = fESD->GetPrimaryVertex()->GetNContributors(); - if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return; - if(GetPlugin(kCorrection)){ - fCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed); - } - fCFM->SetRecEventInfo(fESD); + AliStack *stack = 0x0; + if(!(stack = fMCEvent->Stack()))return; + + // + // cut at ESD event level + // + if(!fDeCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return; + if(GetPlugin(kCorrection)) fDeCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed); + for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){ track = fESD->GetTrack(itrack); - // - // track quality cut: 1st step: ITS and TPC cut; 2nd step: Rec prim; 3rd step: hfe cut on ITS pixel layer - // - // require within rapidity range +/-0.9 - - // if((TMath::Abs(track->Eta()))>0.9) continue; - - if(GetPlugin(kDisplacedElectrons)) { - - // 1st cut - // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5 - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)){ - signal = kFALSE; - continue; - } - container[0] = track->Pt(); - container[1] = track->Eta(); - container[2] = track->Phi(); - container[3] = track->Charge(); + esdContainer[0] = track->Pt(); + esdContainer[1] = track->Eta(); + esdContainer[2] = track->Phi(); + esdContainer[3] = track->Charge(); - AliStack *stack = fMC->Stack(); - if(!stack) continue; + // before any cut + alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); + cont.Append(TMath::Abs(track->GetLabel())); // check double counting + if(alreadyseen) continue; // avoid double counting + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecNoCut); - AliMCParticle *mctrack = NULL; - if(HasMCData() ){ - mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))); - if(!mctrack) continue; - - container[4] = mctrack->Pt(); - container[5] = mctrack->Eta(); - container[6] = mctrack->Phi(); - container[7] = mctrack->Charge(); - - // if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE; - if(TMath::Abs(mctrack->Eta())>0.9) { - signal = kFALSE; - continue; - } // cut on kinematics - - } // has MC data - + // 1st track cut + // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5 + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecKineITSTPC); - if(signal && GetPlugin(kCorrection)){ - alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); // double counted track - cont.Append(TMath::Abs(track->GetLabel())); - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecKineITSTPC); - fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecKineITSTPC + 2*AliHFEcuts::kNcutStepsESDtrack); - if(alreadyseen) - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsESDtrack); - - } // fill correction --- 1st - - // second cut + // 2nd track cut // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) { - signal = kFALSE; - continue; - } - - if(signal) { - alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); - cont.Append(TMath::Abs(track->GetLabel())); - - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecPrim); - fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecPrim + 2*AliHFEcuts::kNcutStepsESDtrack); - if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsESDtrack); - } - } + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepRecPrim); - // third cut + // 3rd track cut // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)){ - signal = kFALSE; - continue; - } - - if(signal) { - alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); - cont.Append(TMath::Abs(track->GetLabel())); - - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepHFEcutsITS); - fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepHFEcutsITS + 2*AliHFEcuts::kNcutStepsESDtrack); - if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsESDtrack); - } - } + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue; + if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsITS); + + /* + // 4th track cut + // TRD: number of tracklets in TRD + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepHFEcutsTRD); + */ - fDisplacedElectrons->FillMCOutput(fESD, track, stack); - - // track accepted, do PID --> only electron candidate will be processed + // 5th track cut + // track accepted, do PID + // --> only electron candidate will be processed AliHFEpidObject hfetrack; hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; hfetrack.fRecTrack = track; - if((fPID->IsSelected(&hfetrack)==kTRUE)) - if(fDebugLevel>=10) - AliInfo(Form("ESD info: this particle is %s identified as electron by HFEpid method \n", (fPID->IsSelected(&hfetrack)==kTRUE)?" ":" NOT ")); - if(!fPID->IsSelected(&hfetrack)) continue; + // if(HasMCData())hfetrack.fMCtrack = mctrack; - // Fill Containers - - nElectrons++; - - fElectronsPt->Fill(track->Pt()); - - if(signal) { - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack); - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepPID); - if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[4], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack))); - } - } + if(!fDePID->IsSelected(&hfetrack)) continue; - fDisplacedElectrons->FillESDOutput(fESD, track); + else if(fDeDebugLevel>=10) + AliInfo("ESD info: this particle is identified as electron by HFEpid method \n"); + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(esdContainer, 1+AliHFEcuts::kStepPID); - } // analyze displaced electrons plugin switched on + // Fill Containers + nHFEelectrons++; + fElectronsEsdPt->Fill(esdContainer[0]); + fDisplacedElectrons->FillEsdOutput(fESD, track, stack); + + } // displaced electron analysis on ESD with MC plugin } // track loop + + if(fDeDebugLevel>=10) printf("there are %d HFE electrons in this ESD event", nHFEelectrons); + +} - if(fDebugLevel>=5) - AliInfo(Form("ESD info: number of electrons found in this event: %d\n", nElectrons)); - fNEvents->Fill(1); +//____________________________________________________________ +void AliAnalysisTaskDisplacedElectrons::ProcessData(){ + + // this is a track loop over real data + // no MC information at all + // HFE pid is used + + AliESDEvent *fESD = dynamic_cast(fInputEvent); + + Double_t dataContainer[4]; // container for the output in THnSparse + memset(dataContainer, 0, sizeof(Double_t) * 4); - PostData(1, fOutput); - PostData(2, fCorrection); + Bool_t alreadyseen = kFALSE; + LabelContainer cont(fESD->GetNumberOfTracks()); -} -//____________________________________________________________ -void AliAnalysisTaskDisplacedElectrons::Terminate(Option_t *){ - // - // Terminate not implemented at the moment - // + AliESDtrack *track = 0x0; + Int_t nHFEelectrons= 0; - if(GetPlugin(kDisplacedElectrons)) - { + fDeCFM->SetRecEventInfo(fESD); + Double_t nContrib = fESD->GetPrimaryVertex()->GetNContributors(); + if(!fDeCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fESD)) return; + if(GetPlugin(kCorrection)) fDeCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed); + + + for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){ + track = fESD->GetTrack(itrack); + + if(GetPlugin(kDisplacedElectrons)) { - fOutput = dynamic_cast(GetOutputData(1)); - fCorrection= dynamic_cast(GetOutputData(2)); - - if(!fOutput || !fCorrection){ - if(!fCorrection) AliError("correction list not available\n"); - if(!fOutput) AliError("output list not available\n"); - - return; - } + dataContainer[0] = track->Pt(); + dataContainer[1] = track->Eta(); + dataContainer[2] = track->Phi(); + dataContainer[3] = track->Charge(); + + alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); // double counted track + cont.Append(TMath::Abs(track->GetLabel())); + if(alreadyseen) continue; // avoid double counting + if(GetPlugin(kCorrection))fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], + 1+AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack); - fOutput->Print(); - fCorrection->Print(); + // 1st track cut + // RecKine: ITSTPC cuts : ITS & TPC refit, covmatrix: (2, 2, 0.5, 0.5, 2); min_tpccls: 50, chi2_tpccls: 3.5 + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], + 1+AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsESDtrack); - AliInfo("analysis done!\n"); + // 2nd track cut + // RecPrim: cut on track quality : DCA to vertex max: 3cm and 10cm; reject kink daughters + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], + 1+AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsESDtrack); + + // 3rd track cut + // HFEcuts: ITS layers cuts: ITS pixel layer: kFirst, kSecond, kBoth, kNone or kAny + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsITS, track)) continue; + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], + 1+AliHFEcuts::kStepHFEcutsITS + AliHFEcuts::kNcutStepsESDtrack); - } -} + /* + // 4th track cut + // TRD: number of tracklets in TRD0 + if(!fDeCFM->CheckParticleCuts(AliHFEcuts::kStepHFEcutsTRD, track)) continue; + if(GetPlugin(kCorrection)) if(HasMCData())fDeCFM->GetParticleContainer()->Fill(&dataContainer[4], + 1+AliHFEcuts::kStepHFEcutsTRD + AliHFEcuts::kNcutStepsESDtrack); + */ + + + // 5th track cut + // track accepted, do PID --> only electron candidate will be processed + AliHFEpidObject hfetrack; + hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; + hfetrack.fRecTrack = track; + // if(HasMCData())hfetrack.fMCtrack = mctrack; + + if(!fDePID->IsSelected(&hfetrack)) continue; + else if(fDeDebugLevel>=10) + AliInfo("ESD info: this particle is identified as electron by HFEpid method \n"); + if(GetPlugin(kCorrection)) fDeCFM->GetParticleContainer()->Fill(dataContainer, 1+AliHFEcuts::kStepPID + AliHFEcuts::kNcutStepsESDtrack); + + nHFEelectrons++; + fElectronsDataPt->Fill(dataContainer[0]); + fDisplacedElectrons->FillDataOutput(fESD, track); + } // analyze displaced electrons plugin switched on + } // track loop + if(fDeDebugLevel>=10) printf("there are %d HFE electrons in this DATA event", nHFEelectrons); +} +//____________________________________________________________ +void AliAnalysisTaskDisplacedElectrons::Terminate(Option_t *){ + // + // Terminate not implemented at the moment + // + + fHistDisplacedElectrons = dynamic_cast(GetOutputData(1)); + fDeCorrection = dynamic_cast(GetOutputData(2)); + fDeQA = dynamic_cast(GetOutputData(3)); + if(!fDeCorrection) AliError("correction list not available\n"); + if(!fHistDisplacedElectrons) AliError("de list not available\n"); + if(!fDeQA) AliError("qa list is not available\n"); + + fHistDisplacedElectrons->Print(); + fDeCorrection->Print(); + fDeQA->Print(); + AliInfo("analysis done!\n"); + +} //____________________________________________________________ void AliAnalysisTaskDisplacedElectrons::PrintStatus() const { @@ -501,11 +670,14 @@ void AliAnalysisTaskDisplacedElectrons::PrintStatus() const { // // Print Analysis status // - printf("\n\tAnalysis Settings\n\t========================================\n"); - printf("\tdisplaced electrons' analysis is %s\n", GetPlugin(kDisplacedElectrons)?"ON":"OFF"); - printf("\tcorrection container is %s\n", GetPlugin(kCorrection)?"ON":"OFF"); - printf("\tpost processing is %s\n", GetPlugin(kPostProcess)?"ON":"OFF"); - printf("\tcuts: %s\n", (fCuts != NULL) ? "YES" : "NO"); + printf("\n"); + printf("\t Analysis Settings\n\t========================================\n"); + printf("\t running over %s\n", HasMCData()?"MC data":"pp collision data"); + printf("\t displaced electrons' analysis is %s\n", GetPlugin(kDisplacedElectrons)?"ON":"OFF"); + printf("\t correction container is %s\n", GetPlugin(kCorrection)?"ON":"OFF"); + printf("\t hfe pid qa is %s\n", GetPlugin(kDePidQA)?"ON":"OFF"); + printf("\t post processing is %s\n", GetPlugin(kPostProcess)?"ON":"OFF"); + printf("\t cuts: %s\n", (fDeCuts != NULL) ? "YES" : "NO"); printf("\t "); printf("\n"); } @@ -521,92 +693,103 @@ void AliAnalysisTaskDisplacedElectrons::SwitchOnPlugin(Int_t plug){ switch(plug) { case kDisplacedElectrons: - SETBIT(fPlugins, plug); - break; - case kPostProcess: - SETBIT(fPlugins, plug); + SETBIT(fDePlugins, plug); break; case kCorrection: - SETBIT(fPlugins, plug); + SETBIT(fDePlugins, plug); + break; + case kDePidQA: + SETBIT(fDePlugins, plug); + break; + case kPostProcess: + SETBIT(fDePlugins, plug); break; default: AliError("Unknown Plugin"); }; } - //____________________________________________________________ void AliAnalysisTaskDisplacedElectrons::MakeParticleContainer(){ // - // Create the particle container (borrowed from AliAnalysisTaskHFE) + // Create the particle container for the correction framework manager and + // link it // - const Int_t kNvar = 4; //number of variables on the grid:pt,eta, phi - const Double_t kPtmin = 0.1, kPtmax = 20.; // used for fixed pt bins - // const Float_t ptBins[14] = {0.0,0.5,1.0,1.5,2.0,2.5,3.0,4.0,5.0,7.0,9.0,12.0,16.0,20.0}; - const Double_t kEtamin = -0.9, kEtamax = 0.9; - const Double_t kPhimin = 0., kPhimax = 2. * TMath::Pi(); + const Int_t kNvar = 4; + //number of variables on the grid:pt,eta, phi, charge + const Double_t kPtbound[2] = {0.1, 10.}; + const Double_t kEtabound[2] = {-0.8, 0.8}; + const Double_t kPhibound[2] = {0., 2. * TMath::Pi()}; //arrays for the number of bins in each dimension Int_t iBin[kNvar]; - iBin[0] = 40; //bins in pt // used for fixed pt bins - // iBin[0] = 13; //bins in pt - iBin[1] = 8; //bins in eta + iBin[0] = 40; // bins in pt + iBin[1] = 8; // bins in eta iBin[2] = 18; // bins in phi iBin[3] = 2; // bins in charge - + //arrays for lower bounds : Double_t* binEdges[kNvar]; - for(Int_t ivar = 0; ivar < kNvar; ivar++) - binEdges[ivar] = new Double_t[iBin[ivar] + 1]; - - //values for bin lower bounds - // for(Int_t i=0; i<=iBin[0]; i++) binEdges[0][i]=ptBins[i]; // using variable bins - for(Int_t i=0; i<=iBin[0]; i++) - binEdges[0][i]=(Double_t)TMath::Power(10,TMath::Log10(kPtmin) + (TMath::Log10(kPtmax)-TMath::Log10(kPtmin))/iBin[0]*(Double_t)i); // fixed pt bin - for(Int_t i=0; i<=iBin[1]; i++) binEdges[1][i]=(Double_t)kEtamin + (kEtamax-kEtamin)/iBin[1]*(Double_t)i; - for(Int_t i=0; i<=iBin[2]; i++) binEdges[2][i]=(Double_t)kPhimin + (kPhimax-kPhimin)/iBin[2]*(Double_t)i; - for(Int_t i=0; i<=iBin[3]; i++) binEdges[3][i]=1.1*i-1.1; // Numeric precision - - //one "container" for MC - AliCFContainer* container = new AliCFContainer("container","container for tracks", - (AliHFEcuts::kNcutStepsTrack + 1 + 2*(AliHFEcuts::kNcutStepsESDtrack + 1)), - kNvar, iBin); - + binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]); + binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]); + binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]); + binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision + + //------------------------------------------------ + // one "container" for MC+ESD+Data + //----------pure MC track------------------------- + // 0: MC generated + // 1: MC pion total ---- be careful!!!! + // 2: MC electrons total + // 3: MC electrons in acceptance + //-------ESD track with MC info------------------- + // 4: ESD track with MC: no cut + // 5: ESD track with MC: cut on kine its tpc + // 6: ESD track with MC: rec prim + // 7: ESD track with MC: hfe cuts its + // 8: ESD track with MC: hfe cuts trd + // 9: ESD track with MC: hfe pid + //-----------data track--------------------------- + // 10: DATA track wo MC: no cut + // 11: DATA track wo MC: cut on kine its tpc + // 12: DATA track wo MC: rec prim + // 13: DATA track wo MC: hfe cuts its + // 14: DATA track wo MC: hfe cuts trd + // 15: DATA track wo MC: hfe pid + //------------------------------------------------ + + AliCFContainer* container = new AliCFContainer("deTrackContainer", "Container for tracks", + (1 + AliHFEcuts::kNcutStepsTrack + AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin); + //setting the bin limits - for(Int_t ivar = 0; ivar < kNvar; ivar++) + for(Int_t ivar = 0; ivar < kNvar; ivar++){ container -> SetBinLimits(ivar, binEdges[ivar]); - fCFM->SetParticleContainer(container); - - //create correlation matrix for unfolding - Int_t thnDim[2*kNvar]; - for (int k=0; kSetParticleContainer(container); } + //____________________________________________________________ void AliAnalysisTaskDisplacedElectrons::MakeEventContainer(){ // // Create the event container for the correction framework and link it // + + // event container + // 0: MC event + // 1: ESD event + const Int_t kNvar = 1; // number of variables on the grid: number of tracks per event const Double_t kNTrackBound[2] = {-0.5, 200.5}; const Int_t kNBins = 201; - AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, &kNBins); + AliCFContainer *evCont = new AliCFContainer("deEventContainer", "Container for DE events", AliHFEcuts::kNcutStepsEvent, kNvar, &kNBins); Double_t trackBins[kNBins]; for(Int_t ibin = 0; ibin < kNBins; ibin++) trackBins[ibin] = kNTrackBound[0] + static_cast(ibin); evCont->SetBinLimits(0,trackBins); - fCFM->SetEventContainer(evCont); + fDeCFM->SetEventContainer(evCont); } @@ -617,10 +800,10 @@ void AliAnalysisTaskDisplacedElectrons::AddPIDdetector(TString detector){ // // Adding PID detector to the task // - if(!fPIDdetectors.Length()) - fPIDdetectors = detector; + if(!fDePIDdetectors.Length()) + fDePIDdetectors = detector; else - fPIDdetectors += ":" + detector; + fDePIDdetectors += ":" + detector; } @@ -663,7 +846,7 @@ Bool_t AliAnalysisTaskDisplacedElectrons::LabelContainer::Find(Int_t label) cons } //____________________________________________________________ -Int_t AliAnalysisTaskDisplacedElectrons::LabelContainer::Next() { +Int_t AliAnalysisTaskDisplacedElectrons::LabelContainer::Next() { // // Mimic iterator // diff --git a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h index 1750e170b72..4190d8da5ee 100644 --- a/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h +++ b/PWG3/hfe/AliAnalysisTaskDisplacedElectrons.h @@ -17,6 +17,12 @@ // study displaced electrons from beauty and charm // with cut on impact parameters in various pT bins // +// +// Authors: +// Hongyan Yang +// Carlo Bombonati +// + #ifndef ALIANALYSISTASKDISPLACEDELECTRONS_H @@ -53,7 +59,8 @@ class AliAnalysisTaskDisplacedElectrons : public AliAnalysisTaskSE{ typedef enum{ kPostProcess = 0, kDisplacedElectrons = 1, - kCorrection = 2 + kCorrection = 2, + kDePidQA = 3 }Switches_t; enum{ @@ -74,19 +81,30 @@ class AliAnalysisTaskDisplacedElectrons : public AliAnalysisTaskSE{ void PrintStatus() const; - Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); }; + Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fDePlugins, plug); }; void SwitchOnPlugin(Int_t plug); - void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; }; - - void SetPIDdetectors(Char_t * const detectors){ fPIDdetectors = detectors; }; - void SetPIDStrategy(UInt_t strategy) { fPIDstrategy = strategy; }; - void SetDBLevel(UInt_t debugLevel) { fDebugLevel = debugLevel; }; + void SetHFECuts(AliHFEcuts * const cuts) { fDeCuts = cuts; }; + void SetNclustersITS(Int_t nITSclusters){fNminITSCluster = nITSclusters;}; + void SetMinPrimVtxContrib(Int_t nPrimVtxContrib){fNminPrimVtxContrib = nPrimVtxContrib;}; + void SetPIDdetectors(Char_t * const detectors){ fDePIDdetectors = detectors; }; + void SetPIDStrategy(UInt_t strategy) { fDePIDstrategy = strategy; }; + void SetDBLevel(UInt_t debugLevel) { fDeDebugLevel = debugLevel; }; void AddPIDdetector(TString detector); - Bool_t HasMCData() const { return TestBit(kHasMCdata); }; + Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); }; + Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); }; + Bool_t HasMCData() const { return TestBit(kHasMCdata); } void SetHasMCData(Bool_t hasMC = kTRUE) { SetBit(kHasMCdata, hasMC); }; + void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); }; + void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); }; + + void ProcessMC(); + void ProcessESD(); + void ProcessData(); + + private: @@ -113,25 +131,27 @@ class AliAnalysisTaskDisplacedElectrons : public AliAnalysisTaskSE{ void MakeParticleContainer(); void MakeEventContainer(); - UInt_t fDebugLevel; // debug level - - TString fPIDdetectors; // Detectors for Particle Identification - UInt_t fPIDstrategy; // PID Strategy - + UInt_t fDeDebugLevel; // debug level + Int_t fNminITSCluster; // number of clusters in ITS + Int_t fNminPrimVtxContrib; // number of ncontributor in ITS for prim vtx + TString fDePIDdetectors; // Detectors for Particle Identification + UInt_t fDePIDstrategy; // PID Strategy - UShort_t fPlugins; // Enabled Plugins - AliESDEvent *fESD; //! The ESD Event - AliMCEvent *fMC; //! The MC Event + UShort_t fDePlugins; // Enabled Plugins - AliHFEcuts *fCuts; // Cut Collection - AliHFEpid *fPID; // PID method - AliCFManager *fCFM; //! Correction Framework Manager - - TH1I *fNEvents; //! counter for the number of Events - TH1F *fElectronsPt; //! pt distribution of electrons (hfepid) - TList *fOutput; //! Container for this Task Output - TList *fCorrection; //! Container for correction Output + AliHFEcuts *fDeCuts; // Cut Collection + AliESDpid *fDeDefaultPID; //! ESD PID method + AliHFEpid *fDePID; //! PID method + AliCFManager *fDeCFM; //! Correction Framework Manager AliHFEdisplacedElectrons *fDisplacedElectrons; //! HFE displaced Electrons pointer + + + TH1I *fDeNEvents; //! counter for the number of Events + TH1F *fElectronsMcPt; //! pt distribution of MC electrons (mcpid) + TH1F *fElectronsEsdPt; //! pt distribution of ESD electrons (hfepid) + TH1F *fElectronsDataPt; //! pt distribution of DATA electrons (hfepid) + TList *fDeCorrection; //! Container for correction Outpu + TList *fDeQA; //! container for the PID qa TList *fHistDisplacedElectrons; //! list of outputs ClassDef(AliAnalysisTaskDisplacedElectrons, 1); // The DisplacedElectrons Analysis Task diff --git a/PWG3/hfe/AliAnalysisTaskHFE.cxx b/PWG3/hfe/AliAnalysisTaskHFE.cxx index 78b505e92fd..b59edb96a7c 100644 --- a/PWG3/hfe/AliAnalysisTaskHFE.cxx +++ b/PWG3/hfe/AliAnalysisTaskHFE.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include "AliAODInputHandler.h" @@ -50,6 +52,7 @@ #include "AliCFManager.h" #include "AliESDEvent.h" #include "AliESDInputHandler.h" +#include "AliESDpid.h" #include "AliESDtrack.h" #include "AliLog.h" #include "AliAnalysisManager.h" @@ -72,6 +75,8 @@ #include "AliHFEtools.h" #include "AliAnalysisTaskHFE.h" +ClassImp(AliAnalysisTaskHFE) + //____________________________________________________________ AliAnalysisTaskHFE::AliAnalysisTaskHFE(): AliAnalysisTaskSE("PID efficiency Analysis") @@ -79,7 +84,11 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(): , fPIDdetectors("") , fPIDstrategy(0) , fPlugins(0) + , fWeighting(kFALSE) + , fWeightFactors(NULL) + , fWeightFactorsFunction(NULL) , fCFM(NULL) + , fHadronicBackground(NULL) , fCorrelation(NULL) , fPIDperformance(NULL) , fSignalToBackgroundMC(NULL) @@ -100,13 +109,6 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(): // // Dummy constructor // - DefineOutput(1, TH1I::Class()); - DefineOutput(2, TList::Class()); - DefineOutput(3, TList::Class()); -// DefineOutput(4, TList::Class()); - - // Initialize cuts - fPID = new AliHFEpid; } //____________________________________________________________ @@ -116,7 +118,11 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name): , fPIDdetectors("") , fPIDstrategy(0) , fPlugins(0) + , fWeighting(kFALSE) + , fWeightFactors(NULL) + , fWeightFactorsFunction(NULL) , fCFM(NULL) + , fHadronicBackground(NULL) , fCorrelation(NULL) , fPIDperformance(NULL) , fSignalToBackgroundMC(NULL) @@ -143,37 +149,41 @@ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name): // DefineOutput(4, TList::Class()); // Initialize cuts - fPID = new AliHFEpid; } //____________________________________________________________ AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref): AliAnalysisTaskSE(ref) - , fQAlevel(ref.fQAlevel) - , fPIDdetectors(ref.fPIDdetectors) - , fPIDstrategy(ref.fPIDstrategy) - , fPlugins(ref.fPlugins) - , fCFM(ref.fCFM) - , fCorrelation(ref.fCorrelation) - , fPIDperformance(ref.fPIDperformance) - , fSignalToBackgroundMC(ref.fSignalToBackgroundMC) - , fPID(ref.fPID) - , fCuts(ref.fCuts) - , fSecVtx(ref.fSecVtx) - , fElecBackGround(ref.fElecBackGround) - , fMCQA(ref.fMCQA) - , fNEvents(ref.fNEvents) - , fNElectronTracksEvent(ref.fNElectronTracksEvent) - , fQA(ref.fQA) - , fOutput(ref.fOutput) - , fHistMCQA(ref.fHistMCQA) - , fHistSECVTX(ref.fHistSECVTX) - , fHistELECBACKGROUND(ref.fHistELECBACKGROUND) + , fQAlevel(0) + , fPIDdetectors() + , fPIDstrategy(0) + , fPlugins(0) + , fWeighting(kFALSE) + , fWeightFactors(NULL) + , fWeightFactorsFunction(NULL) + , fCFM(NULL) + , fHadronicBackground(NULL) + , fCorrelation(NULL) + , fPIDperformance(NULL) + , fSignalToBackgroundMC(NULL) + , fPID(NULL) + , fCuts(NULL) + , fSecVtx(NULL) + , fElecBackGround(NULL) + , fMCQA(NULL) + , fNEvents(NULL) + , fNElectronTracksEvent(NULL) + , fQA(NULL) + , fOutput(NULL) + , fHistMCQA(NULL) + , fHistSECVTX(NULL) + , fHistELECBACKGROUND(NULL) // , fQAcoll(ref.fQAcoll) { // // Copy Constructor // + ref.Copy(*this); } //____________________________________________________________ @@ -181,38 +191,49 @@ AliAnalysisTaskHFE &AliAnalysisTaskHFE::operator=(const AliAnalysisTaskHFE &ref) // // Assignment operator // - if(this == &ref) return *this; - AliAnalysisTask::operator=(ref); - fQAlevel = ref.fQAlevel; - fPIDdetectors = ref.fPIDdetectors; - fPIDstrategy = ref.fPIDstrategy; - fPlugins = ref.fPlugins; - fCFM = ref.fCFM; - fCorrelation = ref.fCorrelation; - fPIDperformance = ref.fPIDperformance; - fSignalToBackgroundMC = ref.fSignalToBackgroundMC; - fPID = ref.fPID; - fCuts = ref.fCuts; - fSecVtx = ref.fSecVtx; - fElecBackGround = ref.fElecBackGround; - fMCQA = ref.fMCQA; - fNEvents = ref.fNEvents; - fNElectronTracksEvent = ref.fNElectronTracksEvent; - fQA = ref.fQA; - fOutput = ref.fOutput; - fHistMCQA = ref.fHistMCQA; - fHistSECVTX = ref.fHistSECVTX; - fHistELECBACKGROUND = ref.fHistELECBACKGROUND; - -// fQAcoll = ref.fQAcoll; + if(this == &ref) + ref.Copy(*this); return *this; } +//____________________________________________________________ +void AliAnalysisTaskHFE::Copy(TObject &o) const { + // + // Copy into object o + // + AliAnalysisTaskHFE &target = dynamic_cast(o); + target.fQAlevel = fQAlevel; + target.fPIDdetectors = fPIDdetectors; + target.fPIDstrategy = fPIDstrategy; + target.fPlugins = fPlugins; + target.fWeighting = fWeighting; + target.fWeightFactors = fWeightFactors; + target.fWeightFactorsFunction = fWeightFactorsFunction; + target.fCFM = fCFM; + target.fHadronicBackground = fHadronicBackground; + target.fCorrelation = fCorrelation; + target.fPIDperformance = fPIDperformance; + target.fSignalToBackgroundMC = fSignalToBackgroundMC; + target.fPID = fPID; + target.fCuts = fCuts; + target.fSecVtx = fSecVtx; + target.fElecBackGround = fElecBackGround; + target.fMCQA = fMCQA; + target.fNEvents = fNEvents; + target.fNElectronTracksEvent = fNElectronTracksEvent; + target.fQA = fQA; + target.fOutput = fOutput; + target.fHistMCQA = fHistMCQA; + target.fHistSECVTX = fHistSECVTX; + target.fHistELECBACKGROUND = fHistELECBACKGROUND; +} + //____________________________________________________________ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){ // // Destructor // + return; if(fPID) delete fPID; if(fQA){ fQA->Clear(); @@ -222,6 +243,8 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){ fOutput->Clear(); delete fOutput; } + if(fWeightFactors) delete fWeightFactors; + if(fWeightFactorsFunction) delete fWeightFactorsFunction; if(fHistMCQA){ fHistMCQA->Clear(); delete fHistMCQA; @@ -245,6 +268,7 @@ AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){ if(fPIDperformance) delete fPIDperformance; if(fSignalToBackgroundMC) delete fSignalToBackgroundMC; // if(fQAcoll) delete fQAcoll; + } //____________________________________________________________ @@ -259,9 +283,10 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ // QA histograms are created if requested // Called once per worker // + fPID = new AliHFEpid; AliDebug(3, "Creating Output Objects"); // Automatic determination of the analysis mode - AliVEventHandler *inputHandler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler(); + AliVEventHandler *inputHandler = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){ SetAODAnalysis(); } else { @@ -289,6 +314,9 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ fQA->AddAt(new TProfile("ntrdclusters", "Number of TRD clusters as function of momentum", 20, 0, 20), 5); fQA->AddAt(new TH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20), 6); fQA->AddAt(new TH1I("mccharge", "MC Charge", 200, -100, 100), 7); + fQA->AddAt(new TH2F("radius", "Production Vertex", 100, 0.0, 5.0, 100, 0.0, 5.0), 8); + fQA->AddAt(new TH1F("secvtxept", "pT of tagged e", 500, 0, 50), 9); // mj: will move to another place soon + fQA->AddAt(new TH2F("secvtxeTPCsig", "TPC signal for tagged e",125, 0, 25, 200, 0, 200 ), 10); // mj: will move to another place soon if(!fOutput) fOutput = new TList; // Initialize correction Framework and Cuts @@ -314,6 +342,7 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ fOutput->AddAt(fPIDperformance, 3); fOutput->AddAt(fSignalToBackgroundMC, 4); fOutput->AddAt(fNElectronTracksEvent, 5); + fOutput->AddAt(fHadronicBackground, 6); // Initialize PID if(IsQAOn(kPIDqa)){ @@ -337,14 +366,22 @@ void AliAnalysisTaskHFE::UserCreateOutputObjects(){ fHistMCQA->SetName("MCqa"); fMCQA->CreateHistograms(AliHFEmcQA::kCharm,0,"mcqa_"); // create histograms for charm fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,0,"mcqa_"); // create histograms for beauty + fMCQA->CreateHistograms(AliHFEmcQA::kOthers,0,"mcqa_"); // create histograms for beauty fMCQA->CreateHistograms(AliHFEmcQA::kCharm,1,"mcqa_barrel_"); // create histograms for charm fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,1,"mcqa_barrel_"); // create histograms for beauty + fMCQA->CreateHistograms(AliHFEmcQA::kOthers,1,"mcqa_barrel_"); // create histograms for beauty fMCQA->CreateHistograms(AliHFEmcQA::kCharm,2,"mcqa_unitY_"); // create histograms for charm fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,2,"mcqa_unitY_"); // create histograms for beauty + fMCQA->CreateHistograms(AliHFEmcQA::kOthers,2,"mcqa_unitY_"); // create histograms for beauty fMCQA->CreateHistograms(AliHFEmcQA::kCharm,3,"mcqa_reccut_"); // create histograms for charm fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,3,"mcqa_reccut_"); // create histograms for beauty + fMCQA->CreateHistograms(AliHFEmcQA::kOthers,3,"mcqa_reccut_"); // create histograms for beauty fMCQA->CreateHistograms(AliHFEmcQA::kCharm,4,"mcqa_recpidcut_"); // create histograms for charm fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,4,"mcqa_recpidcut_"); // create histograms for beauty + fMCQA->CreateHistograms(AliHFEmcQA::kOthers,4,"mcqa_recpidcut_"); // create histograms for beauty + fMCQA->CreateHistograms(AliHFEmcQA::kCharm,5,"mcqa_secvtxcut_"); // create histograms for charm + fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,5,"mcqa_secvtxcut_"); // create histograms for beauty + fMCQA->CreateHistograms(AliHFEmcQA::kOthers,5,"mcqa_secvtxcut_"); // create histograms for beauty TIter next(gDirectory->GetList()); TObject *obj; int counter = 0; @@ -408,10 +445,30 @@ void AliAnalysisTaskHFE::UserExec(Option_t *){ return; } + if(IsESDanalysis() && HasMCData()){ + // Protect against missing MC trees + AliMCEventHandler *mcH = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()); + if(!mcH->InitOk()) return; + if(!mcH->TreeK()) return; + if(!mcH->TreeTR()) return; + } + + // Protect agains missing if(HasMCData()) ProcessMC(); // Run the MC loop + MC QA in case MC Data are available if(IsAODanalysis()) ProcessAOD(); - else ProcessESD(); + else{ + AliESDInputHandler *inH = dynamic_cast(fInputHandler); + AliESDpid *workingPID = inH->GetESDpid(); + if(workingPID){ + AliDebug(1, "Using ESD PID from the input handler"); + fPID->SetESDpid(workingPID); + } else { + AliDebug(1, "Using default ESD PID"); + fPID->SetESDpid(AliHFEtools::GetDefaultPID(HasMCData())); + } + ProcessESD(); + } // Done!!! PostData(1, fNEvents); PostData(2, fOutput); @@ -449,7 +506,31 @@ void AliAnalysisTaskHFE::Terminate(Option_t *){ } } } +//_______________________________________________________________ +Bool_t AliAnalysisTaskHFE::IsEventInBinZero() { + // + // + // + + //printf("test in IsEventInBinZero\n"); + if(!fInputEvent){ + AliError("Reconstructed Event not available"); + return kFALSE; + } + // check vertex + const AliVVertex *vertex = fInputEvent->GetPrimaryVertex(); + if(!vertex) return kTRUE; + //if(vertex) return kTRUE; + + // check tracks + if(fInputEvent->GetNumberOfTracks()<=0) return kTRUE; + //if(fInputEvent->GetNumberOfTracks()>0) return kTRUE; + + + return kFALSE; + +} //____________________________________________________________ void AliAnalysisTaskHFE::ProcessMC(){ // @@ -468,7 +549,7 @@ void AliAnalysisTaskHFE::ProcessMC(){ AliDebug(2, "Running MC QA"); if(fMCEvent->Stack()){ - fMCQA->SetStack(fMCEvent->Stack()); + fMCQA->SetMCEvent(fMCEvent); fMCQA->SetGenEventHeader(fMCEvent->GenEventHeader()); fMCQA->Init(); @@ -483,13 +564,16 @@ void AliAnalysisTaskHFE::ProcessMC(){ fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kBeauty); fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 0); // no accept cut fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 0); // no accept cut + fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 0); // no accept cut if (TMath::Abs(mcpart->Eta()) < 0.9) { fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9 + fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9 } if (TMath::Abs(AliHFEtools::GetRapidity(mcpart)) < 0.5) { fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5 + fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5 } } fMCQA->EndOfEventAna(AliHFEmcQA::kCharm); @@ -505,8 +589,10 @@ void AliAnalysisTaskHFE::ProcessMC(){ } // Run MC loop AliVParticle *mctrack = NULL; + AliDebug(3, Form("Number of Tracks: %d", fMCEvent->GetNumberOfTracks())); for(Int_t imc = 0; imc GetNumberOfTracks(); imc++){ if(!(mctrack = fMCEvent->GetTrack(imc))) continue; + AliDebug(4, "Next Track"); if(ProcessMCtrack(mctrack)) nElectrons++; } @@ -539,7 +625,7 @@ void AliAnalysisTaskHFE::ProcessESD(){ if(HasMCData()){ if (GetPlugin(kSecVtx)) { - if(fMCEvent->Stack()) fSecVtx->SetStack(fMCEvent->Stack()); + fSecVtx->SetMCEvent(fMCEvent); } if (GetPlugin(kIsElecBackGround)) { fElecBackGround->SetMCEvent(fMCEvent); @@ -547,8 +633,8 @@ void AliAnalysisTaskHFE::ProcessESD(){ } - Double_t container[8]; - memset(container, 0, sizeof(Double_t) * 8); + Double_t container[10]; + memset(container, 0, sizeof(Double_t) * 10); // container for the output THnSparse Double_t dataE[5]; // [pT, eta, Phi, type, 'C' or 'B'] Int_t nElectronCandidates = 0; @@ -574,14 +660,18 @@ void AliAnalysisTaskHFE::ProcessESD(){ // // Loop ESD // + AliDebug(3, Form("Number of Tracks: %d", fESD->GetNumberOfTracks())); for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){ track = fESD->GetTrack(itrack); + + AliDebug(3, Form("Doing track %d, %p", itrack, track)); container[0] = track->Pt(); container[1] = track->Eta(); container[2] = track->Phi(); container[3] = track->Charge(); + container[4] = 0; dataE[0] = track->Pt(); dataE[1] = track->Eta(); @@ -591,34 +681,51 @@ void AliAnalysisTaskHFE::ProcessESD(){ dataE[5] = -1; signal = kTRUE; - + Double_t weight = 1.0; + // Fill step without any cut if(HasMCData()){ + container[4] = container[9] = kOther; // Check if it is electrons near the vertex if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue; - mctrack4QA = mctrack->Particle();//fMCEvent->Stack()->Particle(TMath::Abs(track->GetLabel())); + mctrack4QA = mctrack->Particle(); + + container[5] = mctrack->Pt(); + container[6] = mctrack->Eta(); + container[7] = mctrack->Phi(); + container[8] = mctrack->Charge()/3.; + + if(fWeighting) weight = FindWeight(container[5],container[6],container[7]); - container[4] = mctrack->Pt(); - container[5] = mctrack->Eta(); - container[6] = mctrack->Phi(); - container[7] = mctrack->Charge()/3.; - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE; + else AliDebug(3, "Signal Electron"); + + Int_t signalTrack = 0; + if((signalTrack = IsSignalElectron(track))){ + AliDebug(3, Form("Signal: Index = %d\n", signalTrack)); + switch(signalTrack){ + case 1: container[4] = container[9] = kSignalCharm; break; + case 2: container[4] = container[9] = kSignalBeauty; break; + default: container[4] = container[9] = kOther; break; + }; + } else if(IsGammaElectron(track)) container[4] = container[9] = kGammaConv; + AliDebug(3, Form("Signal Decision(%f/%f)", container[4], container[9])); } + AliDebug(3, Form("Weight? %f", weight)); if(signal) { alreadyseen = cont.Find(TMath::Abs(track->GetLabel())); cont.Append(TMath::Abs(track->GetLabel())); - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut); - fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack); + fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut,weight); + fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack,weight); if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack); + fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack,weight); } } // RecKine: ITSTPC cuts - if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen)) continue; + if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen, weight)) continue; // Check TRD criterions (outside the correction framework) if(track->GetTRDncls()){ @@ -631,13 +738,13 @@ void AliAnalysisTaskHFE::ProcessESD(){ // RecPrim - if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen)) continue; + if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen,weight)) continue; // HFEcuts: ITS layers cuts - if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen)) continue; + if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen,weight)) continue; // HFEcuts: Nb of tracklets TRD0 - if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen)) continue; + if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen,weight)) continue; if(signal) { // dimensions 3&4&5 : pt,eta,phi (MC) ((THnSparseF *)fCorrelation->At(0))->Fill(container); @@ -648,8 +755,13 @@ void AliAnalysisTaskHFE::ProcessESD(){ AliDebug(2, "Running MC QA"); fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 3); // charm fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 3); // beauty + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 3); // beauty } + if(HasMCData()){ + FillProductionVertex(track); + } + // track accepted, do PID AliHFEpidObject hfetrack; hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis; @@ -658,51 +770,74 @@ void AliAnalysisTaskHFE::ProcessESD(){ if(!fPID->IsSelected(&hfetrack)) continue; nElectronCandidates++; + // Fill Histogram for Hadronic Background + if(HasMCData()){ + if(mctrack && (TMath::Abs(mctrack->Particle()->GetPdgCode()) != 11)) + fHadronicBackground->Fill(container, 0); + } + if (HasMCData() && IsQAOn(kMCqa)) { // mc qa for after the reconstruction and pid cuts AliDebug(2, "Running MC QA"); fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 4); // charm fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 4); // beauty + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 4); // beauty } // Fill Containers if(signal) { - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack); - fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepPID); + fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack,weight); + fCFM->GetParticleContainer()->Fill(&container[5], AliHFEcuts::kStepPID,weight); if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[4], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack))); + fCFM->GetParticleContainer()->Fill(&container[5], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)),weight); } // dimensions 3&4&5 : pt,eta,phi (MC) ((THnSparseF *)fCorrelation->At(1))->Fill(container); } - if(GetPlugin(kSecVtx) && fMCEvent->Stack()) { + if(GetPlugin(kSecVtx)) { AliDebug(2, "Running Secondary Vertex Analysis"); - if(track->Pt()>1.0){ + if(track->Pt()>2.0 && nContrib > 1){ fSecVtx->InitHFEpairs(); fSecVtx->InitHFEsecvtxs(); for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){ htrack = fESD->GetTrack(jtrack); if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition - if (htrack->Pt()<1.0) continue; + if (htrack->Pt()<2.0) continue; if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue; if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue; fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing } - /*for(int ip=0; ipHFEpairs()->GetEntriesFast(); ip++){ - if(HasMCData()){ + for(int ip=0; ipHFEpairs()->GetEntriesFast(); ip++){ + //if(HasMCData()){ AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip)); - if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.)) // apply various cuts + //if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.)) // apply various cuts + // apply various cuts + if(pair->GetKFChi2()>5.) // only apply vertex chi2 cut for the moment + //if((pair->GetKFChi2()>5.) || !(pair->GetSignedLxy()>0. && pair->GetSignedLxy()<2.)) fSecVtx->HFEpairs()->RemoveAt(ip); - } - }*/ + //} + } fSecVtx->HFEpairs()->Compress(); - fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks + if(fSecVtx->HFEpairs()->GetEntriesFast()) fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks for(int ip=0; ipHFEsecvtxs()->GetEntriesFast(); ip++){ AliHFEsecVtxs *secvtx=0x0; secvtx = (AliHFEsecVtxs*) (fSecVtx->HFEsecvtxs()->UncheckedAt(ip)); + if(!(secvtx->GetInvmass()>2.0 && secvtx->GetInvmass()<5.2) || !(secvtx->GetSignedLxy2()>0.08 && secvtx->GetSignedLxy2()<1.5) || !(secvtx->GetKFIP2()>-0.1 && secvtx->GetKFIP2()<0.1)) + fSecVtx->HFEsecvtxs()->RemoveAt(ip); // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs() } + if(fSecVtx->HFEsecvtxs()->GetEntriesFast()) { + (dynamic_cast(fQA->At(9)))->Fill(track->Pt()); + (dynamic_cast(fQA->At(10)))->Fill(track->P(),track->GetTPCsignal()); + if (HasMCData() && IsQAOn(kMCqa)) { + // mc qa for after the reconstruction and pid cuts + AliDebug(2, "Running MC QA"); + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 5); // charm + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 5); // beauty + fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kOthers, AliHFEmcQA::kElectronPDG, 5); // beauty + } + } fSecVtx->DeleteHFEpairs(); fSecVtx->DeleteHFEsecvtxs(); } @@ -770,7 +905,7 @@ void AliAnalysisTaskHFE::ProcessAOD(){ AliAODTrack *track = NULL; AliAODMCParticle *mctrack = NULL; - Double_t container[8]; memset(container, 0, sizeof(Double_t) * 8); + Double_t container[10]; memset(container, 0, sizeof(Double_t) * 10); Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B'] Int_t nElectronCandidates = 0; Int_t pid; @@ -792,13 +927,23 @@ void AliAnalysisTaskHFE::ProcessAOD(){ dataE[5] = -1; if(HasMCData()){ + Int_t signalTrack = 0; + if((signalTrack = IsSignalElectron(track))){ + switch(signalTrack){ + case 1: container[4] = container[9] = kSignalCharm; break; + case 2: container[4] = container[9] = kSignalBeauty; break; + }; + } else if(IsGammaElectron(track)) + container[4] = container[9] = kGammaConv; + else container[4] = container[9] = kOther; + Int_t label = TMath::Abs(track->GetLabel()); if(label){ mctrack = dynamic_cast(fMCEvent->GetTrack(label)); - container[4] = mctrack->Pt(); - container[5] = mctrack->Eta(); - container[6] = mctrack->Phi(); - container[7] = mctrack->Charge(); + container[5] = mctrack->Pt(); + container[6] = mctrack->Eta(); + container[7] = mctrack->Phi(); + container[8] = mctrack->Charge(); } } // track accepted, do PID @@ -848,7 +993,7 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){ // Additionally Fill a THnSparse for Signal To Background Studies // Works for AOD and MC analysis Type // - Double_t container[4], signalContainer[6]; + Double_t container[5], signalContainer[6]; Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s) if(IsESDanalysis()){ AliMCParticle *mctrack = dynamic_cast(track); @@ -878,11 +1023,24 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){ aodmctrack->XvYvZv(vertex); } - if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE; + Int_t signal = 0; + if((signal = IsSignalElectron(track))){ + switch(signal){ + case 1: container[4] = kSignalCharm; break; + case 2: container[4] = kSignalBeauty; break; + }; + }else if(IsGammaElectron(track)) container[4] = kGammaConv; + else container[4] = kOther; + + // weight + Double_t weight = 1.0; + if(fWeighting) weight = FindWeight(container[0],container[1],container[2]); + + if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE; TH1 *test = dynamic_cast(fQA->FindObject("mccharge")); test->Fill(signalContainer[3]); - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated); - if((signalContainer[4] = static_cast(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal); + fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated,weight); + if((signalContainer[4] = static_cast(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal,weight); signalContainer[5] = 0; // apply cut on the sqrt of the production vertex Double_t radVertex = TMath::Sqrt(vertex[0]*vertex[0] + vertex[1] * vertex[1]); @@ -896,7 +1054,7 @@ Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){ (dynamic_cast(fQA->At(2)))->Fill(container[2] - TMath::Pi()); //if(IsESDanalysis()){ if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE; - fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance); + fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance,weight); //} return kTRUE; } @@ -925,7 +1083,8 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){ // Create the particle container for the correction framework manager and // link it // - const Int_t kNvar = 4 ; //number of variables on the grid:pt,eta, phi, charge + const Int_t kNvar = 5; + //number of variables on the grid:pt,eta, phi, charge const Double_t kPtbound[2] = {0.1, 10.}; const Double_t kEtabound[2] = {-0.8, 0.8}; const Double_t kPhibound[2] = {0., 2. * TMath::Pi()}; @@ -936,6 +1095,7 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){ iBin[1] = 8; // bins in eta iBin[2] = 18; // bins in phi iBin[3] = 2; // bins in charge + iBin[4] = 4; // creation process of the electron //arrays for lower bounds : Double_t* binEdges[kNvar]; @@ -943,13 +1103,19 @@ void AliAnalysisTaskHFE::MakeParticleContainer(){ binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]); binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]); binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision + binEdges[4] = AliHFEtools::MakeLinearBinning(iBin[4], 0, iBin[4]); // Numeric precision + //for(Int_t ib = 0; ib <= iBin[4]; ib++) printf("%f\t", binEdges[4][ib]); + //printf("\n"); //one "container" for MC AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin); + fHadronicBackground = new AliCFContainer("hadronicBackground", "Container for hadronic Background", 1, kNvar, iBin); //setting the bin limits - for(Int_t ivar = 0; ivar < kNvar; ivar++) + for(Int_t ivar = 0; ivar < kNvar; ivar++){ container -> SetBinLimits(ivar, binEdges[ivar]); + fHadronicBackground -> SetBinLimits(ivar, binEdges[ivar]); + } fCFM->SetParticleContainer(container); //create correlation matrix for unfolding @@ -1082,7 +1248,7 @@ Int_t AliAnalysisTaskHFE::LabelContainer::Next(){ } //____________________________________________________________ -Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{ +Int_t AliAnalysisTaskHFE::IsSignalElectron(const AliVParticle * const track) const{ // // Checks whether the identified electron track is coming from heavy flavour // returns 0 in case of no signal, 1 in case of charm and 2 in case of Bottom @@ -1092,66 +1258,133 @@ Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{ kCharm = 1, kBeauty = 2 }; - TString objname = fTrack->IsA()->GetName(); + + if(!fMCEvent) return kNoSignal; + const AliVParticle *motherParticle = NULL, *mctrack = NULL; + TString objectType = track->IsA()->GetName(); + Int_t label = 0; + if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){ + // Reconstructed track + if((label = TMath::Abs(track->GetLabel())) && label < fMCEvent->GetNumberOfTracks()) + mctrack = fMCEvent->GetTrack(label); + } else { + // MCParticle + mctrack = track; + } + + if(!mctrack) return kNoSignal; + Int_t pid = 0; - if(IsESDanalysis()){ - // ESD Analysis - AliMCParticle *mctrack = NULL; - if(!objname.CompareTo("AliESDtrack")){ - AliDebug(2, "Checking signal for ESD track"); - AliESDtrack *esdtrack = dynamic_cast(fTrack); - mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(esdtrack->GetLabel()))); - } - else if(!objname.CompareTo("AliMCParticle")){ - AliDebug(2, "Checking signal for MC track"); - mctrack = dynamic_cast(fTrack); - } - else{ - AliError("Input object not supported"); - return kNoSignal; - } - if(!mctrack) return kNoSignal; - TParticle *ecand = mctrack->Particle(); - if(TMath::Abs(ecand->GetPdgCode()) != 11) return kNoSignal; // electron candidate not true electron - Int_t motherLabel = TMath::Abs(ecand->GetFirstMother()); - AliDebug(3, Form("mother label: %d\n", motherLabel)); - if(!motherLabel) return kNoSignal; // mother track unknown - AliMCParticle *motherTrack = dynamic_cast(fMCEvent->GetTrack(motherLabel)); - if(!motherTrack) return kNoSignal; - TParticle *mparticle = motherTrack->Particle(); - pid = TMath::Abs(mparticle->GetPdgCode()); + Int_t daughterPDG = 0, motherLabel = 0; + if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){ + // case MC Particle + daughterPDG = TMath::Abs((dynamic_cast(mctrack))->Particle()->GetPdgCode()); + motherLabel = (dynamic_cast(mctrack))->Particle()->GetFirstMother(); + if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks()) + motherParticle = fMCEvent->GetTrack(motherLabel); + if(motherParticle) + pid = TMath::Abs((dynamic_cast(motherParticle))->Particle()->GetPdgCode()); } else { - // AOD Analysis - Different Data handling - AliAODMCParticle *aodmc = NULL; - if(!objname.CompareTo("AliAODTrack")){ - AliAODTrack *aodtrack = dynamic_cast(fTrack); - Int_t aodlabel = TMath::Abs(aodtrack->GetLabel()); - if(aodlabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal; - aodmc = dynamic_cast(fMCEvent->GetTrack(aodlabel)); - } else if(!objname.CompareTo("AliAODMCParticle")){ - aodmc = dynamic_cast(fTrack); - } else{ - AliError("Input object not supported"); - return kNoSignal; - } - if(!aodmc) return kNoSignal; - Int_t motherLabel = TMath::Abs(aodmc->GetMother()); - AliDebug(3, Form("mother label: %d\n", motherLabel)); - if(!motherLabel || motherLabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal; - AliAODMCParticle *aodmother = dynamic_cast(fMCEvent->GetTrack(motherLabel)); - pid = aodmother->GetPdgCode(); + // case AODMCParticle + daughterPDG = TMath::Abs((dynamic_cast(mctrack))->GetPdgCode()); + motherLabel = (dynamic_cast(mctrack))->GetMother(); + if(motherLabel >= 0 && motherLabel < fMCEvent->GetNumberOfTracks()) + motherParticle = fMCEvent->GetTrack(motherLabel); + if(motherParticle) + pid = TMath::Abs((dynamic_cast(motherParticle))->GetPdgCode()); } + AliDebug(5, Form("Daughter PDG code: %d", daughterPDG)); + + if(!pid) return kNoSignal; + // From here the two analysis modes go together - AliDebug(3, Form("PDG code: %d\n", pid)); + AliDebug(5, Form("Mother PDG code: %d", pid)); - // identify signal according to Pdg Code - if((pid % 1000) / 100 == 4) return kCharm; // charmed meson, 3rd position in pdg code == 4 + // identify signal according to Pdg Code - barions higher ranked than mesons if(pid / 1000 == 4) return kCharm; // charmed baryon, 4th position in pdg code == 4 - if((pid % 1000) / 100 == 5) return kBeauty; // beauty meson, 3rd position in pdg code == 5 if(pid / 1000 == 5) return kBeauty; // beauty baryon, 4th position in pdg code == 5 + if((pid % 1000) / 100 == 4) return kCharm; // charmed meson, 3rd position in pdg code == 4 + if((pid % 1000) / 100 == 5) return kBeauty; // beauty meson, 3rd position in pdg code == 5 return kNoSignal; } +//__________________________________________ +Bool_t AliAnalysisTaskHFE::IsGammaElectron(const AliVParticle * const track) const { + // + // Check for MC if the electron is coming from Gamma + // + if(!fMCEvent) return kFALSE; + const AliVParticle *motherParticle = NULL, *mctrack = NULL; + TString objectType = track->IsA()->GetName(); + if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){ + // Reconstructed track + if(track->GetLabel()) + mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel())); + } else { + // MCParticle + mctrack = track; + } + + if(!mctrack) return kFALSE; + + Int_t motherPDG = 0; + if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){ + // case MC Particle + motherParticle = fMCEvent->GetTrack((dynamic_cast(mctrack)->Particle()->GetFirstMother())); + if(motherParticle) + motherPDG = TMath::Abs((dynamic_cast(motherParticle))->Particle()->GetPdgCode()); + } else { + // case AODMCParticle + motherParticle = fMCEvent->GetTrack((dynamic_cast(mctrack))->GetMother()); + if(motherParticle) + motherPDG = TMath::Abs((dynamic_cast(motherParticle))->GetPdgCode()); + } + if(motherPDG!=22) return kFALSE; + else return kTRUE; +} +//____________________________________________________________ +Bool_t AliAnalysisTaskHFE::FillProductionVertex(const AliVParticle * const track) const{ + // + // Find the production vertex of the associated MC track + // + if(!fMCEvent) return kFALSE; + const AliVParticle *mctrack = NULL; + TString objectType = track->IsA()->GetName(); + if(objectType.CompareTo("AliESDtrack") == 0 || objectType.CompareTo("AliAODTrack") == 0){ + // Reconstructed track + mctrack = fMCEvent->GetTrack(TMath::Abs(track->GetLabel())); + } else { + // MCParticle + mctrack = track; + } + + if(!mctrack) return kFALSE; + + Double_t xv = 0.0; + Double_t yv = 0.0; + + if(TString(mctrack->IsA()->GetName()).CompareTo("AliMCParticle") == 0){ + // case MCParticle + xv = (dynamic_cast(mctrack)->Xv()); + yv = (dynamic_cast(mctrack)->Yv()); + + } else { + // case AODMCParticle + xv = (dynamic_cast(mctrack)->Xv()); + yv = (dynamic_cast(mctrack)->Yv()); + } + + //printf("xv %f, yv %f\n",xv,yv); + + TH2F *test = dynamic_cast(fQA->FindObject("radius")); + if(!test) return kFALSE; + else { + test->Fill(TMath::Abs(xv),TMath::Abs(yv)); + } + + return kTRUE; + +} //__________________________________________ void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){ // @@ -1169,29 +1402,68 @@ void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){ default: AliError("Unknown Plugin"); }; } +//_______________________________________________ +void AliAnalysisTaskHFE::SetWeightFactors(TH3D * const weightFactors){ + // + // Set the histos with the weights for the efficiency maps + // + fWeighting = kTRUE; + fWeightFactors = weightFactors; +} +//_______________________________________________ +void AliAnalysisTaskHFE::SetWeightFactorsFunction(TF1 * const weightFactorsFunction){ + // + // Set the histos with the weights for the efficiency maps + // + fWeighting = kTRUE; + fWeightFactorsFunction = weightFactorsFunction; + //printf("SetWeightFactors\n"); +} +//_______________________________________________ +Double_t AliAnalysisTaskHFE::FindWeight(Double_t pt, Double_t eta, Double_t phi) const { + // + // Find the weight corresponding to pt eta and phi in the TH3D + // + Double_t weight = 1.0; + if(fWeightFactors) { + + TAxis *ptaxis = fWeightFactors->GetXaxis(); + TAxis *etaaxis = fWeightFactors->GetYaxis(); + TAxis *phiaxis = fWeightFactors->GetZaxis(); + + Int_t ptbin = ptaxis->FindBin(pt); + Int_t etabin = etaaxis->FindBin(eta); + Int_t phibin = phiaxis->FindBin(phi); + + + weight = fWeightFactors->GetBinContent(ptbin,etabin,phibin); + } + else if(fWeightFactorsFunction) { + + weight = fWeightFactorsFunction->Eval(pt,eta,phi); + //printf("pt %f and weight %f\n",pt,weight); + + } + //printf("pt %f, eta %f, phi %f, weight %f\n",pt,eta,phi,weight); + + return weight; + +} //__________________________________________ -Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen){ +Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight){ // // Check single track cuts for a given cut step // Fill the particle container // if(!fCFM->CheckParticleCuts(cutStep, track)) return kFALSE; if(signal) { - fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack); - fCFM->GetParticleContainer()->Fill(&container[4], cutStep); + fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack,weight); + fCFM->GetParticleContainer()->Fill(&container[5], cutStep,weight); if(alreadyseen) { - fCFM->GetParticleContainer()->Fill(&container[4], cutStep + AliHFEcuts::kNcutStepsESDtrack); + fCFM->GetParticleContainer()->Fill(&container[5], cutStep + AliHFEcuts::kNcutStepsESDtrack,weight); } } return kTRUE; } -//__________________________________________ -void AliAnalysisTaskHFE::SetTPCBetheBlochParameters(Double_t *pars){ - // - // Set Bethe-Bloch Parameters for TPC PID - // - fPID->SetTPCBetheBlochParameters(pars); -} - diff --git a/PWG3/hfe/AliAnalysisTaskHFE.h b/PWG3/hfe/AliAnalysisTaskHFE.h index 207410e17b4..84ef254e9d8 100644 --- a/PWG3/hfe/AliAnalysisTaskHFE.h +++ b/PWG3/hfe/AliAnalysisTaskHFE.h @@ -40,6 +40,8 @@ class AliMCEvent; class AliVParticle; class TH1I; class TList; +class TH3D; +class TF1; class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ public: @@ -53,22 +55,30 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ kIsElecBackGround = 2, kPostProcess = 3 }; + enum CreationProcess_t{ + kSignalCharm = 0, + kSignalBeauty = 1, + kGammaConv = 2, + kOther = 3 + }; AliAnalysisTaskHFE(); AliAnalysisTaskHFE(const char * name); AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref); AliAnalysisTaskHFE& operator=(const AliAnalysisTaskHFE &ref); + virtual void Copy(TObject &o) const; virtual ~AliAnalysisTaskHFE(); virtual void UserCreateOutputObjects(); virtual void UserExec(Option_t *); virtual void Terminate(Option_t *); + virtual Bool_t IsEventInBinZero(); + Bool_t IsQAOn(Int_t qaLevel) const { return TESTBIT(fQAlevel, qaLevel); }; Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); }; Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); }; Bool_t HasMCData() const { return TestBit(kHasMCdata); } Bool_t GetPlugin(Int_t plug) const { return TESTBIT(fPlugins, plug); }; - Int_t IsSignalElectron(AliVParticle *fTrack) const; void SetHFECuts(AliHFEcuts * const cuts) { fCuts = cuts; }; void SetHFEElecBackGround(AliHFEelecbackground * const elecBackGround) { fElecBackGround = elecBackGround; }; void SetQAOn(Int_t qaLevel) { SETBIT(fQAlevel, qaLevel); }; @@ -77,9 +87,10 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ void SetPIDdetectors(Char_t * const detectors){ fPIDdetectors = detectors; } void SetPIDStrategy(UInt_t strategy) { fPIDstrategy = strategy; } void AddPIDdetector(TString detector); - void SetTPCBetheBlochParameters(Double_t *pars); void SetAODAnalysis() { SetBit(kAODanalysis, kTRUE); }; void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); }; + void SetWeightFactors(TH3D * const weightFactors); + void SetWeightFactorsFunction(TF1 * const weightFactorsFunction); void PrintStatus() const; private: @@ -106,20 +117,29 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ Int_t *fLast; // Pointer to the last entry Int_t *fCurrent; // Current entry to mimic an iterator }; + + Bool_t IsGammaElectron(const AliVParticle * const track) const; + Int_t IsSignalElectron(const AliVParticle * const track) const; + Bool_t FillProductionVertex(const AliVParticle * const track) const; + Double_t FindWeight(Double_t pt, Double_t eta, Double_t phi) const; void MakeParticleContainer(); void MakeEventContainer(); void ProcessMC(); void ProcessESD(); void ProcessAOD(); Bool_t ProcessMCtrack(AliVParticle *track); - Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen); + Bool_t ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen,Double_t weight); ULong_t fQAlevel; // QA level TString fPIDdetectors; // Detectors for Particle Identification UInt_t fPIDstrategy; // PID Strategy Double_t fTPCBetheBlochParameters[5]; // TPC Bethe-Bloch Parameters UShort_t fPlugins; // Enabled Plugins + Bool_t fWeighting; // Weighting or not for the efficiency maps + TH3D *fWeightFactors; // Weight factors + TF1 *fWeightFactorsFunction; // Weight factors AliCFManager *fCFM; //! Correction Framework Manager + AliCFContainer * fHadronicBackground; //! Container for hadronic Background TList *fCorrelation; //! response matrix for unfolding THnSparseF *fPIDperformance; //! info on contamination and yield of electron spectra THnSparseF *fSignalToBackgroundMC; //! Signal To Background Studies on pure MC information @@ -137,7 +157,7 @@ class AliAnalysisTaskHFE : public AliAnalysisTaskSE{ TList *fHistELECBACKGROUND; //! Output container for electron background analysis // AliHFEcollection *fQAcoll; //! collection class for basic QA histograms - ClassDef(AliAnalysisTaskHFE, 1) // The electron Analysis Task + ClassDef(AliAnalysisTaskHFE, 2) // The electron Analysis Task }; #endif diff --git a/PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx b/PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx index 79eac727395..e5573ffdcda 100644 --- a/PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx +++ b/PWG3/hfe/AliAnalysisTaskHFEpidQA.cxx @@ -23,39 +23,44 @@ // #include #include +#include #include "AliAnalysisManager.h" #include "AliMCEventHandler.h" -#include "AliLog.h" -#include "AliAnalysisTaskHFEpidQA.h" #include "AliHFEpidQA.h" -#include "AliESDEvent.h" -#include "AliMCEvent.h" +#include "AliHFEtools.h" +#include "AliESDInputHandler.h" + +#include "AliHFEtrdPIDqa.h" + +#include "AliAnalysisTaskHFEpidQA.h" ClassImp(AliAnalysisTaskHFEpidQA) AliAnalysisTaskHFEpidQA::AliAnalysisTaskHFEpidQA(): - AliAnalysisTaskSE("pidQAtask") + AliAnalysisTaskSE("pidQAtask") , fPIDqa(NULL) , fOutput(NULL) , fEvents(NULL) + , fNNref(NULL) { // // Default Constructor // - DefineOutput(1, TList::Class()); } AliAnalysisTaskHFEpidQA::AliAnalysisTaskHFEpidQA(const Char_t *name): - AliAnalysisTaskSE(name) + AliAnalysisTaskSE(name) , fPIDqa(NULL) , fOutput(NULL) , fEvents(NULL) + , fNNref(NULL) { // // Default Constructor // DefineOutput(1, TList::Class()); + } AliAnalysisTaskHFEpidQA::~AliAnalysisTaskHFEpidQA(){ @@ -79,6 +84,7 @@ void AliAnalysisTaskHFEpidQA::UserCreateOutputObjects(){ fPIDqa = new AliHFEpidQA; if(HasV0pidQA()) fPIDqa->SetV0pidQA(); if(HasRecalculateTRDpid()) fPIDqa->SetRecalculateTRDpid(); + if(fNNref) fPIDqa->SetNNref(fNNref); fPIDqa->Init(); TList *tmp = fPIDqa->GetOutput(); @@ -96,14 +102,15 @@ void AliAnalysisTaskHFEpidQA::UserCreateOutputObjects(){ fOutput->Add(tmp); } - + // Add TRD PID QA object to the output + fOutput->Add(fPIDqa->GetTRDQA()); } + Bool_t AliAnalysisTaskHFEpidQA::UserNotify(){ - // DEBUG + // DEBUG //printf("*****\n"); //printf(" -D Current File Name: %s \n", CurrentFileName()); return AliAnalysisTask::Notify(); - } void AliAnalysisTaskHFEpidQA::UserExec(Option_t *){ @@ -111,15 +118,21 @@ void AliAnalysisTaskHFEpidQA::UserExec(Option_t *){ // Event Loop // AliMCEventHandler* mcHandler = (dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())); + AliESDInputHandler *inh = dynamic_cast(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()); + AliESDpid *workingPID = NULL; + if(inh && (workingPID = inh->GetESDpid())) + fPIDqa->SetESDpid(workingPID); + else fPIDqa->SetESDpid(AliHFEtools::GetDefaultPID(mcHandler ? kTRUE : kFALSE)); + // check the MC data if(fMCEvent && !mcHandler ) return; if(fMCEvent && !mcHandler->InitOk() ) return; if(fMCEvent && !mcHandler->TreeK() ) return; if(fMCEvent && !mcHandler->TreeTR() ) return; if(fMCEvent) fPIDqa->SetMCEvent(fMCEvent); - fPIDqa->SetRun((dynamic_cast(fInputEvent))->GetRunNumber()); - fPIDqa->SetT0((dynamic_cast(fInputEvent))->GetT0()); - fPIDqa->Process(fInputEvent); + + fPIDqa->SetEvent(fInputEvent); + fPIDqa->Process(); fEvents->Fill(1.1); PostData(1, fOutput); } diff --git a/PWG3/hfe/AliAnalysisTaskHFEpidQA.h b/PWG3/hfe/AliAnalysisTaskHFEpidQA.h index 4b2e6c63c50..2b084431e66 100644 --- a/PWG3/hfe/AliAnalysisTaskHFEpidQA.h +++ b/PWG3/hfe/AliAnalysisTaskHFEpidQA.h @@ -26,6 +26,10 @@ class TH1; class TList; +class TFile; + +class AliLog; +class AliMCEvent; class AliHFEpidQA; @@ -45,6 +49,8 @@ class AliAnalysisTaskHFEpidQA : public AliAnalysisTaskSE{ void SetV0pidQA(Bool_t v0pidQA = kTRUE) { SetBit(kV0pidQA, v0pidQA); }; void SetRecalculateTRDpid(Bool_t recal = kTRUE) { SetBit(kRecalculateTRDpid, recal); }; + void SetNNref(TFile *f) { fNNref = f; }; + private: enum{ kV0pidQA = BIT(22), @@ -55,6 +61,7 @@ class AliAnalysisTaskHFEpidQA : public AliAnalysisTaskSE{ AliHFEpidQA *fPIDqa; //! The heart of the analysis TList *fOutput; //! Container for output histos TH1 *fEvents; //! Number of Events + TFile *fNNref; // reference file for NN ClassDef(AliAnalysisTaskHFEpidQA, 1) }; diff --git a/PWG3/hfe/AliHFEV0pid.cxx b/PWG3/hfe/AliHFEV0pid.cxx index 9956fa2b169..a2b1eed7816 100644 --- a/PWG3/hfe/AliHFEV0pid.cxx +++ b/PWG3/hfe/AliHFEV0pid.cxx @@ -24,26 +24,21 @@ // Markus Heide // Markus Fasel // -#include #include -#include -#include - -#include #include "AliAODEvent.h" -#include "AliAODTrack.h" #include "AliAODv0.h" -#include "AliAODVertex.h" #include "AliESDEvent.h" #include "AliESDtrack.h" #include "AliESDv0.h" -#include "AliESDVertex.h" -#include "AliKFParticle.h" #include "AliKFVertex.h" #include "AliVEvent.h" #include "AliVTrack.h" +#include "AliHFEV0cuts.h" +#include "AliHFEV0info.h" +#include "AliHFEcollection.h" + #include "AliHFEV0pid.h" ClassImp(AliHFEV0pid) @@ -57,8 +52,14 @@ AliHFEV0pid::AliHFEV0pid(): , fPionsL(NULL) , fKaons(NULL) , fProtons(NULL) + , fGammas(NULL) + , fK0s(NULL) + , fLambdas(NULL) + , fAntiLambdas(NULL) , fIndices(NULL) , fQA(NULL) + , fV0cuts(NULL) + , fOutput(NULL) { // // Default constructor @@ -68,7 +69,20 @@ AliHFEV0pid::AliHFEV0pid(): fPionsL = new TObjArray(); fKaons = new TObjArray(); fProtons = new TObjArray(); - fIndices = new AliHFEV0pidTrackIndex; + + fElectrons->SetOwner(); + fPionsK0->SetOwner(); + fProtons->SetOwner(); + fPionsL->SetOwner(); + fKaons->SetOwner(); + + fGammas = new TObjArray(); + fK0s = new TObjArray(); + fLambdas = new TObjArray(); + fAntiLambdas = new TObjArray(); + + fIndices = new AliHFEV0pidTrackIndex(); + } //____________________________________________________________ @@ -77,15 +91,21 @@ AliHFEV0pid::~AliHFEV0pid(){ // Destructor // Remove Containers // - if(fInputEvent) delete fInputEvent; - //if(fPrimaryVertex) delete fPrimaryVertex; if(fElectrons) delete fElectrons; if(fPionsK0) delete fPionsK0; if(fPionsL) delete fPionsL; if(fKaons) delete fKaons; if(fProtons) delete fProtons; + + if(fGammas) delete fGammas; + if(fK0s) delete fK0s; + if(fLambdas) delete fLambdas; + if(fAntiLambdas) delete fAntiLambdas; + if(fIndices) delete fIndices; if(fQA) delete fQA; + if(fV0cuts) delete fV0cuts; + if(fOutput) delete fOutput; } //____________________________________________________________ @@ -93,19 +113,20 @@ void AliHFEV0pid::InitQA(){ // // Initialize QA histograms // + + fOutput = new TList(); + + fV0cuts = new AliHFEV0cuts(); + fV0cuts->Init("V0cuts"); + if(!fQA){ fQA = new AliHFEcollection("v0pidQA", "QA histograms for V0 PID"); - // QA histograms for cut statistics - fQA->CreateTH1F("h_cutEfficiencyGamma", "Cut Efficiency for Gammas", 10, 0, 10); - fQA->CreateTH1F("h_cutEfficiencyK0s", "Cut Efficiency for K0s", 10, 0, 10); - fQA->CreateTH1F("h_cutEfficiencyPhi", "Cut Efficiency for Phi", 10, 0, 10); - fQA->CreateTH1F("h_cutEfficiencyLambda", "Cut Efficiency for Lambdas", 10, 0, 10); + fQA->CreateTH1F("h_nV0s", "No. of found and accepted V0s", 5, -0.5, 4.5); // QA histograms for invariant mass fQA->CreateTH1F("h_InvMassGamma", "Gamma invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0, 0.25); - fQA->CreateTH1F("h_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0.4, 0.65); - fQA->CreateTH1F("h_InvMassPhi", "Phi invariant mass; inv mass [GeV/c^{2}]; counts", 100, 0.4, 0.65); + fQA->CreateTH1F("h_InvMassK0s", "K0s invariant mass; inv mass [GeV/c^{2}]; counts", 200, 0.4, 0.65); fQA->CreateTH1F("h_InvMassLambda", "Lambda invariant mass; inv mass [GeV/c^{2}]; counts", 100, 1.05, 1.15); // QA histograms for p distribution (of the daughters) @@ -114,31 +135,12 @@ void AliHFEV0pid::InitQA(){ fQA->CreateTH1F("h_P_Lpion", "P distribution of the Lambda pions; p (GeV/c); counts", 100, 0.1, 10); fQA->CreateTH1F("h_P_Lproton", "P distribution of the Lambda protons; p (GeV/c); counts", 100, 0.1, 10); - // QA invariant mass as a functin of pt - fQA->CreateTH1Fvector1(20, "h_InvMassGamma_pt", "Gamma invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2); - fQA->CreateTH1Fvector1(20, "h_InvMassK0_pt", "K0 invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2); - fQA->CreateTH1Fvector1(20, "h_InvMassPhi_pt", "Phi invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2); - fQA->CreateTH1Fvector1(20, "h_InvMassLambda_pt", "Lambda invarinat mass in pt bins; inv mass [GeV/c^{2}]; counts", 250, 0, 2); - // QA pt of the V0 fQA->CreateTH1F("h_Pt_Gamma", "Pt of the gamma conversion; p_{T} (GeV/c); counts", 100, 0, 10); fQA->CreateTH1F("h_Pt_K0", "Pt of the K0; p_{T} (GeV/c); counts", 100, 0, 10); - fQA->CreateTH1F("h_Pt_Phi", "Pt of the Phi; p_{T} (GeV/c); counts", 100, 0, 10); - fQA->CreateTH1F("h_Pt_Lambda", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10); - //fQA->CreateTH1F("h_Pt_electrons", "Pt of the conversion electrons; p_{T} (GeV/c); counts"); - //fQA->CreateTH1F("h_Pt_pionsK0", "Pt of the K0 pions; p_{T} (GeV/c); counts"); - //fQA->CreateTH1F("h_Pt_pionsL", "Pt of the Lambda pions; p_{T} (GeV/c); counts"); - //fQA->CreateTH1F("h_Pt_protons", "Pt of the Lambda protons; p_{T} (GeV/c); counts"); - - - // QA histogram for both Lambda candidate combinations - - fQA->CreateTH2F("h_L0_dca_v_dMass", "L0 dca verus dMass; dMass [GeV/c^{2}]; dDCA [cm]; ", 100, -1., 1., 100, 0., 5.); + fQA->CreateTH1F("h_Pt_Lambda", "Pt of the Lambda; p_{T} (GeV/c); counts", 100, 0, 10); + - // Chi2 histograms - fQA->CreateTH1F("h_chi2_gamma", "Chi2 for gammas", 10000, 0, 1000); - fQA->CreateTH1F("h_chi2_K0s", "Chi2 for K0s", 10000, 0, 500); - fQA->CreateTH1F("h_chi2_Phi", "Chi2 for K0s", 10000, 0, 500); - fQA->CreateTH1F("h_chi2_Lambda", "Chi2 for Lambdas", 10000, 0, 1000); } } @@ -149,17 +151,21 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){ // Find protons, pions and electrons using V0 decays and // store the pointers in the TObjArray // + Int_t nGamma = 0, nK0s = 0, nLambda = 0, nPhi = 0; fInputEvent = inputEvent; - fIndices->Init(fInputEvent->GetNumberOfV0s() * 2); fPrimaryVertex = new AliKFVertex(*(fInputEvent->GetPrimaryVertex())); + if(!fPrimaryVertex) return; + fV0cuts->SetInputEvent(fInputEvent); + fV0cuts->SetPrimaryVertex(fPrimaryVertex); Int_t v0status = 0; for(Int_t iv0 = 0; iv0 < fInputEvent->GetNumberOfV0s(); iv0++){ if(!TString(fInputEvent->IsA()->GetName()).CompareTo("AliESDEvent")){ // case ESD SetESDanalysis(); AliESDv0 *esdV0 = (dynamic_cast(fInputEvent))->GetV0(iv0); + if(!esdV0) continue; if(!esdV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder v0status = ProcessV0(esdV0); } else { @@ -168,6 +174,8 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){ AliAODv0 *aodV0 = (dynamic_cast(fInputEvent))->GetV0(iv0); if(aodV0->GetOnFlyStatus()) continue; // Take only V0s from the On-the-fly v0 finder v0status = ProcessV0(aodV0); + if(kUndef != v0status){ + } } switch(v0status){ case kRecoGamma: nGamma++; break; @@ -177,6 +185,7 @@ void AliHFEV0pid::Process(AliVEvent * const inputEvent){ }; } + AliDebug(1, Form("Number of gammas : %d", nGamma)); AliDebug(1, Form("Number of K0s : %d", nK0s)); AliDebug(1, Form("Number of Phis : %d", nPhi)); @@ -200,21 +209,35 @@ Int_t AliHFEV0pid::ProcessV0(TObject *v0){ // AliVTrack* daughter[2]; daughter[0] = dynamic_cast(fInputEvent->GetTrack((dynamic_cast(v0))->GetPindex())); - daughter[1] = dynamic_cast(fInputEvent->GetTrack((dynamic_cast(v0))->GetPindex())); + daughter[1] = dynamic_cast(fInputEvent->GetTrack((dynamic_cast(v0))->GetNindex())); if(!daughter[0] || !daughter[1]) return kUndef; + if(IsESDanalysis()){ for(Int_t i=0; i<2; ++i){ - if(!CutESDtrack(dynamic_cast(daughter[i]))) return kUndef; + // check common single track cuts + if(!fV0cuts->TrackCutsCommon(dynamic_cast(daughter[i]))) return kUndef; } + // check commom V0 cuts + if(!fV0cuts->V0CutsCommon(dynamic_cast(v0))) return kUndef; } - if(IsGammaConv(v0)) return kRecoGamma; - else if(IsK0s(v0)) return kRecoK0s; - else if(IsLambda(v0)) return kRecoLambda; + + // store the resutls + if(IsGammaConv(v0)){ + fQA->Fill("h_nV0s", kRecoGamma); + return kRecoGamma; + } + else if(IsK0s(v0)){ + fQA->Fill("h_nV0s", kRecoK0s); + return kRecoK0s; + } + else if(IsLambda(v0)){ + fQA->Fill("h_nV0s", kRecoLambda); + return kRecoLambda; + } else return kUndef; - - + } //____________________________________________________________ void AliHFEV0pid::Flush(){ @@ -222,13 +245,12 @@ void AliHFEV0pid::Flush(){ // Clear the Lists // AliDebug(1, "Flushing containers"); - fProtons->Clear(); - fPionsK0->Clear(); - fPionsL->Clear(); - fElectrons->Clear(); + fProtons->Delete(); + fPionsK0->Delete(); + fPionsL->Delete(); + fElectrons->Delete(); fIndices->Flush(); } - //____________________________________________________________ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){ // @@ -237,21 +259,22 @@ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){ AliVTrack* daughter[2]; Int_t pIndex = 0, nIndex = 0; Double_t invMass = 0.; + Double_t mPt = 0.; + Int_t v0id = -1; if(IsESDanalysis()){ // ESD - cut V0 AliESDv0 *esdV0 = dynamic_cast(v0); - if(!CutV0(esdV0, kRecoGamma)) return kFALSE; - if(LooseRejectK0(esdV0) || LooseRejectLambda(esdV0)) return kFALSE; - // DEBUG - //invMass = esdV0->GetEffMass(AliPID::kElectron, AliPID::kElectron); - invMass = GetEffMass(esdV0, AliPID::kElectron, AliPID::kElectron); - //.. - + v0id = esdV0->GetLabel(); + // apply FULL gamma cuts + if(!fV0cuts->GammaCuts(esdV0)) return kFALSE; + invMass = esdV0->GetEffMass(AliPID::kElectron, AliPID::kElectron); pIndex = esdV0->GetPindex(); nIndex = esdV0->GetNindex(); + mPt = esdV0->Pt(); } else { // AOD Analysis - not possible to cut AliAODv0 *aodV0 = dynamic_cast(v0); + v0id = aodV0->GetID(); pIndex = aodV0->GetPosID(); nIndex = aodV0->GetNegID(); invMass = aodV0->InvMass2Prongs(0, 1, kElectron, kElectron); @@ -259,61 +282,52 @@ Bool_t AliHFEV0pid::IsGammaConv(TObject *v0){ daughter[0] = dynamic_cast(fInputEvent->GetTrack(pIndex)); daughter[1] = dynamic_cast(fInputEvent->GetTrack(nIndex)); if(!daughter[0] || !daughter[1]) return kFALSE; + + // DEBUG + AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID())); - // Get Invariant mass and chi2/ndf - AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kElectron), TMath::Abs(kElectron)); - kfMother->SetProductionVertex(*fPrimaryVertex); - kfMother->SetMassConstraint(0, 1.); - Double_t ndf = kfMother->GetNDF(); - Double_t chi2 = kfMother->GetChi2(); - delete kfMother; - - if(fQA) fQA->Fill("h_chi2_gamma", chi2/ndf); - if(chi2/ndf > 7) return kFALSE; - Double_t mPt = kfMother->GetPt(); + // AFTER all gamma cuts fQA->Fill("h_Pt_Gamma", mPt); - Int_t ptBin = (int)(mPt*10.0); + fQA->Fill("h_InvMassGamma", invMass); - if(fQA) fQA->Fill("h_InvMassGamma", invMass); - if(invMass > 0.05) return kFALSE; - fQA->Fill("h_InvMassGamma_pt", ptBin+1, invMass); - - AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID())); // Identified gamma - store tracks in the electron containers if(!fIndices->Find(daughter[0]->GetID())){ AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID())); - fElectrons->Add(daughter[0]); + fElectrons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoElectron); } if(!fIndices->Find(daughter[1]->GetID())){ AliDebug(1, Form("Gamma identified, daughter IDs: %d,%d", daughter[1]->GetID(), daughter[1]->GetID())); - fElectrons->Add(daughter[1]); + fElectrons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoElectron); } + fGammas->Add(v0); + return kTRUE; } - - - //____________________________________________________________ Bool_t AliHFEV0pid::IsK0s(TObject *v0){ // // Identify K0s // - const Double_t kK0smass=TDatabasePDG::Instance()->GetParticle(kK0Short)->Mass(); // PDG K0s mass AliVTrack* daughter[2]; Int_t pIndex = 0, nIndex = 0; + Int_t v0id = -1; Double_t invMass = 0.; + Double_t mPt = 0.; if(IsESDanalysis()){ // ESD - cut V0 AliESDv0 *esdV0 = dynamic_cast(v0); - if(!CutV0(esdV0, kRecoK0s)) return kFALSE; - invMass = esdV0->GetEffMass(AliPID::kPion, AliPID::kPion); + if(!fV0cuts->K0Cuts(esdV0)) return kFALSE; + v0id = esdV0->GetLabel(); pIndex = esdV0->GetPindex(); nIndex = esdV0->GetNindex(); + invMass = esdV0->GetEffMass(AliPID::kPion, AliPID::kPion); + mPt = esdV0->Pt(); } else { // AOD Analysis - not possible to cut AliAODv0 *aodV0 = dynamic_cast(v0); + aodV0->GetID(); pIndex = aodV0->GetPosID(); nIndex = aodV0->GetNegID(); invMass = aodV0->MassK0Short(); @@ -322,37 +336,24 @@ Bool_t AliHFEV0pid::IsK0s(TObject *v0){ daughter[1] = dynamic_cast(fInputEvent->GetTrack(nIndex)); if(!daughter[0] || !daughter[1]) return kFALSE; - // Get Invariant mass and chi2/ndf - AliKFParticle *kfMother = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kPiPlus)); - kfMother->SetProductionVertex(*fPrimaryVertex); - kfMother->SetMassConstraint(kK0smass, 0.); - Double_t ndf = kfMother->GetNDF(); - Double_t chi2 = kfMother->GetChi2(); - delete kfMother; - - if(fQA) fQA->Fill("h_chi2_K0s", chi2/ndf); - if(chi2/ndf > 5) return kFALSE; - Double_t mPt = kfMother->GetPt(); fQA->Fill("h_Pt_K0", mPt); - Int_t ptBin = (int)(mPt*10.0); - fQA->Fill("h_InvMassK0_pt", ptBin+1, invMass); + fQA->Fill("h_InvMassK0s", invMass); - if(fQA) fQA->Fill("h_InvMassK0s", invMass); - - if(invMass < 0.485 || invMass > 0.51) return kFALSE; AliDebug(1, Form("K0 identified, daughter IDs: %d,%d", daughter[0]->GetID(), daughter[1]->GetID())); + // AFTER all K0 cuts // Identified gamma - store tracks in the electron containers if(!fIndices->Find(daughter[0]->GetID())){ AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[0]->GetID())); - fPionsK0->Add(daughter[0]); + fPionsK0->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoPionK0); } if(!fIndices->Find(daughter[1]->GetID())){ AliDebug(1, Form("Adding K0 Pion track with ID %d", daughter[1]->GetID())); - fPionsK0->Add(daughter[1]); + fPionsK0->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionK0); } + fK0s->Add(v0); return kTRUE; } @@ -364,15 +365,12 @@ Bool_t AliHFEV0pid::IsPhi(TObject *v0){ //const Double_t kPhiMass=TDatabasePDG::Instance()->GetParticle(333)->Mass(); // PDG phi mass //AliVTrack* daughter[2]; - //AliKFParticle *mother = NULL; //Double_t invMass = 0.; Int_t pIndex = 0, nIndex = 0; if(IsESDanalysis()){ // ESD - cut V0 AliESDv0 *esdV0 = dynamic_cast(v0); - if(!CutV0(esdV0, kRecoPhi)) return kFALSE; - if(LooseRejectGamma(esdV0) || LooseRejectK0(esdV0)) return kFALSE; pIndex = esdV0->GetPindex(); nIndex = esdV0->GetNindex(); } else { @@ -388,472 +386,68 @@ Bool_t AliHFEV0pid::IsLambda(TObject *v0){ // // Identify Lambda // - const Double_t kL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(); // PDG lambda mass AliVTrack* daughter[2]; Int_t pIndex = 0, nIndex = 0; - AliKFParticle *mother[2] = {NULL, NULL}; - Float_t dMass[2]; // lambda mass difference for the two hypoteses - //Int_t lambda = 0; // [1] for lambda and [-1] for anti-lambda - Double_t chi2 = 0.; - Double_t invMass = 0.; - Double_t invMassEOD = 0; + Bool_t isLambda = kTRUE; // Lambda - kTRUE, Anti Lambda - kFALSE + Int_t v0id = -1; if(IsESDanalysis()){ // ESD - cut V0 AliESDv0 *esdV0 = dynamic_cast(v0); - if(!CutV0(esdV0, kRecoLambda)) return kFALSE; - if(LooseRejectK0(esdV0) || LooseRejectGamma(esdV0)) return kFALSE; - pIndex = esdV0->GetPindex(); - nIndex = esdV0->GetNindex(); - - //invMass = esdV0->GetEffMass(AliPID::kPion, AliPID::kPion); - + v0id = esdV0->GetLabel(); + if(!fV0cuts->LambdaCuts(esdV0,isLambda)) return kFALSE; + if(fV0cuts->CheckSigns(esdV0)){ + pIndex = esdV0->GetPindex(); + nIndex = esdV0->GetNindex(); + } + else{ + pIndex = esdV0->GetNindex(); + nIndex = esdV0->GetPindex(); + } } else { // PRELIMINARY - !!! // AOD Analysis - not possible to cut // again - two cases as above AliAODv0 *aodV0 = dynamic_cast(v0); + v0id = aodV0->GetID(); pIndex = aodV0->GetPosID(); nIndex = aodV0->GetNegID(); - invMassEOD = aodV0->MassLambda(); - } - + invMass = aodV0->MassLambda(); + } + daughter[0] = dynamic_cast(fInputEvent->GetTrack(pIndex)); daughter[1] = dynamic_cast(fInputEvent->GetTrack(nIndex)); if(!daughter[0] || !daughter[1]) return kFALSE; - - // - // now - go over two case - Lambda and AntiLambda - // choose the on ewhere the resulting lambda mass is close to the - // expected value and at the same time points closer to the primary vertex in XY plane - // - // A) lambda -> proton + negative-pion - // B) anti-lambda -> anti-proton + positive-pion - // - - // - // A) :: proton - // - mother[0] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kProton), TMath::Abs(kPiPlus)); - AliHFELambdaInf lambda0(mother[0], fPrimaryVertex); - - // Undo changes - *fPrimaryVertex -= *mother[0]; - AddTrackToKFVertex(daughter[0], TMath::Abs(kProton)); - AddTrackToKFVertex(daughter[1], TMath::Abs(kPiPlus)); - - // - // B) :: anti-proton - // - mother[1] = CreateMotherParticle(daughter[0], daughter[1], TMath::Abs(kPiPlus), TMath::Abs(kProton)); - AliHFELambdaInf lambda1(mother[1], fPrimaryVertex); - - // qa histograms - dMass[0] = lambda0.GetInvariantMass() - kL0mass; - dMass[1] = lambda1.GetInvariantMass() - kL0mass; - fQA->Fill("h_L0_dca_v_dMass", dMass[0], lambda0.GetDistanceFromPrimaryVertex()); - fQA->Fill("h_L0_dca_v_dMass", dMass[1], lambda1.GetDistanceFromPrimaryVertex()); - - // - // decide on the true Lambda candidate bsaed on - // - mass difference - // - vertex dca (testing needed first) - // - AliHFELambdaInf *lambdaInf[2] = {&lambda0, &lambda1}; - Bool_t isLambda = kFALSE; - Int_t index = -1; - index = (dMass[0] GetInvariantMass(); - chi2 = lambdaInf[index]->GetChi2NDF(); - //if(!IsESDanalysis()){ - // invMass = invMassEOD; - //} - //else{ - // invMass = mother[index]->GetMass(); - //} - if(fQA) fQA->Fill("h_chi2_Lambda", chi2); - if(chi2 < 3){ - if(fQA) fQA->Fill("h_InvMassLambda", invMass); - Double_t mPt = mother[index]->GetPt(); - fQA->Fill("h_Pt_Lambda", mPt); - Int_t ptBin = (int)(mPt*10.0); - fQA->Fill("h_InvMassLambda_pt", ptBin+1, invMass); - - // cut on the invariant mass for the proton and pion selection - if(invMass > 1.11 || invMass < 1.12){ - // Identified lambdas - store the protons and pions and update primary vertex - *fPrimaryVertex += *mother[index]; - - // lambda - if(0 == index){ - if(!fIndices->Find(daughter[0]->GetID())){ - fProtons->Add(daughter[0]); - fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoProton); - } - if(!fIndices->Find(daughter[1]->GetID())){ - fPionsL->Add(daughter[1]); - fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionL); - } - } - // antilambda - if(1 == index){ - if(!fIndices->Find(daughter [1]->GetID())){ - fProtons->Add(daughter[1]); - fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoProton); - } - if(!fIndices->Find(daughter [0]->GetID())){ - fPionsL->Add(daughter[0]); - fIndices->Add(daughter [0]->GetID(), AliHFEV0pid::kRecoPionL); - } - } - isLambda = kTRUE; + + // lambda + if(isLambda){ + if(!fIndices->Find(daughter[0]->GetID())){ + fProtons->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); + fIndices->Add(daughter[0]->GetID(), AliHFEV0pid::kRecoProton); } - } - - if(!isLambda){ - // Add the daughters again to the primary vertex - AddTrackToKFVertex(daughter[0], TMath::Abs(kPiPlus)); - AddTrackToKFVertex(daughter[1], TMath::Abs(kProton)); - } - // remove the objects - for(Int_t i=0; i<2; ++i){ - if (mother[i]) delete mother[i]; - } - - return isLambda; -} - -//____________________________________________________________ -AliKFParticle *AliHFEV0pid::CreateMotherParticle(AliVTrack *pdaughter, AliVTrack *ndaughter, Int_t pspec, Int_t nspec){ - // - // Creates a mother particle - // - AliKFParticle pkfdaughter(*pdaughter, pspec); - AliKFParticle nkfdaughter(*ndaughter, nspec); - - // check if the daughter particles are coming from the primary vertex - if(IsESDanalysis()){ - // ESD Analyis - const AliESDVertex *esdvertex = dynamic_cast(fInputEvent->GetPrimaryVertex()); - UShort_t *contrib = esdvertex->GetIndices(); - - Int_t nfound = 0; - for(Int_t id = 0; id < esdvertex->GetNIndices(); id++){ - if(contrib[id] == pdaughter->GetID()){ - *fPrimaryVertex -= pkfdaughter; - nfound++; - } - if(contrib[id] == ndaughter->GetID()){ - *fPrimaryVertex -= nkfdaughter; - nfound++; - } - if(nfound == 2) break; + if(!fIndices->Find(daughter[1]->GetID())){ + fPionsL->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); + fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoPionL); } - } else { - // AOD Analysis: AOD Vertex - const AliAODVertex *aodvertex = dynamic_cast(fInputEvent->GetPrimaryVertex()); - if(aodvertex->HasDaughter(pdaughter)) - *fPrimaryVertex -= pkfdaughter; - if(aodvertex->HasDaughter(ndaughter)) - *fPrimaryVertex -= nkfdaughter; } - - // Create the mother particle and add them to the primary vertex - AliKFParticle *mother = new AliKFParticle(pkfdaughter, nkfdaughter); - *fPrimaryVertex += *mother; - - return mother; -} - -//____________________________________________________________ -void AliHFEV0pid::AddTrackToKFVertex(AliVTrack *track, Int_t species){ - // - // Add track to the primary vertex (if it was used in the vertex - // calculation) - // - Bool_t isAdd = kFALSE; - if(IsESDanalysis()){ - const AliESDVertex *esdvertex = dynamic_cast(fInputEvent->GetPrimaryVertex()); - UShort_t *contrib = esdvertex->GetIndices(); - for(Int_t id = 0; id < esdvertex->GetNIndices(); id++){ - if(contrib[id] == track->GetID()){ - isAdd = kTRUE; - break; - } + // antilambda + else{ + if(!fIndices->Find(daughter [1]->GetID())){ + fProtons->Add(new AliHFEV0info(daughter[1], daughter[0]->GetID(), v0id)); + fIndices->Add(daughter[1]->GetID(), AliHFEV0pid::kRecoProton); + } + if(!fIndices->Find(daughter [0]->GetID())){ + fPionsL->Add(new AliHFEV0info(daughter[0], daughter[1]->GetID(), v0id)); + fIndices->Add(daughter [0]->GetID(), AliHFEV0pid::kRecoPionL); } - } else { - const AliAODVertex *aodvertex = dynamic_cast(fInputEvent->GetPrimaryVertex()); - if(aodvertex->HasDaughter(track)) isAdd = kTRUE; - } - if(isAdd){ - AliKFParticle kftrack(*track, species); - *fPrimaryVertex += kftrack; } -} - -//____________________________________________________________ -Bool_t AliHFEV0pid::CutV0(AliESDv0 *v0, Int_t V0species){ - // - // Cut the V0 - // - Int_t cutRequired = 0; - // For cut always take min and max - Double_t cutCosPoint[2] = {0., 0.}, - cutDCA[2] = {0., 0.}, - cutProdVtx[2] = {0., 0.}, - cutOpAng[2] = {0., 0.}, - cutPsiPair[2] = {0., 0.}; - - switch(V0species){ - case kRecoGamma: - cutCosPoint[1] = 0.03; - SETBIT(cutRequired, 1); - cutDCA[1] = 0.25; - SETBIT(cutRequired, 3); - cutProdVtx[0] = 6; - SETBIT(cutRequired, 4); - cutOpAng[1] = 0.1; - SETBIT(cutRequired, 7); - cutPsiPair[1] = 0.05; - SETBIT(cutRequired, 9); - break; - case kRecoK0s: - cutCosPoint[1] = 0.03; - SETBIT(cutRequired, 1); - cutDCA[1] = 0.1; - SETBIT(cutRequired, 3); - cutProdVtx[1] = 8.1; - SETBIT(cutRequired, 5); - break; - case kRecoPhi: - break; - case kRecoLambda: - cutCosPoint[1] = 0.03; - SETBIT(cutRequired, 1); - cutDCA[1] = 0.2; - SETBIT(cutRequired, 3); - cutProdVtx[1] = 24; - SETBIT(cutRequired, 5); - break; - default: - // unidentified, return - return kFALSE; - }; - - Char_t hname[256]; - const Char_t *specname[4] = {"Gamma", "K0s", ", Phi", "Lambda"}; - sprintf(hname, "h_cutEfficiency%s", specname[V0species-1]); - - // Cut on pointing angle - Double_t cosPoint = v0->GetV0CosineOfPointingAngle(); - if(TESTBIT(cutRequired, 0) && TMath::ACos(cosPoint) < cutCosPoint[0]) return kFALSE; - if(fQA) fQA->Fill(hname, 0); - if(TESTBIT(cutRequired, 1) && TMath::ACos(cosPoint) > cutCosPoint[1]) return kFALSE; - if(fQA) fQA->Fill(hname, 1); + if(isLambda) fLambdas->Add(v0); + else fAntiLambdas->Add(v0); - // Cut on DCA between daughters - Double_t dca = v0->GetDcaV0Daughters(); - if(TESTBIT(cutRequired, 2) && dca < cutDCA[0]) return kFALSE; - if(fQA) fQA->Fill(hname, 2); - if(TESTBIT(cutRequired, 3) && dca > cutDCA[1]) return kFALSE; - if(fQA) fQA->Fill(hname, 3); - - // Cut on reconstructed verted position - Double_t x, y, z; - v0->GetXYZ(x,y,z); - Double_t r = TMath::Sqrt(x*x + y*y); - if(TESTBIT(cutRequired, 4) && r < cutProdVtx[0]) return kFALSE; - if(fQA) fQA->Fill(hname, 4); - if(TESTBIT(cutRequired, 5) && r > cutProdVtx[1]) return kFALSE; - if(fQA) fQA->Fill(hname, 5); - - //Cut on Opening angle (conversions only) - if(TESTBIT(cutRequired, 6) && OpenAngle(v0) < cutOpAng[0]) return kFALSE; - if(fQA) fQA->Fill(hname, 6); - if(TESTBIT(cutRequired, 7) && OpenAngle(v0) > cutOpAng[1]) return kFALSE; - if(fQA) fQA->Fill(hname, 7); - - //Cut on PsiPair angle (conversons only) - if(TESTBIT(cutRequired, 8) && PsiPair(v0) < cutPsiPair[0]) return kFALSE; - if(fQA) fQA->Fill(hname, 8); - if(TESTBIT(cutRequired, 9) && PsiPair(v0) > cutPsiPair[1]) return kFALSE; - if(fQA) fQA->Fill(hname, 9); return kTRUE; } -//____________________________________________________________ -Bool_t AliHFEV0pid::CutESDtrack(AliESDtrack *track){ - // - // Single track cuts - // - // Hard coaded cut values for the beginning - // - - if(!track) return kFALSE; - - // status word - ULong_t status = track->GetStatus(); - - // DCA - to Vertex R & Z - Float_t dcaR = -1.; - Float_t dcaZ = -1.; - track->GetImpactParameters(dcaR, dcaZ); - //if(dcaR > 4.0) return kFALSE; - //if(dcaZ > 10.0) return kFALSE; - - // No. of TPC clusters - if(track->GetTPCNcls() < 80) return kFALSE; - - // TPC refit - if(!(status & AliESDtrack::kTPCrefit)) return kFALSE; - - // Chi2 per TPC cluster - Int_t nTPCclusters = track->GetTPCclusters(0); - Float_t chi2perTPCcluster = track->GetTPCchi2()/Float_t(nTPCclusters); - if(chi2perTPCcluster > 3.5) return kFALSE; - - // TPC cluster ratio - Float_t cRatioTPC = track->GetTPCNclsF() > 0. ? static_cast(track->GetTPCNcls())/static_cast (track->GetTPCNclsF()) : 1.; - if(cRatioTPC < 0.6) return kFALSE; - - // kinks - if(track->GetKinkIndex(0) != 0) return kFALSE; - - // Covariance matrix - TO BE RECONSIDERED - Double_t extCov[15]; - track->GetExternalCovariance(extCov); - //if(extCov[0] > 2. ) return kFALSE; - //if(extCov[2] > 2. ) return kFALSE; - //if(extCov[5] > 0.5) return kFALSE; - //if(extCov[9] > 0.5) return kFALSE; - //if(extCov[14] > 2. ) return kFALSE; - - // pt - if(track->Pt() < 0.1 || track->Pt() > 100) return kFALSE; - - // eta - if(TMath::Abs(track->Eta()) > 0.9) return kFALSE; - - // the track made it through! :-) - return kTRUE; -} - -//_________________________________________________ -Bool_t AliHFEV0pid::LooseRejectK0(AliESDv0 * const v0) const { - // - // Reject K0 based on loose cuts - // - Double_t mass = v0->GetEffMass(AliPID::kPion, AliPID::kPion); - if(mass > 0.494 && mass < 0.501) return kTRUE; - return kFALSE; -} - -//_________________________________________________ -Bool_t AliHFEV0pid::LooseRejectLambda(AliESDv0 * const v0) const { - // - // Reject Lambda based on loose cuts - // - Double_t mass1 = v0->GetEffMass(AliPID::kPion, AliPID::kProton); - Double_t mass2 = v0->GetEffMass(AliPID::kProton, AliPID::kPion); - - if(mass1 > 1.1 && mass1 < 1.12) return kTRUE; - if(mass2 > 1.1 && mass2 < 1.12) return kTRUE; - return kFALSE; -} - -//_________________________________________________ -Bool_t AliHFEV0pid::LooseRejectGamma(AliESDv0 * const v0) const { - // - // Reject Lambda based on loose cuts - // - - //Double_t mass = v0->GetEffMass(AliPID::kElectron, AliPID::kElectron); - // DEBUG temporary solution, see the comment in GetEffMass - Double_t mass = GetEffMass(v0, AliPID::kElectron, AliPID::kElectron); - //.. - if(mass < 0.02) return kTRUE; - return kFALSE; -} - -//_________________________________________________ -Float_t AliHFEV0pid::OpenAngle(AliESDv0 *v0) const { - // - // Opening angle between two daughter tracks - // - Double_t mn[3] = {0,0,0}; - Double_t mp[3] = {0,0,0}; - - - v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter; - v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; - - - Float_t openAngle = TMath::ACos((mp[0]*mn[0] + mp[1]*mn[1] + mp[2]*mn[2])/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1] + mp[2]*mp[2])*TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1] + mn[2]*mn[2]))); - - return TMath::Abs(openAngle); -} - -//_________________________________________________ -Float_t AliHFEV0pid::PsiPair(AliESDv0 *v0) { - // - // Angle between daughter momentum plane and plane - // - Float_t magField = fInputEvent->GetMagneticField(); - - Int_t pIndex = v0->GetPindex(); - Int_t nIndex = v0->GetNindex(); - - AliESDtrack* daughter[2]; - - daughter[0] = dynamic_cast(fInputEvent->GetTrack(pIndex)); - daughter[1] = dynamic_cast(fInputEvent->GetTrack(nIndex)); - - Double_t x, y, z; - v0->GetXYZ(x,y,z);//Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions! - - Double_t mn[3] = {0,0,0}; - Double_t mp[3] = {0,0,0}; - - - v0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter; - v0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; - - - Double_t deltat = 1.; - deltat = TMath::ATan(mp[2]/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1])+1.e-13)) - TMath::ATan(mn[2]/(TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1])+1.e-13));//difference of angles of the two daughter tracks with z-axis - - Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated - - Double_t momPosProp[3]; - Double_t momNegProp[3]; - - AliExternalTrackParam pt(*daughter[0]), nt(*daughter[1]); - - Float_t psiPair = 4.; - - if(nt.PropagateTo(radiussum,magField) == 0)//propagate tracks to the outside - psiPair = -5.; - if(pt.PropagateTo(radiussum,magField) == 0) - psiPair = -5.; - pt.GetPxPyPz(momPosProp);//Get momentum vectors of tracks after propagation - nt.GetPxPyPz(momNegProp); - - Double_t pEle = - TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);//absolute momentum value of negative daughter - Double_t pPos = - TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);//absolute momentum value of positive daughter - - Double_t scalarproduct = - momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];//scalar product of propagated positive and negative daughters' momenta - - Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks - - psiPair = TMath::Abs(TMath::ASin(deltat/chipair)); - - return psiPair; -} - //____________________________________________________________ AliHFEV0pid::AliHFEV0pidTrackIndex::AliHFEV0pidTrackIndex(): fNElectrons(0) @@ -988,81 +582,19 @@ Bool_t AliHFEV0pid::AliHFEV0pidTrackIndex::Find(Int_t index) const { } //____________________________________________________________ -AliHFEV0pid::AliHFELambdaInf::AliHFELambdaInf(AliKFParticle *mother, AliKFVertex * const primaryVertex): - fInvariantMass(0.), - fChi2NDF(0.), - fDistVtx(0.) -{ - // - // Constructor - // Fill infos - // - const Double_t kL0mass=TDatabasePDG::Instance()->GetParticle(kLambda0)->Mass(); // PDG lambda mass - fInvariantMass = mother->GetMass(); - // distance frm the privary vertex and mass difference for the (A) case - fDistVtx = mother->GetDistanceFromVertex(*primaryVertex); - // apply constraints for the fit - mother->SetMassConstraint(kL0mass, 0.); - mother->SetProductionVertex(*primaryVertex); - fChi2NDF = mother->GetChi2()/mother->GetNDF(); -} -//____________________________________________________________ -AliHFEV0pid::AliHFELambdaInf::~AliHFELambdaInf(){ - // - // destructor - // -} -//____________________________________________________________ -// DEBUG -//____________________________________________________________ -Double_t AliHFEV0pid::GetEffMass(AliESDv0 *v0, UInt_t p1, UInt_t p2) const{ - // - // TEMPORARY - this function should become obsolete with v4-18-Rev-10 or 11 - // calculate effective mass - // - const Double_t kpmass[5] = {TDatabasePDG::Instance()->GetParticle(kElectron)->Mass(), - TDatabasePDG::Instance()->GetParticle(kMuonMinus)->Mass(), - TDatabasePDG::Instance()->GetParticle(kPiPlus)->Mass(), - TDatabasePDG::Instance()->GetParticle(kKPlus)->Mass(), - TDatabasePDG::Instance()->GetParticle(kProton)->Mass()}; // float - if (p1>4) return -1; - if (p2>4) return -1; - Double_t mass1 = kpmass[p1]; // float - Double_t mass2 = kpmass[p2]; // float - - Double_t pMom[3]; - Double_t nMom[3]; - - v0->GetPPxPyPz(pMom[0], pMom[1], pMom[2]); - v0->GetNPxPyPz(nMom[0], nMom[1], nMom[2]); - - - const Double_t *m1 = pMom; - const Double_t *m2 = nMom; +TList *AliHFEV0pid::GetListOfQAhistograms(){ // - //if (fRP[p1]+fRM[p2]GetList(); + tmp->SetName("V0cuts"); + fOutput->Add(tmp); + if(fQA){ + tmp = 0x0; + tmp = fQA->GetList(); + tmp->SetName("V0pid"); + fOutput->Add(tmp); + } + return fOutput; } diff --git a/PWG3/hfe/AliHFEV0pid.h b/PWG3/hfe/AliHFEV0pid.h index 1413ead040f..8d66402d163 100644 --- a/PWG3/hfe/AliHFEV0pid.h +++ b/PWG3/hfe/AliHFEV0pid.h @@ -24,12 +24,9 @@ #include #endif -#ifndef ALIHFECOLLECTION_H -#include "AliHFEcollection.h" -#endif - class TObjArray; class TList; +class TString; class AliESDv0; class AliESDtrack; @@ -38,6 +35,9 @@ class AliKFVertex; class AliVEvent; class AliVTrack; +class AliHFEV0cuts; +class AliHFEcollection; + class AliHFEV0pid : public TObject{ public: enum{ // Reconstructed V0 @@ -50,22 +50,20 @@ class AliHFEV0pid : public TObject{ }; enum{ // Identified Daughter particles kRecoElectron = 0, - kRecoPionK0 = 1, - kRecoPionL = 2, - kRecoKaon = 3, - kRecoProton = 4 - }; + kRecoPionK0 = 1, + kRecoPionL = 2, + kRecoKaon = 3, + kRecoProton = 4 + }; AliHFEV0pid(); ~AliHFEV0pid(); - Double_t GetEffMass(AliESDv0 *v0, UInt_t p1, UInt_t p2) const; - - void Process(AliVEvent * const inputEvent); + void Process(AliVEvent * const inputEvent); Int_t ProcessV0(TObject *v0); - void Flush(); + void Flush(); - void InitQA(); - inline TList *GetListOfQAhistograms(); + void InitQA(); + TList *GetListOfQAhistograms(); TObjArray *GetListOfElectrons() const { return fElectrons; } TObjArray *GetListOfPionsK0() const { return fPionsK0; } @@ -73,82 +71,55 @@ class AliHFEV0pid : public TObject{ TObjArray *GetListOfKaons() const { return fKaons; } TObjArray *GetListOfProtons() const { return fProtons; } - Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); } - Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); } - void SetAODanalysis(Bool_t isAOD = kTRUE) { SetBit(kAODanalysis, isAOD); }; - void SetESDanalysis(Bool_t isESD = kTRUE) { SetBit(kAODanalysis, !isESD); }; - private: - Float_t PsiPair(AliESDv0 *esdv0);//angle between daughters in plane perpendicular to magnetic field (characteristically around zero for conversions) - Float_t OpenAngle(AliESDv0 *esdv0) const;//opening angle between V0 daughters; close to zero for conversions - + Bool_t IsAODanalysis() const { return TestBit(kAODanalysis); } + Bool_t IsESDanalysis() const { return !TestBit(kAODanalysis); } + void SetAODanalysis(Bool_t isAOD = kTRUE) { SetBit(kAODanalysis, isAOD); }; + void SetESDanalysis(Bool_t isESD = kTRUE) { SetBit(kAODanalysis, !isESD); }; - protected: + protected: enum{ kAODanalysis = BIT(14) - }; - AliKFParticle *CreateMotherParticle(AliVTrack *pdaughter, AliVTrack *ndaughter, Int_t pspec, Int_t nspec); - void AddTrackToKFVertex(AliVTrack *track, Int_t species); - + }; + Bool_t IsGammaConv(TObject *v0); Bool_t IsK0s(TObject *v0); Bool_t IsPhi(TObject *v0); - Bool_t IsLambda(TObject *v0); - - Bool_t CutESDtrack(AliESDtrack *track); - Bool_t CutV0(AliESDv0 *v0, Int_t species); + Bool_t IsLambda(TObject *v0); + TList *GetV0pidQA(); - Bool_t LooseRejectK0(AliESDv0 * const v0) const; - Bool_t LooseRejectLambda(AliESDv0 * const v0) const; - Bool_t LooseRejectGamma(AliESDv0 * const v0) const; - - private: + private: class AliHFEV0pidTrackIndex{ - public: - AliHFEV0pidTrackIndex(); - ~AliHFEV0pidTrackIndex(); - void Init(Int_t capacity); - void Add(Int_t index, Int_t species); - Bool_t Find(Int_t index) const; - Bool_t Find(Int_t index, Int_t species) const; - Int_t GetNumberOfElectrons() const { return fNElectrons; }; - Int_t GetNumberOfPionsK0() const { return fNPionsK0; }; - Int_t GetNumberOfPionsL() const { return fNPionsL; }; - Int_t GetNumberOfKaons() const { return fNKaons; }; - Int_t GetNumberOfProtons() const { return fNProtons; }; - void Flush(); - - private: - AliHFEV0pidTrackIndex(const AliHFEV0pidTrackIndex &ref); - AliHFEV0pidTrackIndex &operator=(const AliHFEV0pidTrackIndex &ref); - Int_t fNElectrons; // Number of identified electrons - Int_t fNPionsK0; // Number of identified pions from K0s - Int_t fNPionsL; // Lumber of identified pions from Lambda - Int_t fNKaons; // Number of identified kaons - Int_t fNProtons; // Number of identified protons - Int_t *fIndexElectron; // Indices of identified electrons - Int_t *fIndexPionK0; // Indices of identified pions from K0s - Int_t *fIndexPionL; // Indices of identified pions from Lambda - Int_t *fIndexKaon; // Indices of identified kaons - Int_t *fIndexProton; // Indices of identified protons - }; - - class AliHFELambdaInf{ - public: - AliHFELambdaInf(AliKFParticle *track, AliKFVertex * const primaryVertex); - ~AliHFELambdaInf(); - - Double_t GetInvariantMass() const { return fInvariantMass; }; - Double_t GetChi2NDF() const { return fChi2NDF; }; - Double_t GetDistanceFromPrimaryVertex() const { return fDistVtx; }; - private: - Double_t fInvariantMass; // invariant mass before constraint - Double_t fChi2NDF; // chi2/ndf after constraints - Double_t fDistVtx; // Distance to primary Vertex + public: + AliHFEV0pidTrackIndex(); + ~AliHFEV0pidTrackIndex(); + void Init(Int_t capacity); + void Add(Int_t index, Int_t species); + Bool_t Find(Int_t index) const; + Bool_t Find(Int_t index, Int_t species) const; + Int_t GetNumberOfElectrons() const { return fNElectrons; }; + Int_t GetNumberOfPionsK0() const { return fNPionsK0; }; + Int_t GetNumberOfPionsL() const { return fNPionsL; }; + Int_t GetNumberOfKaons() const { return fNKaons; }; + Int_t GetNumberOfProtons() const { return fNProtons; }; + void Flush(); + + private: + AliHFEV0pidTrackIndex(const AliHFEV0pidTrackIndex &ref); + AliHFEV0pidTrackIndex &operator=(const AliHFEV0pidTrackIndex &ref); + Int_t fNElectrons; // Number of identified electrons + Int_t fNPionsK0; // Number of identified pions from K0s + Int_t fNPionsL; // Lumber of identified pions from Lambda + Int_t fNKaons; // Number of identified kaons + Int_t fNProtons; // Number of identified protons + Int_t *fIndexElectron; // Indices of identified electrons + Int_t *fIndexPionK0; // Indices of identified pions from K0s + Int_t *fIndexPionL; // Indices of identified pions from Lambda + Int_t *fIndexKaon; // Indices of identified kaons + Int_t *fIndexProton; // Indices of identified protons }; - AliHFEV0pid(const AliHFEV0pid &ref); AliHFEV0pid&operator=(const AliHFEV0pid &ref); - + AliVEvent *fInputEvent; // Input Event AliKFVertex *fPrimaryVertex; // Primary Vertex TObjArray *fElectrons; // List of Electron tracks coming from Conversions @@ -156,20 +127,19 @@ class AliHFEV0pid : public TObject{ TObjArray *fPionsL; // List of Pion tracks coming from L TObjArray *fKaons; // List of Kaon tracks from Phi decay TObjArray *fProtons; // List of Proton Tracks coming from Lambdas + + TObjArray *fGammas; // for MC purposes - list of found gammas + TObjArray *fK0s; // for MC purposes - list of found K0s + TObjArray *fLambdas; // for MC purposes - list of found lambdas + TObjArray *fAntiLambdas; // for MC purposes - list of found anti lambdas + AliHFEV0pidTrackIndex *fIndices; // Container for Track indices AliHFEcollection *fQA; // Collection of QA histograms + AliHFEV0cuts *fV0cuts; // separate class for studying and applying the V0 cuts + TList *fOutput; // collection list ClassDef(AliHFEV0pid, 1) // V0 PID Class }; -//____________________________________________________________ -TList *AliHFEV0pid::GetListOfQAhistograms(){ - // - // Get QA histograms - // - if(fQA) - return fQA->GetList(); - return NULL; -} #endif diff --git a/PWG3/hfe/AliHFEV0pidMC.cxx b/PWG3/hfe/AliHFEV0pidMC.cxx index 3f6f6186b59..517890a8f59 100644 --- a/PWG3/hfe/AliHFEV0pidMC.cxx +++ b/PWG3/hfe/AliHFEV0pidMC.cxx @@ -23,10 +23,12 @@ #include "TIterator.h" -#include "AliMCEvent.h" #include "AliVParticle.h" #include "AliESDtrack.h" #include "AliMCParticle.h" +#include "AliMCEvent.h" + +#include "AliHFEcollection.h" #include "AliHFEV0pidMC.h" ClassImp(AliHFEV0pidMC) @@ -34,64 +36,51 @@ ClassImp(AliHFEV0pidMC) //____________________________________________________________ AliHFEV0pidMC::AliHFEV0pidMC(): fMC(0x0) - , fColl(0x0) + , fColl(NULL) + , fV0cuts(NULL) { // // default constructor // + } //____________________________________________________________ AliHFEV0pidMC::~AliHFEV0pidMC(){ // // destructor // - if(fColl) delete fColl; + if (fColl) delete fColl; + //if (fV0cuts) delete fV0cuts; } //____________________________________________________________ void AliHFEV0pidMC::Init(){ // // initialize objects // + fColl = new AliHFEcollection("V0pidMC", "MC based V0 benchmarking"); // QA fColl->CreateTH1F("h_QA_nParticles", "QA on track processing", 10, -0.5, 9.5); // before PID - fColl->CreateTH1F("h_Electron", "all electron candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC)", 100, 0.1, 10); + fColl->CreateTH1F("h_Electron", "all electron candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_PionK0", "all K0 pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_PionL", "all Lambda pion candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_Kaon", "all Kaon candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_Proton", "all Lambda proton candidates (no MC); p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1F("h_mis_Electron", "all NON electron candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates (no MC)", 100, 0.1, 10); - fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates (no MC)", 100, 0.1, 10); + fColl->CreateTH1F("h_mis_Electron", "all NON electron candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_mis_PionK0", "all NON K0 pion candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_mis_PionL", "all NON Lambda pion candidates MC tagged ; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_mis_Kaon", "all NON Kaon candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1F("h_mis_Proton", "all NON Lambda proton candidates MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged", 100, 0.1, 10); - fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged", 100, 0.1, 10); - fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged", 100, 0.1, 10); - fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged", 100, 0.1, 10); - fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged", 100, 0.1, 10); + fColl->CreateTH1Fvector1(5, "h_tag_Electron", "electron candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1Fvector1(5, "h_tag_PionK0", "K0 pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1Fvector1(5, "h_tag_PionL", "Lambda pion candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1Fvector1(5, "h_tag_Kaon", "kaon candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); + fColl->CreateTH1Fvector1(5, "h_tag_Proton", "Lambda proton candidate MC tagged; p (GeV/c); counts", 100, 0.1, 10, 0); - - fColl->BinLogAxis("h_Electron", 0); - fColl->BinLogAxis("h_PionK0", 0); - fColl->BinLogAxis("h_PionL", 0); - fColl->BinLogAxis("h_Kaon", 0); - fColl->BinLogAxis("h_Proton", 0); - fColl->BinLogAxis("h_mis_Electron", 0); - fColl->BinLogAxis("h_mis_PionK0", 0); - fColl->BinLogAxis("h_mis_PionL", 0); - fColl->BinLogAxis("h_mis_Kaon", 0); - fColl->BinLogAxis("h_mis_Proton", 0); -// fColl->BinLogAxis(, 0); -// fColl->BinLogAxis(, 0); -// fColl->BinLogAxis(, 0); -// fColl->BinLogAxis(, 0); -// fColl->BinLogAxis(, 0); - } //____________________________________________________________ Bool_t AliHFEV0pidMC::Process(TObjArray * const particles, Int_t type){ @@ -135,22 +124,22 @@ Bool_t AliHFEV0pidMC::Process(TObjArray * const particles, Int_t type){ continue; } //Int_t pdgM = mcpM->PdgCode(); + // all candidates sprintf(hname, "h_%s", typeName[type]); fColl->Fill(hname, p); Int_t pidD = PDGtoPIDdaughter(pdgD); - // all misidentified candidates + // all misidentified candidates sprintf(hname, "h_mis_%s", typeName[type]); if(typePID[type] != pidD){ fColl->Fill(hname, p); } - sprintf(hname, "h_tag_%s", typeName[type]); - if(pidD >=0){ - fColl->Fill(hname, pidD, p); - } - + // for every particle fill detailed information about the missidentified particles + sprintf(hname, "h_tag_%s", typeName[type]); + Int_t aliPID = PDGtoAliPID(pdgD); + fColl->Fill(hname, aliPID, p); }// .. loop over array @@ -197,3 +186,26 @@ Int_t AliHFEV0pidMC::PDGtoPIDmother(Int_t pdg) const { return -1; } +//____________________________________________________________ +Int_t AliHFEV0pidMC::PDGtoAliPID(Int_t pdg) const { + // + // convert PDG to AliPID + // + + switch (TMath::Abs(pdg)){ + case 11: + return 0; // electron + case 13: + return 1; // muon + case 211: + return 2; // pion + case 321: + return 3; // kaon + case 2212: + return 4; // proton + default: + return -1; + }; + return -1; +} + diff --git a/PWG3/hfe/AliHFEV0pidMC.h b/PWG3/hfe/AliHFEV0pidMC.h index f0c59a82a14..8efffce37dd 100644 --- a/PWG3/hfe/AliHFEV0pidMC.h +++ b/PWG3/hfe/AliHFEV0pidMC.h @@ -25,14 +25,12 @@ #include #endif -#ifndef ALIHFECOLLECTION_H -#include "AliHFEcollection.h" -#endif - class TList; class AliMCEvent; +class AliHFEV0cuts; +class AliHFEcollection; class AliHFEV0pidMC : public TObject { @@ -52,9 +50,12 @@ class AliHFEV0pidMC : public TObject { AliHFEV0pidMC &operator=(const AliHFEV0pidMC &); Int_t PDGtoPIDdaughter(Int_t pdg) const; // convert the PDG code to local PID Int_t PDGtoPIDmother(Int_t pdg) const; // convert the PDG code to local PID + Int_t PDGtoAliPID(Int_t pdg) const; // convert PDG to AliPID AliMCEvent* fMC; // MC event AliHFEcollection* fColl; // Histogram collection + AliHFEV0cuts* fV0cuts; // V0 cut class + ClassDef(AliHFEV0pidMC, 1) // QA class for V0 PID }; //____________________________________________________________ diff --git a/PWG3/hfe/AliHFEcollection.cxx b/PWG3/hfe/AliHFEcollection.cxx index 012cce65df8..ef9a6e0c6a7 100644 --- a/PWG3/hfe/AliHFEcollection.cxx +++ b/PWG3/hfe/AliHFEcollection.cxx @@ -61,7 +61,7 @@ AliHFEcollection::AliHFEcollection(): } //___________________________________________________________________ -AliHFEcollection::AliHFEcollection(char* name, char* title): +AliHFEcollection::AliHFEcollection(const char* name, const char* title): TNamed(name, title) , fList(0x0) { @@ -71,6 +71,7 @@ AliHFEcollection::AliHFEcollection(char* name, char* title): // fList = new THashList(); + fList->SetName(Form("list_%s", name)); if(!fList){ AliError("Initialization of the list failed"); } @@ -130,7 +131,7 @@ AliHFEcollection::~AliHFEcollection(){ AliInfo("DESTRUCTOR"); } //___________________________________________________________________ -Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax){ +Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis){ // // Creates a TH1F histogram for the collection @@ -142,11 +143,14 @@ Bool_t AliHFEcollection::CreateTH1F(const char* name, const char* title, Int_t n } else{ fList->Add(new TH1F(name, title, nBin, nMin, nMax)); + if(logAxis >= 0){ + BinLogAxis(name, logAxis); + } return CheckObject(name); } } //___________________________________________________________________ -Bool_t AliHFEcollection::CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY){ +Bool_t AliHFEcollection::CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY, Int_t logAxis){ // // Creates a TH2F histogram for the collection @@ -157,10 +161,13 @@ Bool_t AliHFEcollection::CreateTH2F(const char* name, const char* title, Int_t n return kFALSE; } fList->Add(new TH2F(name, title, nBinX, nMinX, nMaxX, nBinY, nMinY, nMaxY)); + if(logAxis >= 0){ + BinLogAxis(name, logAxis); + } return CheckObject(name); } //___________________________________________________________________ -Bool_t AliHFEcollection::CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax){ +Bool_t AliHFEcollection::CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis){ // // create a 1 dimensional array of size [X] @@ -180,16 +187,16 @@ Bool_t AliHFEcollection::CreateTH1Fvector1(Int_t X, const char* name, const char hname.Append(Form("%s_[%d]", name, i)); //cout<<" -D: name: "<FindObject(name)->InheritsFrom("TH1")){ (dynamic_cast(fList->FindObject(name)))->Fill(v); @@ -316,6 +324,15 @@ Bool_t AliHFEcollection::Fill(const char* name, Double_t v){ } //___________________________________________________________________ +Bool_t AliHFEcollection::Fill(const char* name, Int_t v){ + + // + // fill function for one TH1 histograms for integer numbers + // + + return Fill(name, v*1.0); +} +//___________________________________________________________________ Bool_t AliHFEcollection::Fill(const char* name, Int_t X, Double_t v){ // @@ -368,8 +385,8 @@ Bool_t AliHFEcollection::Fill(const char* name, Double_t v1, Double_t v2){ // fill function for TH2 objects // - if(!CheckObject(name)){ - AliError(Form("Not possible to return pointer to the object '%s'\n", name)); + if(!CheckObject(name)){ + AliError(Form("Not possible to fill the object '%s', the object does not exist\n", name)); return kFALSE; } @@ -386,7 +403,24 @@ Bool_t AliHFEcollection::Fill(const char* name, Double_t v1, Double_t v2){ return kFALSE; } +//___________________________________________________________________ +Bool_t AliHFEcollection::Fill(const char* name, Double_t* entry, Double_t weight){ + // + // Fill a THnSparse object + // + + if(!CheckObject(name)){ + AliError(Form("Not possible to fill the object '%s', the object does not exist\n", name)); + return kFALSE; + } + + if(fList->FindObject(name)->InheritsFrom("THnSparse")){ + (dynamic_cast(fList->FindObject(name)))->Fill(entry, weight); + return kTRUE; + } + return kFALSE; +} //___________________________________________________________________ Bool_t AliHFEcollection::CheckObject(const char* name){ @@ -461,6 +495,10 @@ Bool_t AliHFEcollection::BinLogAxis(const char* name, Int_t dim){ Int_t bins = axis->GetNbins(); Double_t from = axis->GetXmin(); + if(from <= 0){ + AliError(Form(" Log binning not possible for object '%s'because the '%d' axis starts from '%f\n'", name, dim, from)); + return kFALSE; + } Double_t to = axis->GetXmax(); Double_t *newBins = new Double_t[bins+1]; newBins[0] = from; @@ -469,7 +507,7 @@ Bool_t AliHFEcollection::BinLogAxis(const char* name, Int_t dim){ newBins[i] = factor * newBins[i-1]; } axis->Set(bins, newBins); - delete [] newBins; + delete newBins; return kTRUE; diff --git a/PWG3/hfe/AliHFEcollection.h b/PWG3/hfe/AliHFEcollection.h index 639ee7dc955..3f673b34637 100644 --- a/PWG3/hfe/AliHFEcollection.h +++ b/PWG3/hfe/AliHFEcollection.h @@ -41,7 +41,7 @@ class AliHFEcollection : public TNamed{ public: AliHFEcollection(); - AliHFEcollection(char* name, char* title); + AliHFEcollection(const char* name, const char* title); AliHFEcollection(const AliHFEcollection &c); AliHFEcollection &operator=(const AliHFEcollection &c); virtual ~AliHFEcollection(); @@ -50,13 +50,13 @@ class AliHFEcollection : public TNamed{ virtual void Browse(TBrowser *b); // Set & Create functions - Bool_t CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax); + Bool_t CreateTH1F(const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis = -1); - Bool_t CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY); + Bool_t CreateTH2F(const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY, Int_t logAxis = -1); - Bool_t CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax); - Bool_t CreateTH1Fvector2(Int_t X, Int_t Y, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax); - Bool_t CreateTH2Fvector1(Int_t X, const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY); + Bool_t CreateTH1Fvector1(Int_t X, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis = -1); + Bool_t CreateTH1Fvector2(Int_t X, Int_t Y, const char* name, const char* title, Int_t nBin, Float_t nMin, Float_t nMax, Int_t logAxis = -1); + Bool_t CreateTH2Fvector1(Int_t X, const char* name, const char* title, Int_t nBinX, Float_t nMinX, Float_t nMaxX, Int_t nBinY, Float_t nMinY, Float_t nMaxY, Int_t logAxis = -1); Bool_t CreateProfile(const char* name, const char* title, Int_t nbins, Double_t xmin, Double_t xmax); Bool_t CreateTHnSparse(const char* name, const char* title, Int_t dim, Int_t* nbins, Double_t* xmin, Double_t* xmax); @@ -72,10 +72,12 @@ class AliHFEcollection : public TNamed{ // Fill functions Bool_t Fill(const char* name, Double_t v); + Bool_t Fill(const char* name, Int_t v); Bool_t Fill(const char* name, Int_t X, Double_t v); Bool_t Fill(const char* name, Int_t X, Int_t Y, Double_t v); Bool_t Fill(const char* name, Double_t v1, Double_t v2); Bool_t Fill(const char* name, Int_t X, Double_t v1, Double_t v2); + Bool_t Fill(const char* name, Double_t* entry, Double_t weight = 1); private: Bool_t CheckObject(const char* name); void Copy(TObject &ref) const; diff --git a/PWG3/hfe/AliHFEcuts.cxx b/PWG3/hfe/AliHFEcuts.cxx index 62688965083..602b9d2b095 100644 --- a/PWG3/hfe/AliHFEcuts.cxx +++ b/PWG3/hfe/AliHFEcuts.cxx @@ -139,6 +139,7 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){ // Initializes the cut objects from the correction framework // Publishes the cuts to the correction framework manager // + AliDebug(2, "Called"); if(IsInDebugMode()){ fHistQA = new TList; fHistQA->SetName("CutQAhistograms"); @@ -182,6 +183,7 @@ void AliHFEcuts::Initialize(AliCFManager *cfm){ //__________________________________________________________________ void AliHFEcuts::Initialize(){ // Call all the setters for the cuts + AliDebug(2, "Called\n"); SetParticleGenCutList(); SetAcceptanceCutList(); SetRecKineITSTPCCutList(); @@ -196,20 +198,20 @@ void AliHFEcuts::SetEventCutList(Int_t istep){ // // Cuts for Event Selection // + AliDebug(2, "Called\n"); TObjArray *arr = new TObjArray; if(istep == kEventStepGenerated){ - AliCFEventGenCuts *evGenCuts = new AliCFEventGenCuts("fCutsEvGen", "Event Generated cuts"); + AliCFEventGenCuts *evGenCuts = new AliCFEventGenCuts((Char_t *)"fCutsEvGen", (Char_t *)"Event Generated cuts"); evGenCuts->SetNTracksCut(1); evGenCuts->SetRequireVtxCuts(kTRUE); evGenCuts->SetVertexXCut(-1, 1); evGenCuts->SetVertexYCut(-1, 1); - evGenCuts->SetVertexZCut(-30, 30); + evGenCuts->SetVertexZCut(-10, 10); arr->SetName("fEvGenCuts"); arr->AddLast(evGenCuts); } else { - AliCFEventRecCuts *evRecCuts = new AliCFEventRecCuts("fCutsEvRec", "Event Reconstructed cuts"); - evRecCuts->SetUseSPDVertex(); + AliCFEventRecCuts *evRecCuts = new AliCFEventRecCuts((Char_t *)"fCutsEvRec", (Char_t *)"Event Reconstructed cuts"); evRecCuts->SetNTracksCut(1); evRecCuts->SetRequireVtxCuts(kTRUE); evRecCuts->SetVertexXCut(-1, 1); @@ -231,29 +233,38 @@ void AliHFEcuts::SetParticleGenCutList(){ // Particle Species: Electrons // Eta: < 0.9 (TRD-TOF acceptance) // + + TObjArray *mcCuts = new TObjArray; + mcCuts->SetName("fPartGenCuts"); + + // + AliDebug(2, "Called\n"); AliCFParticleGenCuts *genCuts = new AliCFParticleGenCuts("fCutsGenMC", "Particle Generation Cuts"); genCuts->SetRequireIsCharged(); - if(IsRequirePrimary()) genCuts->SetRequireIsPrimary(); + if(IsRequirePrimary()) { + genCuts->SetRequireIsPrimary(); + } if(IsRequireProdVertex()){ + AliDebug(3, Form("Vertex Range: fProdVtx[0] %f, fProdVtx[1] %f, fProdVtx[2] %f, fProdVtx[3] %f", fProdVtx[0], fProdVtx[1], fProdVtx[2], fProdVtx[3])); genCuts->SetProdVtxRangeX(fProdVtx[0], fProdVtx[1]); genCuts->SetProdVtxRangeY(fProdVtx[2], fProdVtx[3]); genCuts->SetProdVtxRange2D(kTRUE); // Use ellipse } genCuts->SetRequirePdgCode(11, kTRUE); - - AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts("fCutsKineMC","MC Kine Cuts"); - kineMCcuts->SetPtRange(fPtRange[0], fPtRange[1]); - kineMCcuts->SetEtaRange(-0.8, 0.8); + if(IsInDebugMode()) genCuts->SetQAOn(fHistQA); - if(IsInDebugMode()){ - genCuts->SetQAOn(fHistQA); - kineMCcuts->SetQAOn(fHistQA); - } - - TObjArray *mcCuts = new TObjArray; - mcCuts->SetName("fPartGenCuts"); + // Add mcCuts->AddLast(genCuts); - mcCuts->AddLast(kineMCcuts); + + // + if(IsRequireKineMCCuts()) { + AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineMC", (Char_t *)"MC Kine Cuts"); + kineMCcuts->SetPtRange(fPtRange[0], fPtRange[1]); + kineMCcuts->SetEtaRange(-0.8, 0.8); + if(IsInDebugMode()) kineMCcuts->SetQAOn(fHistQA); + mcCuts->AddLast(kineMCcuts); + } + fCutList->AddLast(mcCuts); } @@ -267,6 +278,7 @@ void AliHFEcuts::SetAcceptanceCutList(){ // TRD [2*nTracklets] // TOF [0] // + AliDebug(2, "Called\n"); AliCFAcceptanceCuts *accCuts = new AliCFAcceptanceCuts("fCutsAccMC", "MC Acceptance Cuts"); accCuts->SetMinNHitITS(3); accCuts->SetMinNHitTPC(2); @@ -301,7 +313,9 @@ void AliHFEcuts::SetRecKineITSTPCCutList(){ // Momentum Range: 100MeV - 20GeV // Eta: < 0.9 (TRD-TOF acceptance) // - AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts("fCutsQualityRec","REC Track Quality Cuts"); + AliDebug(2, "Called\n"); + AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts((Char_t *)"fCutsQualityRec", (Char_t *)"REC Track Quality Cuts"); + trackQuality->SetMinNClusterITS(4); trackQuality->SetMinNClusterTPC(fMinClustersTPC); trackQuality->SetMaxChi2PerClusterTPC(fMaxChi2clusterTPC); trackQuality->SetStatus(AliESDtrack::kTPCrefit | AliESDtrack::kITSrefit); @@ -311,7 +325,7 @@ void AliHFEcuts::SetRecKineITSTPCCutList(){ if(fMinClusterRatioTPC > 0.) hfecuts->SetClusterRatioTPC(fMinClusterRatioTPC); hfecuts->SetDebugLevel(fDebugLevel); - AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts("fCutsKineRec", "REC Kine Cuts"); + AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineRec", (Char_t *)"REC Kine Cuts"); kineCuts->SetPtRange(fPtRange[0], fPtRange[1]); kineCuts->SetEtaRange(-0.8, 0.8); @@ -338,7 +352,8 @@ void AliHFEcuts::SetRecPrimaryCutList(){ // Z: 10. cm // No Kink daughters // - AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts("fCutsPrimaryCuts", "REC Primary Cuts"); + AliDebug(2, "Called\n"); + AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts((Char_t *)"fCutsPrimaryCuts", (Char_t *)"REC Primary Cuts"); if(IsRequireDCAToVertex()){ //primaryCut->SetDCAToVertex2D(kTRUE); primaryCut->SetMaxDCAToVertexXY(fDCAtoVtx[0]); @@ -362,6 +377,7 @@ void AliHFEcuts::SetHFElectronITSCuts(){ // // Special Cuts introduced by the HFElectron Group: ITS // + AliDebug(2, "Called\n"); AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupPixels","Extra cuts from the HFE group"); if(IsRequireITSpixel()){ hfecuts->SetRequireITSpixel(AliHFEextraCuts::ITSPixel_t(fCutITSPixel)); @@ -382,6 +398,7 @@ void AliHFEcuts::SetHFElectronTRDCuts(){ // // Special Cuts introduced by the HFElectron Group: TRD // + AliDebug(2, "Called\n"); AliHFEextraCuts *hfecuts = new AliHFEextraCuts("fCutsHFElectronGroupTRD","Extra cuts from the HFE group"); if(fMinTrackletsTRD > 0.) hfecuts->SetMinTrackletsTRD(fMinTrackletsTRD); if(IsInDebugMode()) hfecuts->SetQAOn(fHistQA); @@ -406,6 +423,7 @@ Bool_t AliHFEcuts::CheckParticleCuts(CutStep_t step, TObject *o){ // // Checks the cuts without using the correction framework manager // + AliDebug(2, "Called\n"); TString stepnames[kNcutStepsTrack] = {"fPartGenCuts", "fPartAccCuts", "fPartRecCuts", "fPartPrimCuts", "fPartHFECuts"}; TObjArray *cuts = dynamic_cast(fCutList->FindObject(stepnames[step].Data())); if(!cuts) return kTRUE; diff --git a/PWG3/hfe/AliHFEcuts.h b/PWG3/hfe/AliHFEcuts.h index dc1568b32dc..19814240647 100644 --- a/PWG3/hfe/AliHFEcuts.h +++ b/PWG3/hfe/AliHFEcuts.h @@ -85,6 +85,7 @@ class AliHFEcuts : public TObject{ Bool_t IsRequireProdVertex() const { return TESTBIT(fRequirements, kProductionVertex); }; Bool_t IsRequireSigmaToVertex() const { return TESTBIT(fRequirements, kSigmaToVertex); }; Bool_t IsRequireDCAToVertex() const {return TESTBIT(fRequirements, kDCAToVertex); }; + Bool_t IsRequireKineMCCuts() const {return TESTBIT(fRequirements, kKineMCCuts); }; // Setters inline void SetCutITSpixel(UChar_t cut); @@ -106,6 +107,7 @@ class AliHFEcuts : public TObject{ void SetRequireITSPixel() { SETBIT(fRequirements, kITSPixel); } void SetRequireProdVertex() { SETBIT(fRequirements, kProductionVertex); }; void SetRequireSigmaToVertex() { SETBIT(fRequirements, kSigmaToVertex); }; + void SetRequireKineMCCuts() { SETBIT(fRequirements, kKineMCCuts); }; void SetDebugLevel(Int_t level) { fDebugLevel = level; }; Int_t GetDebugLevel() const { return fDebugLevel; }; @@ -121,7 +123,8 @@ class AliHFEcuts : public TObject{ kSigmaToVertex = 2, kDCAToVertex = 3, kITSPixel = 4, - kMaxImpactParam = 5 + kMaxImpactParam = 5, + kKineMCCuts = 6 } Require_t; void SetParticleGenCutList(); void SetAcceptanceCutList(); @@ -186,14 +189,14 @@ void AliHFEcuts::CreateStandardCuts(){ // Standard Cuts defined by the HFE Group // SetRequireProdVertex(); - fProdVtx[0] = -3; + fProdVtx[0] = 0; fProdVtx[1] = 3; - fProdVtx[2] = -3; + fProdVtx[2] = 0; fProdVtx[3] = 3; - SetRequireDCAToVertex(); - fDCAtoVtx[0] = 2.; - fDCAtoVtx[1] = 10.; - fMinClustersTPC = 50; + //SetRequireDCAToVertex(); + //fDCAtoVtx[0] = 0.5; + //fDCAtoVtx[1] = 1.5; + fMinClustersTPC = 80; fMinTrackletsTRD = 0; SetRequireITSPixel(); fCutITSPixel = AliHFEextraCuts::kFirst; @@ -201,5 +204,6 @@ void AliHFEcuts::CreateStandardCuts(){ fMinClusterRatioTPC = 0.6; fPtRange[0] = 0.1; fPtRange[1] = 20.; + SetRequireKineMCCuts(); } #endif diff --git a/PWG3/hfe/AliHFEdca.cxx b/PWG3/hfe/AliHFEdca.cxx index 040ed6fc138..02b38d0157e 100644 --- a/PWG3/hfe/AliHFEdca.cxx +++ b/PWG3/hfe/AliHFEdca.cxx @@ -29,113 +29,209 @@ #include "AliESDtrack.h" #include "AliESDEvent.h" #include "AliMCEvent.h" +#include "AliMCVertex.h" + +#include "AliKFParticle.h" +#include "AliKFVertex.h" + +#include "AliESDVertex.h" + +#include "AliPID.h" #include "AliHFEdca.h" + ClassImp(AliHFEdca) //________________________________________________________________________ const Char_t* AliHFEdca::fgkParticles[12] = { - // particles name - "electron", "muonMinus","pionMinus", "kaonMinus", "protonMinus", - "positron", "muonPlus", "pionPlus", "kaonPlus", "protonPlus", - "allNegative", "allPositive" + // particles name + "electron", "muonMinus","pionMinus", "kaonMinus", "protonMinus", + "positron", "muonPlus", "pionPlus", "kaonPlus", "protonPlus", + "allNegative", "allPositive" }; + +const Int_t AliHFEdca::fgkPdgParticle[10] = { +// 11, 13, -211, -233, -2122, +// -11, -13, 211, 233, 2122}; + kPDGelectron, kPDGmuon, -kPDGpion, -kPDGkaon, -kPDGproton, + -kPDGelectron, -kPDGmuon, kPDGpion, kPDGkaon, kPDGproton}; + //________________________________________________________________________ const Int_t AliHFEdca::fgkColorPart[12] = { - // colors assigned to particles - kRed, kBlue, kGreen+2, kYellow+2, kMagenta, - kRed+2, kBlue+2, kGreen+4, kYellow+4, kMagenta+2, - kBlack, kGray+1 + // colors assigned to particles + kRed, kBlue, kGreen+2, kYellow+2, kMagenta, + kRed+2, kBlue+2, kGreen+4, kYellow+4, kMagenta+2, + kBlack, kGray+1 }; - - //________________________________________________________________________ -const Float_t AliHFEdca::fgkPtIntv[44] = { - // define pT bins - 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, - 1.0, 1.2, 1.4, 1.6, 1.8, 2.0, 2.2, 2.4, 2.6, 2.8, - 3.0, 3.3, 3.6, 3.9, 4.2, 4.5, 5.0, 5.5, 6.0, 6.5, - 7.0, 8.0, 9.0, 10., 11., 12., 13., 14., 15., 16., - 17., 18., 19., 20.}; +const Float_t AliHFEdca::fgkPtIntv[51] = { + // define pT bins + 0.10, 0.15, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, + 0.60, 0.70, 0.80, 0.90, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, + 1.70, 1.90, 2.10, 2.30, 2.50, 2.70, 2.90, 3.10, 3.30, 3.50, + 3.80, 4.10, 4.40, 4.70, 5.00, 5.30, 5.60, 5.90, 6.20, 6.50, + 7.00, 7.50, 8.00, 9.00, 10.0, 11.0, 12.0, 13.0, 15.0, 18.0, + 20.00}; //________________________________________________________________________ const Char_t *AliHFEdca::fgkDcaVar[2] = { - "deltaDcaXY", "deltaDcaZ"}; + "DcaXY", "DcaZ"}; //________________________________________________________________________ const Char_t *AliHFEdca::fgkDcaVarTitle[2] ={ - ";residual #Delta(d_{xy}) [#mum];couts", ";residual #Delta(d_{z}) [#mum];counts"}; + ";dca_{xy} [#mum];counts", ";dca_{z} [#mum];counts"}; + +//________________________________________________________________________ +const Char_t *AliHFEdca::fgkVertexVar[3] = { + "VertexX", "VertexY", "VertexZ"}; + +//________________________________________________________________________ +const Char_t *AliHFEdca::fgkVertexVarTitle[3] ={ + ";vertex_{x} [#mum];counts", ";vertex_{y} [#mum];counts", ";vertex_{z} [#mum];counts"}; + +//________________________________________________________________________ +const Char_t *AliHFEdca::fgkResDcaVar[2] = { + "deltaDcaXY", "deltaDcaZ"}; +//________________________________________________________________________ +const Char_t *AliHFEdca::fgkResDcaVarTitle[2] ={ + ";residual #Delta(d_{xy}) [#mum];counts", ";residual #Delta(d_{z}) [#mum];counts"}; //________________________________________________________________________ const Char_t *AliHFEdca::fgkPullDcaVar[2] = { - "pullDcaXY", "pullDcaZ" + "pullDcaXY", "pullDcaZ" }; //________________________________________________________________________ const Char_t *AliHFEdca::fgkPullDcaVarTitle[2] = { - ";(dca_{xy}^{ESD}-dca_{xy}^{MC})/(#sigma_{track}#oplus#sigma_{Vxy});counts", - ";(dca_{z}^{ESD}-dca_{z}^{MC})/(#sigma_{track}#oplus#sigma_{Vz}); counts" + ";residual dca_{xy}/(error dca_{xy});counts", + ";residual dca_{z}/(error dca_{z});counts" }; //________________________________________________________________________ -AliHFEdca::AliHFEdca(): - fResidualList(0x0) - , fPullList(0x0) +const Char_t *AliHFEdca::fgkPullDataDcaVarTitle[2] = { + ";dca_{xy}^{data}/error dca_{xy};counts", + ";dca_{z}^{data}/error dca_{z};counts" +}; +//________________________________________________________________________ +AliHFEdca::AliHFEdca(): + TObject(), + fStat(NULL) { - // default constructor - + // default constructor + } //________________________________________________________________________ -AliHFEdca::AliHFEdca(const AliHFEdca &dca): - TObject(dca) - , fResidualList(0x0) - , fPullList(0x0) - +AliHFEdca::AliHFEdca(const AliHFEdca &ref): + TObject(ref), + fStat(ref.fStat) { - // copy constructor + // copy constructor } //_______________________________________________________________________________________________ -AliHFEdca& -AliHFEdca::operator=(const AliHFEdca &) +AliHFEdca&AliHFEdca::operator=(const AliHFEdca &ref) { - // - // Assignment operator - // - - Printf("Not yet implemented."); - return *this; + // + // Assignment operator + // + + + if(this == &ref) return *this; + TObject::operator=(ref); + return *this; } //________________________________________________________________________ AliHFEdca::~AliHFEdca() { - // default destructor + // default destructor + + for(Int_t j=0; jSetLineColor((const int)fgkColorPart[j]); + if(j<(kNParticles-2)){ + fHistEPDcaXYRes[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, -maxXYBin, maxXYBin); + fHistEPDcaXYRes[j][i]->SetLineColor((const int)fgkColorPart[j]);} } if(k==1){ fHistDcaZRes[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxZBin, maxZBin); fHistDcaZRes[j][i]->SetLineColor((const int)fgkColorPart[j]); + if(j<(kNParticles-2)){ + fHistEPDcaZRes[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, -maxZBin, maxZBin); + fHistEPDcaZRes[j][i]->SetLineColor((const int)fgkColorPart[j]); } } - } // 43 pt bins - } //12 nparticles - } // 2 dca var - - // TList *fResidualList = 0; - residualList->SetOwner(); - residualList->SetName("residual"); - for(Int_t iPart=0; iPartAdd(fHistDcaXYRes[iPart][iPtBin]); - residualList->Add(fHistDcaZRes[iPart][iPtBin]); - } // loop over pt bins - } // loop over particles (pos, neg) - - - + } // 50 pt bins + } //12 nparticles + } // 2 dca var + + // TList *fResidualList = 0; + residualList->SetOwner(); + residualList->SetName("residual"); + for(Int_t iPart=0; iPartAdd(fHistDcaXYRes[iPart][iPtBin]); + residualList->Add(fHistDcaZRes[iPart][iPtBin]); + if(iPart<(kNParticles-2)){ + residualList->Add(fHistEPDcaXYRes[iPart][iPtBin]); + residualList->Add(fHistEPDcaZRes[iPart][iPtBin]); + } + } // loop over pt bins + } // loop over particles (pos, neg) + + } //________________________________________________________________________ void AliHFEdca::CreateHistogramsPull(TList *pullList){ - // define histogram - // 2. pull - - const Int_t nBins = 1000; - const Float_t maxXYBin = 20.; - const Float_t maxZBin = 20.; - - - // for pull ----------------------------------------------------------------------- - fHistDcaXYPull[kNParticles][kNPtBins]=0x0; - fHistDcaZPull[kNParticles][kNPtBins]=0x0; - - - for(Int_t k=0; kSetLineColor((const int)fgkColorPart[j]); + if(j<(kNParticles-2)) { + fHistEPDcaXYPull[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, 1-maxXYBin, 1+maxXYBin); + fHistEPDcaXYPull[j][i]->SetLineColor((const int)fgkColorPart[j]);} } if(k==1){ fHistDcaZPull[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin); fHistDcaZPull[j][i]->SetLineColor((const int)fgkColorPart[j]); + if(j<(kNParticles-2)) { + fHistEPDcaZPull[j][i] = new TH1F((const char*)histEPName, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin); + fHistEPDcaZPull[j][i]->SetLineColor((const int)fgkColorPart[j]);} + } + } // 50 pt bins + } //6 nparticles + } // 2 dca var + + // TList *fPullList = 0; + pullList->SetOwner(); + pullList->SetName("pull"); + for(Int_t iPart=0; iPartAdd(fHistDcaXYPull[iPart][iPtBin]); + pullList->Add(fHistDcaZPull[iPart][iPtBin]); + if(iPart<(kNParticles-2)){ + pullList->Add(fHistDcaXYPull[iPart][iPtBin]); + pullList->Add(fHistDcaZPull[iPart][iPtBin]); } + } // loop over pt bins + } // loop over particles (pos, neg) + +} + + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsDca(TList *dcaList){ + // + // define histograms: MC dca + // + + // statistics + fStat = 0x0; + fStat = new TH1I("fStatistics", "allStatistics;ID;counts", 7, -3.5, 3.5); + fStat->SetMarkerStyle(20); + fStat->SetMarkerColor(3); + fStat->SetMarkerSize(1); + + // for dca + fHistDcaXY[kNParticles][kNPtBins]=0x0; + fHistDcaZ[kNParticles][kNPtBins]=0x0; + + fHistEPDcaXY[kNParticles-2][kNPtBins]=0x0; + fHistEPDcaZ[kNParticles-2][kNPtBins]=0x0; + + const Int_t nBins = 1000; + const Float_t maxXYBin = 1000.; + const Float_t maxZBin = 1000.; + + + for(Int_t k=0; kSetLineColor((const int)fgkColorPart[j]); + + if(j<(kNParticles-2)){ + fHistEPDcaXY[j][i] = new TH1F((const char*)histNameEP, (const char*)histTitle, nBins, -maxXYBin, maxXYBin); + fHistEPDcaXY[j][i]->SetLineColor((const int)fgkColorPart[j]);} + } + if(k==1){ + fHistDcaZ[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxZBin, maxZBin); + fHistDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]); + if(j<(kNParticles-2)){ + fHistEPDcaZ[j][i] = new TH1F((const char*)histNameEP, (const char*)histTitle, nBins, -maxZBin, maxZBin); + fHistEPDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]);} + } + } // 50 pt bins + } //12 nparticles + } // 2 dca var + + // TList *fDcaList = 0; + dcaList->SetOwner(); + dcaList->SetName("mcDcaDistr"); + for(Int_t iPart=0; iPartAdd(fHistDcaXY[iPart][iPtBin]); + dcaList->Add(fHistDcaZ[iPart][iPtBin]); + if(iPart<(kNParticles-2)) { + dcaList->Add(fHistEPDcaXY[iPart][iPtBin]); + dcaList->Add(fHistEPDcaZ[iPart][iPtBin]); } + } // loop over pt bins + } // loop over particles (pos, neg) + + dcaList->Add(fStat); + +} + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsKfDca(TList *kfDcaList){ + // + // define histograms: MC dca + // + + // statistics + fStat = 0x0; + fStat = new TH1I("fStatistics", "allStatistics;ID;counts", 7, -3.5, 3.5); + fStat->SetMarkerStyle(20); + fStat->SetMarkerColor(3); + fStat->SetMarkerSize(1); + + // for kf dca + fHistKFDcaXY[kNParticles][kNPtBins]=0x0; + fHistKFDcaZ[kNParticles][kNPtBins]=0x0; + + const Int_t nBins = 1000; + const Float_t maxXYBin = 1000.; + const Float_t maxZBin = 1000.; + + + for(Int_t k=0; kSetLineColor((const int)fgkColorPart[j]); + } + if(k==1){ + fHistKFDcaZ[j][i] = new TH1F((const char*)histNameKF, (const char*)histTitle, nBins, -maxZBin, maxZBin); + fHistKFDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]); + } + } // 50 pt bins + } //12 nparticles + } // 2 dca var + + kfDcaList->SetOwner(); + kfDcaList->SetName("mcKfDcaDistr"); + for(Int_t iPart=0; iPartAdd(fHistKFDcaXY[iPart][iPtBin]); + kfDcaList->Add(fHistKFDcaZ[iPart][iPtBin]); + } // loop over pt bins + } // loop over particles (pos, neg) + + kfDcaList->Add(fStat); + +} + + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsDataDca(TList *dataDcaList){ + // + // define histograms: real Data + // + + // for dca + fHistDataDcaXY[kNParticles][kNPtBins]=0x0; + fHistDataDcaZ[kNParticles][kNPtBins]=0x0; + + fHistDataWoDcaXY[kNParticles][kNPtBins]=0x0; + fHistDataWoDcaZ[kNParticles][kNPtBins]=0x0; + + const Int_t nBins = 1000; + const Float_t maxXYBin = 1000.; + const Float_t maxZBin = 1000.; + + for(Int_t k=0; kSetLineColor((const int)fgkColorPart[j]); + + fHistDataWoDcaXY[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, -maxXYBin, maxXYBin); + fHistDataWoDcaXY[j][i]->SetLineColor((const int)fgkColorPart[j]); + } + if(k==1){ + fHistDataDcaZ[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, -maxZBin, maxZBin); + fHistDataDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]); + + fHistDataWoDcaZ[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, -maxZBin, maxZBin); + fHistDataWoDcaZ[j][i]->SetLineColor((const int)fgkColorPart[j]); + } + } // 50 pt bins + } //12 nparticles + } // 2 dca var + + // TList *fDcaList = 0; + dataDcaList->SetOwner(); + dataDcaList->SetName("dataDcaDistr"); + for(Int_t iPart=0; iPartAdd(fHistDataDcaXY[iPart][iPtBin]); + dataDcaList->Add(fHistDataDcaZ[iPart][iPtBin]); + + dataDcaList->Add(fHistDataWoDcaXY[iPart][iPtBin]); + dataDcaList->Add(fHistDataWoDcaZ[iPart][iPtBin]); + } // loop over pt bins + } // loop over particles (pos, neg) + + +} + + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsDataPull(TList *dataPullList){ + // define histogram + // 2. pull + + const Int_t nBins = 1000; + const Float_t maxXYBin = 20.; + const Float_t maxZBin = 20.; + + // for pull ----------------------------------------------------------------------- + fHistDataDcaXYPull[kNParticles][kNPtBins]=0x0; + fHistDataDcaZPull[kNParticles][kNPtBins]=0x0; + + fHistDataWoDcaXYPull[kNParticles][kNPtBins]=0x0; + fHistDataWoDcaZPull[kNParticles][kNPtBins]=0x0; + + + for(Int_t k=0; kSetLineColor((const int)fgkColorPart[j]); + + fHistDataWoDcaXYPull[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, 1-maxXYBin, 1+maxXYBin); + fHistDataWoDcaXYPull[j][i]->SetLineColor((const int)fgkColorPart[j]); + } + if(k==1){ + fHistDataDcaZPull[j][i] = new TH1F((const char*)histName, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin); + fHistDataDcaZPull[j][i]->SetLineColor((const int)fgkColorPart[j]); + + fHistDataWoDcaZPull[j][i] = new TH1F((const char*)histNameWo, (const char*)histTitle, nBins, 1-maxZBin, 1+maxZBin); + fHistDataWoDcaZPull[j][i]->SetLineColor((const int)fgkColorPart[j]); } - } // 43 pt bins - } //6 nparticles - } // 2 dca var - - // TList *fPullList = 0; - pullList->SetOwner(); - pullList->SetName("pull"); - for(Int_t iPart=0; iPartAdd(fHistDcaXYPull[iPart][iPtBin]); - pullList->Add(fHistDcaZPull[iPart][iPtBin]); - } // loop over pt bins - } // loop over particles (pos, neg) - - + } // 50 pt bins + } //6 nparticles + } // 2 dca var + + // TList *fDataPullList = 0; + dataPullList->SetOwner(); + dataPullList->SetName("dataPull"); + for(Int_t iPart=0; iPartAdd(fHistDataDcaXYPull[iPart][iPtBin]); + dataPullList->Add(fHistDataDcaZPull[iPart][iPtBin]); + + dataPullList->Add(fHistDataWoDcaXYPull[iPart][iPtBin]); + dataPullList->Add(fHistDataWoDcaZPull[iPart][iPtBin]); + } // loop over pt bins + } // loop over particles (pos, neg) + +} + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsVertex(TList *vertexList){ + // + // define histograms: vertex + // + // for vertex + + fHistMCvertex[kNVertexVar]=0x0; + fHistESDvertex[kNVertexVar]=0x0; + + const Int_t nBins = 1000; + const Float_t minXBin = -0.2e4; + const Float_t maxXBin = 0.2e4; + const Float_t minYBin = -0.5e4; + const Float_t maxYBin = 0.5e4; + const Float_t minZBin = -1.5e5; + const Float_t maxZBin = 1.5e5; + + const Float_t minBin[kNVertexVar] = {minXBin, minYBin, minZBin}; + const Float_t maxBin[kNVertexVar] = {maxXBin, maxYBin, maxZBin}; + + for(Int_t k=0; kSetLineColor(k+2); + + fHistESDvertex[k] = new TH1F((const char*)histNameESD, (const char*)histTitle, nBins, minBin[k], maxBin[k]); + fHistESDvertex[k]->SetLineColor(k+2); + } // 3 vertex var + + vertexList->SetOwner(); + vertexList->SetName("vertexDistr"); + + for(Int_t k=0; kAdd(fHistMCvertex[k]); + vertexList->Add(fHistESDvertex[k]); + } + +} + + + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsDataVertex(TList *dataVertexList){ + // + // define histograms: vertex + // + // for data vertex + + fHistDatavertex[kNVertexVar]=0x0; + + const Int_t nBins = 1000; + const Float_t minXBin = -0.2e4; + const Float_t maxXBin = 0.2e4; + const Float_t minYBin = -0.5e4; + const Float_t maxYBin = 0.5e4; + const Float_t minZBin = -1.5e5; + const Float_t maxZBin = 1.5e5; + + const Float_t minBin[kNVertexVar] = {minXBin, minYBin, minZBin}; + const Float_t maxBin[kNVertexVar] = {maxXBin, maxYBin, maxZBin}; + + for(Int_t k=0; kSetLineColor(k+2); + } // 3 vertex var + + // TList *fVDaraVertexList = 0; + dataVertexList->SetOwner(); + dataVertexList->SetName("dataVertexDistr"); + + for(Int_t k=0; kAdd(fHistDatavertex[k]); + } + +} + +//_______________________________________________________________________________________________ +void AliHFEdca::CreateHistogramsPid(TList *mcPidList){ + // + // define histograms which fills combined PID + // + + const Char_t *mcOResd[2]={"mcPt", "esdPt"}; + + for(Int_t iPart=0; iPartSetOwner(); + mcPidList->SetName("combinedPid"); + + for(Int_t iPart=0; iPartAdd(fHistMcPid[iPart]); + mcPidList->Add(fHistEsdPid[iPart]); + } +} + + +//_______________________________________________________________________________________________ +void AliHFEdca::CreateHistogramsDataPid(TList *pidList){ + // + // define histograms which fills combined PID: data + // + + + + for(Int_t iPart=0; iPartSetOwner(); + pidList->SetName("dataCombinedPid"); + + for(Int_t iPart=0; iPartAdd(fHistDataEsdPid[iPart]); + + +} + + + +//_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent) +{ + // the kDca plugin + // MC vertex + AliMCVertex *mcPrimVtx = (AliMCVertex *)mcEvent->GetPrimaryVertex(); + Double_t mcPrimV[3]; + mcPrimV[0] = mcPrimVtx->GetX(); + mcPrimV[1] = mcPrimVtx->GetY(); + mcPrimV[2] = mcPrimVtx->GetZ(); + + Double_t mcVtxXY = TMath::Abs(mcPrimV[0]*mcPrimV[0] + mcPrimV[1]*mcPrimV[1]); + +// filling historgams track by track +// obtaining reconstructed dca ------------------------------------------------------------------ + + Float_t esdpx = track->Px(); + Float_t esdpy = track->Py(); + Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); + +// obtaining errors of dca ------------------------------------------------------------------ + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Double_t primV[3]; + primV[0] = primVtx->GetXv(); + primV[1] = primVtx->GetYv(); + primV[2] = primVtx->GetZv(); + + Float_t magneticField = 0; // initialized as 5kG + magneticField = esdEvent->GetMagneticField(); // in kG + + Double_t beampiperadius=3.; + Double_t dz[2]; // error of dca in cm + Double_t covardz[3]; + + if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection + track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz); + AliMCParticle *mctrack = dynamic_cast(mcEvent->GetTrack(TMath::Abs(track->GetLabel()))); + TParticle *part = mctrack->Particle(); + + Float_t vx = part->Vx(); // in cm + Float_t vy = part->Vy(); // in cm + Float_t vz = part->Vz(); // in cm + + Float_t vxy = TMath::Sqrt(vx*vx+vy*vy); + + Float_t mcpx = part->Px(); + Float_t mcpy = part->Py(); + Float_t mcpt = TMath::Sqrt(mcpx*mcpx+mcpy*mcpy); + + Int_t pdg = part->GetPdgCode(); + Int_t esdPid = GetCombinedPid(track); + + Int_t charge = 1; + if(pdg==kPDGelectron || pdg==kPDGmuon + || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton) charge = -1; + + // calculate mcDca ------------------------------------------------------------------ + const Float_t conv[2] = {1.783/1.6, 2.99792458}; + Float_t radiusMc = mcpt/(TMath::Abs(magneticField)/10.)*conv[0]*conv[1]; // pt in GeV/c, magnetic field in Tesla, radius in meter + + Float_t nx = esdpx/mcpt; + Float_t ny = esdpy/mcpt; + + Float_t radius; + radius = TMath::Abs(radiusMc); + + Double_t dxy = vxy - mcVtxXY; // in cm + Double_t dvx = vx - mcPrimV[0]; // in cm + Double_t dvy = vy - mcPrimV[1]; // in cm + + Float_t mcDcaXY = (radius - TMath::Sqrt(dxy*dxy/100./100. + radius*radius + 2*radius*charge*(dvx*ny-dvy*nx)/100.)) ; // in meters + + Double_t mcDca[2] = {mcDcaXY*100, vz}; // in cm + Double_t residual[2] = {0, 0}; + Double_t pull[2] = {0, 0}; + Double_t error[2] ={TMath::Sqrt(covardz[0]), TMath::Sqrt(covardz[2])}; + for(Int_t i=0; i<2; i++){ + residual[i] = dz[i] - mcDca[i]; // in centimeters + if(error[i]!=0)pull[i] = residual[i]/error[i]; // unitless + } + + + for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){ + // identified ones + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){ + if(pdg==fgkPdgParticle[iPart]) { + fHistDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4); + fHistDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4); + fHistDcaXYPull[iPart][iPtBin]->Fill(pull[0]); + fHistDcaZPull[iPart][iPtBin]->Fill(pull[1]); + fHistDcaXY[iPart][iPtBin]->Fill(dz[0]*1.0e4); + fHistDcaZ[iPart][iPtBin]->Fill(dz[1]*1.0e4); + } // mc pdg + + if(esdPid==fgkPdgParticle[iPart]) { + fHistEPDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4); + fHistEPDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4); + fHistEPDcaXYPull[iPart][iPtBin]->Fill(pull[0]); + fHistEPDcaZPull[iPart][iPtBin]->Fill(pull[1]); + fHistEPDcaXY[iPart][iPtBin]->Fill(dz[0]*1.0e4); + fHistEPDcaZ[iPart][iPtBin]->Fill(dz[1]*1.0e4); + } // esd pid + + } // pt range + + else + continue; + } // pt loop + } // particle id loop + + // for charged particles: no pid + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){ + Int_t iPart = 10; + if(charge>0) iPart = 11; + fHistDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1e4); + fHistDcaZRes[iPart][iPtBin]->Fill(residual[1]*1e4); + fHistDcaXYPull[iPart][iPtBin]->Fill(pull[0]); + fHistDcaZPull[iPart][iPtBin]->Fill(pull[1]); + fHistDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4); + fHistDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4); + } + else + continue; + } // pt + +} + +//_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsKfDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent) +{ + // the kKfDca plugin + +// filling historgams track by track + +// obtaining reconstructed dca ------------------------------------------------------------------ + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Float_t magneticField = 0; // initialized as 5kG + magneticField = esdEvent->GetMagneticField(); // in kG + + Float_t esdpx = track->Px(); + Float_t esdpy = track->Py(); + Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); + + Int_t charge = track->Charge(); + + Double_t beampiperadius=3.; + Double_t dz[2]; // error of dca in cm + Double_t covardz[3]; + if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection + track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz); + + AliMCParticle *mctrack = dynamic_cast(mcEvent->GetTrack(TMath::Abs(track->GetLabel()))); + TParticle *part = mctrack->Particle(); + Int_t pdg = part->GetPdgCode(); + + // calculate dca using AliKFParticle class------------------------------------------------------------------ + Double_t kfdz[3] = {0, 0, 0}; + Double_t kfdzwith[3] = {0, 0, 0}; + + Int_t trkID = track->GetID(); + + AliKFParticle::SetField(magneticField); + AliKFParticle kfParticle(*track, pdg); + + // prepare kfprimary vertex + AliKFVertex kfESDprimary; + // Reconstruct Primary Vertex (with ESD tracks) + Int_t n=primVtx->GetNIndices(); + if (n>0 && primVtx->GetStatus()){ + kfESDprimary = AliKFVertex(*primVtx); + + Double_t dcaXYWithTrk = kfParticle.GetDistanceFromVertexXY(kfESDprimary); + Double_t dcaWithTrk = kfParticle.GetDistanceFromVertex(kfESDprimary); + Double_t dcaZWithTrk = 0; + if(TMath::Abs(dcaWithTrk)>=TMath::Abs(dcaXYWithTrk)) + dcaZWithTrk =TMath::Sqrt(dcaWithTrk*dcaWithTrk-dcaXYWithTrk*dcaXYWithTrk)*((dz[1]*-1<=0)?1:-1); + kfdzwith[0] = dcaXYWithTrk; + kfdzwith[1] = dcaZWithTrk; + kfdzwith[2] = dcaWithTrk; // with current track + + Double_t dcaXYWoTrk = 0; + Double_t dcaZWoTrk = 0; + Double_t dcaWoTrk = 0; + + UShort_t *priIndex = primVtx->GetIndices(); + + for (Int_t i=0;i=0) + dcaZWoTrk = TMath::Abs(dcaWoTrk*dcaWoTrk - dcaXYWoTrk*dcaXYWoTrk)*((dz[1]*-1<=0)?1:-1); + } // remove current track from this calculation + } // loop over all primary vertex contributors + + + kfdz[0] = dcaXYWoTrk; + kfdz[1] = dcaZWoTrk; + kfdz[2] = dcaWoTrk; + + } // only if n contributor > 0 and primVtx constructed + + fStat->Fill(0); + + if(dz[0]!=0 && dz[0]*kfdzwith[0]>0 && TMath::Abs(kfdzwith[0]/dz[0])>0.9999 && TMath::Abs(kfdzwith[0]/dz[0])<1.0001)fStat->Fill(1);; // same + if(dz[0]!=0 && dz[0]*kfdzwith[0]<0 && TMath::Abs(kfdzwith[0]/dz[0])>0.9999 && TMath::Abs(kfdzwith[0]/dz[0])<1.0001) fStat->Fill(2); // swapped sign + if(kfdzwith[0]==0 && dz[0]!=0) fStat->Fill(3); // 0 from KF particle (with current track) + + if(dz[0]!=0 && dz[0]*kfdz[0]>0 && TMath::Abs(kfdz[0]/dz[0])>0.8 && TMath::Abs(kfdz[0]/dz[0])<1.2) fStat->Fill(-1);; // same + if(dz[0]!=0 && dz[0]*kfdz[0]<0 && TMath::Abs(kfdz[0]/dz[0])>0.8 && TMath::Abs(kfdz[0]/dz[0]) <1.2) fStat->Fill(-2); // swapped sign + if(kfdz[0]==0 && dz[0]!=0) fStat->Fill(-3); // 0 from KF particle (without current track) + + for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){ + // identified ones + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){ + if(pdg==fgkPdgParticle[iPart]) { + fHistKFDcaXY[iPart][iPtBin]->Fill(kfdzwith[0]*1.0e4); + fHistKFDcaZ[iPart][iPtBin]->Fill(kfdzwith[1]*1.0e4); + } // mc pdg + } // pt range + + else + continue; + } // pt loop + } // particle id loop + + // for charged particles: no pid + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){ + Int_t iPart = 10; + if(charge>0) iPart = 11; + fHistKFDcaXY[iPart][iPtBin]->Fill(kfdzwith[0]*1e4); + fHistKFDcaZ[iPart][iPtBin]->Fill(kfdzwith[1]*1e4); + + } + else + continue; + } // pt + +} // KF dca + + +//_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsVtx(AliESDEvent *const esdEvent, AliMCEvent *const mcEvent) +{ + + // MC vertex + AliMCVertex *mcPrimVtx = (AliMCVertex *)mcEvent->GetPrimaryVertex(); + Double_t mcPrimV[3]; + mcPrimV[0] = mcPrimVtx->GetX(); + mcPrimV[1] = mcPrimVtx->GetY(); + mcPrimV[2] = mcPrimVtx->GetZ(); + +// obtaining errors of dca ------------------------------------------------------------------ + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Double_t primV[3]; + primV[0] = primVtx->GetXv(); + primV[1] = primVtx->GetYv(); + primV[2] = primVtx->GetZv(); + + for(Int_t i=0; iFill(mcPrimV[i]*1.0e4); + fHistESDvertex[i]->Fill(primV[i]*1.0e4); + } + +} + +//_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsPid(AliESDtrack * const track, AliMCEvent * const mcEvent) +{ + + +// filling historgams track by track + Float_t esdpx = track->Px(); + Float_t esdpy = track->Py(); + Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); + + AliMCParticle *mctrack = dynamic_cast(mcEvent->GetTrack(TMath::Abs(track->GetLabel()))); + TParticle *part = mctrack->Particle(); + + Float_t mcpx = part->Px(); + Float_t mcpy = part->Py(); + Float_t mcpt = TMath::Sqrt(mcpx*mcpx+mcpy*mcpy); + + Int_t pdg = part->GetPdgCode(); + Int_t esdPid = GetCombinedPid(track); + + + Double_t ptMom[2] = {mcpt, esdpt}; + // for combined PID + for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){ + if(pdg==fgkPdgParticle[iPart]) // pid all by MC + fHistMcPid[iPart]->Fill(ptMom[0]); + + if(esdPid==fgkPdgParticle[iPart]) // pid all by combined pid + fHistEsdPid[iPart]->Fill(ptMom[1]); + } // loop over particles + + // for charged + if(pdg==kPDGelectron || pdg==kPDGmuon || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton) + fHistMcPid[10]->Fill(ptMom[0]); + if(pdg==-kPDGelectron || pdg==-kPDGmuon || pdg==kPDGpion || pdg==kPDGkaon || pdg==kPDGproton) + fHistMcPid[11]->Fill(ptMom[0]); + if(esdPid==kPDGelectron || esdPid==kPDGmuon || esdPid==-kPDGpion || esdPid==-kPDGkaon || esdPid==-kPDGproton) + fHistEsdPid[10]->Fill(ptMom[1]); + if(esdPid==-kPDGelectron || esdPid==-kPDGmuon || esdPid==kPDGpion || esdPid==kPDGkaon || esdPid==kPDGproton) + fHistEsdPid[11]->Fill(ptMom[1]); } +////_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsDataDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliESDVertex * const vtxESDSkip) +{ +// filling historgams track by track +// obtaining reconstructed dca -------------------------------------------------------------- + + Float_t esdpx = track->Px(); + Float_t esdpy = track->Py(); + Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); + Int_t charge = track->Charge(); + +// obtaining errors of dca ------------------------------------------------------------------ + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Double_t primV[3]; + primV[0] = primVtx->GetXv(); + primV[1] = primVtx->GetYv(); + primV[2] = primVtx->GetZv(); + + + Float_t magneticField = 0; // initialized as 5kG + magneticField = esdEvent->GetMagneticField(); // in kG + + Double_t beampiperadius=3.; + Double_t dz[2]; // error of dca in cm + Double_t covardz[3]; + + if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection + track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz); + + Double_t pull[2] = {0, 0}; + Double_t error[2] ={TMath::Sqrt(covardz[0]), TMath::Sqrt(covardz[2])}; + for(Int_t i=0; i<2; i++){ + if(error[i]!=0)pull[i] = dz[i]/error[i]; // unitless + } + + // get dca when current track is not included + + Double_t dzwo[2], covardzwo[3]; + Double_t pullwo[2] = {0, 0}; + if(!track->PropagateToDCA(vtxESDSkip, magneticField, beampiperadius, dzwo, covardzwo)) return; // protection + track->PropagateToDCA(vtxESDSkip, magneticField, beampiperadius, dzwo, covardzwo); + + Double_t errorwo[2] ={TMath::Sqrt(TMath::Abs(covardzwo[0])), TMath::Sqrt(TMath::Abs(covardzwo[2]))}; + for(Int_t i=0; i<2; i++){ + if(errorwo[i]!=0) pullwo[i] = dzwo[i]/errorwo[i]; // unitless + } + + // do pid + Int_t esdPid = GetCombinedPid(track); + + for(Int_t iPart=0; iPart<(kNParticles-2); iPart++){ + // identified ones + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1])) { + fHistDataDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4); + fHistDataDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4); + fHistDataDcaXYPull[iPart][iPtBin]->Fill(pull[0]); + fHistDataDcaZPull[iPart][iPtBin]->Fill(pull[1]); + // w/o current track + fHistDataWoDcaXY[iPart][iPtBin]->Fill(dzwo[0]*1e4); + fHistDataWoDcaZ[iPart][iPtBin]->Fill(dzwo[1]*1e4); + fHistDataWoDcaXYPull[iPart][iPtBin]->Fill(pullwo[0]); + fHistDataWoDcaZPull[iPart][iPtBin]->Fill(pullwo[1]); + } + else + continue; + } + } + + // for charged particles + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){ + Int_t iPart = 10; + if(charge>0) iPart = 11; + fHistDataDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4); + fHistDataDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4); + fHistDataDcaXYPull[iPart][iPtBin]->Fill(pull[0]); + fHistDataDcaZPull[iPart][iPtBin]->Fill(pull[1]); + // without current track + fHistDataWoDcaXY[iPart][iPtBin]->Fill(dzwo[0]*1e4); + fHistDataWoDcaZ[iPart][iPtBin]->Fill(dzwo[1]*1e4); + fHistDataWoDcaXYPull[iPart][iPtBin]->Fill(pullwo[0]); + fHistDataWoDcaZPull[iPart][iPtBin]->Fill(pullwo[1]); + + } + else + continue; + } + +} + //_______________________________________________________________________________________________ -void AliHFEdca::FillHistograms(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent) +void AliHFEdca::FillHistogramsDataVtx(AliESDEvent * const esdEvent) +{ + + +// obtaining errors of dca ------------------------------------------------------------------ + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Double_t primV[3]; + primV[0] = primVtx->GetXv(); + primV[1] = primVtx->GetYv(); + primV[2] = primVtx->GetZv(); + + // require events with at least 3 contributors for primary vertex construction + Int_t nEsdPrimVtxCtrb = primVtx->GetNContributors(); + if(nEsdPrimVtxCtrb<1) return; // for pass 1, no diomond constrain, each event has at least 1 contributor to Vtx + for(Int_t i=0; iFill(primV[i]*1e4); + +} + + +////_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsDataPid(AliESDtrack * const track) { // filling historgams track by track +// obtaining reconstructed dca -------------------------------------------------------------- + + Float_t esdpx = track->Px(); + Float_t esdpy = track->Py(); + Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); + Int_t charge = track->Charge(); + + Int_t esdPid = GetCombinedPid(track); + + for(Int_t iPart=0; iPartFill(esdpt); + } // for identified + else { + if(charge<0) fHistDataEsdPid[10]->Fill(esdpt); + if(charge>0) fHistDataEsdPid[11]->Fill(esdpt); + } + } +} + +//_________________________________________________________________________________________________ +void AliHFEdca::ApplyExtraCuts(AliESDEvent * const esdEvent, Int_t nMinPrimVtxContributor) +{ + + // + // only one extra cut, number of contributors to each primary vertex + // + + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Int_t nEsdPrimVtxCtrb = primVtx->GetNContributors(); + if(nEsdPrimVtxCtrbGetESDpid(prob); + Double_t priors[5] = {0.01, 0.01, 0.85, 0.10, 0.05}; + + Int_t charge = track->Charge(); + Int_t esdPid = -1; + + AliPID pid; + pid.SetPriors(priors); + pid.SetProbabilities(prob); + + // identify particle as the most probable + + Double_t pelectron = pid.GetProbability(AliPID::kElectron); + if(pelectron > pid.GetProbability(AliPID::kMuon) && + pelectron > pid.GetProbability(AliPID::kPion) && + pelectron > pid.GetProbability(AliPID::kKaon) && + pelectron > pid.GetProbability(AliPID::kProton) ) esdPid = -kPDGelectron; + + Double_t pmuon = pid.GetProbability(AliPID::kMuon); + if(pmuon > pid.GetProbability(AliPID::kElectron) && + pmuon > pid.GetProbability(AliPID::kPion) && + pmuon > pid.GetProbability(AliPID::kKaon) && + pmuon > pid.GetProbability(AliPID::kProton) ) esdPid = -kPDGmuon; + + Double_t ppion = pid.GetProbability(AliPID::kPion); + if(ppion > pid.GetProbability(AliPID::kElectron) && + ppion > pid.GetProbability(AliPID::kMuon) && + ppion > pid.GetProbability(AliPID::kKaon) && + ppion > pid.GetProbability(AliPID::kProton) ) esdPid = kPDGpion; + + Double_t pkaon = pid.GetProbability(AliPID::kKaon); + if(pkaon > pid.GetProbability(AliPID::kElectron) && + pkaon > pid.GetProbability(AliPID::kMuon) && + pkaon > pid.GetProbability(AliPID::kPion) && + pkaon > pid.GetProbability(AliPID::kProton) ) esdPid = kPDGkaon; + + Double_t pproton = pid.GetProbability(AliPID::kProton); + if(pproton > pid.GetProbability(AliPID::kElectron) && + pproton > pid.GetProbability(AliPID::kMuon) && + pproton > pid.GetProbability(AliPID::kPion) && + pproton > pid.GetProbability(AliPID::kKaon) ) esdPid = kPDGproton; + + + return charge*esdPid; + +} + + +// for the HFE pid + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsHfeDca(TList *hfeDcaList){ + // + // define histograms: hfe pid electrons in MC + // + + const Int_t nBinsDca = 1000; + const Float_t maxXYBinDca = 1000.; + const Float_t maxZBinDca = 1000.; + + const Int_t nBinsPull = 1000; + const Float_t maxXYBinPull = 20.; + const Float_t maxZBinPull = 20.; + + const Char_t *mcOResd[2]={"mcPt", "esdPt"}; + + fHistHPDcaXY[2][kNPtBins]=0x0; + fHistHPDcaZ[2][kNPtBins]=0x0; + fHistHPDcaXYRes[2][kNPtBins]=0x0; + fHistHPDcaZRes[2][kNPtBins]=0x0; + fHistHPDcaXYPull[2][kNPtBins]=0x0; + fHistHPDcaZPull[2][kNPtBins]=0x0; + + + for(Int_t k=0; kSetLineColor((const int)fgkColorPart[iPart*5]); + fHistHPDcaXYRes[iPart][i] = new TH1F((const char*)histHPNameRes, (const char*)histTitleRes, nBinsDca, 1-maxXYBinDca, 1+maxXYBinDca); + fHistHPDcaXYRes[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + fHistHPDcaXYPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsPull, 1-maxXYBinPull, 1+maxXYBinPull); + fHistHPDcaXYPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + } + + if(k==1){ + fHistHPDcaZ[iPart][i] = new TH1F((const char*)histHPName, (const char*)histTitleDca, nBinsDca, 1-maxZBinDca, 1+maxZBinDca); + fHistHPDcaZ[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + fHistHPDcaZRes[iPart][i] = new TH1F((const char*)histHPNameRes, (const char*)histTitleRes, nBinsDca, 1-maxZBinDca, 1+maxZBinDca); + fHistHPDcaZRes[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + fHistHPDcaZPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsPull, 1-maxZBinPull, 1+maxZBinPull); + fHistHPDcaZPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + } + } // 50 pt bins + } //2 nparticles + } // 2 dca var + + fHistHfePid[2][2] = 0x0; //! HFE pid + for(Int_t id=0; id<2; id++){ + for(Int_t iPart=0; iPart<2; iPart++){ + TString histTitleHfe((const char*)fgkParticles[iPart*5]); + histTitleHfe+=Form("_MC_HfePid_esdPt;p_{T} [GeV/c];counts"); + TString histNameHfe((const char*)fgkParticles[iPart*5]); + histNameHfe+=Form("_MC_HfePid_%s", mcOResd[id]); + fHistHfePid[id][iPart] = new TH1F(histNameHfe, histTitleHfe, kNPtBins, fgkPtIntv); + } + } + + hfeDcaList->SetOwner(); + hfeDcaList->SetName("hfeDca"); + for(Int_t iPart=0; iPart<2; iPart++){ + for(Int_t iPtBin=0; iPtBinAdd(fHistHPDcaXY[iPart][iPtBin]); + hfeDcaList->Add(fHistHPDcaZ[iPart][iPtBin]); + hfeDcaList->Add(fHistHPDcaXYRes[iPart][iPtBin]); + hfeDcaList->Add(fHistHPDcaZRes[iPart][iPtBin]); + hfeDcaList->Add(fHistHPDcaXYPull[iPart][iPtBin]); + hfeDcaList->Add(fHistHPDcaZPull[iPart][iPtBin]); + } + for(Int_t id=0; id<2; id++) + hfeDcaList->Add(fHistHfePid[id][iPart]); + } + +} + + +//________________________________________________________________________ +void AliHFEdca::CreateHistogramsHfeDataDca(TList *hfeDataDcaList){ + // + // define histograms: hfe pid electrons in data + // + + const Int_t nBinsDca = 1000; + const Float_t maxXYBinDca = 1000.; + const Float_t maxZBinDca = 1000.; + + const Int_t nBinsPull = 1000; + const Float_t maxXYBinPull = 20.; + const Float_t maxZBinPull = 20.; + + + fHistHPDataDcaXY[2][kNPtBins]=0x0; + fHistHPDataDcaZ[2][kNPtBins]=0x0; + fHistHPDataDcaXYPull[2][kNPtBins]=0x0; + fHistHPDataDcaZPull[2][kNPtBins]=0x0; + + for(Int_t k=0; kSetLineColor((const int)fgkColorPart[iPart*5]); + fHistHPDataDcaXYPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsPull, 1-maxXYBinPull, 1+maxXYBinPull); + fHistHPDataDcaXYPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + } + + if(k==1){ + fHistHPDataDcaZ[iPart][i] = new TH1F((const char*)histHPName, (const char*)histTitleDca, nBinsDca, 1-maxZBinDca, 1+maxZBinDca); + fHistHPDataDcaZ[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + fHistHPDataDcaZPull[iPart][i] = new TH1F((const char*)histHPNamePull, (const char*)histTitlePull, nBinsDca, 1-maxZBinPull, 1+maxZBinPull); + fHistHPDataDcaZPull[iPart][i]->SetLineColor((const int)fgkColorPart[iPart*5]); + } + + } // 50 pt bins + } // 2 particle type + } // 2 dca var + + fHistDataHfePid[2] = 0x0; //! HFE pid + for(Int_t iPart=0; iPart<2; iPart++){ + TString histTitleHfe((const char*)fgkParticles[iPart*5]); + histTitleHfe+=Form("_Data_HfePid_esdPt;p_{T} [GeV/c];counts"); + TString histNameHfe((const char*)fgkParticles[iPart*5]); + histNameHfe+=Form("_Data_HfePid"); + fHistDataHfePid[iPart] = new TH1F(histNameHfe, histTitleHfe, kNPtBins, fgkPtIntv); + } + + + hfeDataDcaList->SetOwner(); + hfeDataDcaList->SetName("hfeDataDca"); + for(Int_t iPart=0; iPart<2; iPart++){ + for(Int_t iPtBin=0; iPtBinAdd(fHistHPDataDcaXY[iPart][iPtBin]); + hfeDataDcaList->Add(fHistHPDataDcaZ[iPart][iPtBin]); + hfeDataDcaList->Add(fHistHPDataDcaXYPull[iPart][iPtBin]); + hfeDataDcaList->Add(fHistHPDcaZPull[iPart][iPtBin]); + + hfeDataDcaList->Add(fHistDataHfePid[iPart]); + } + } + + +} + + +//_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsHfeDca(AliESDEvent * const esdEvent, AliESDtrack * const track, AliMCEvent * const mcEvent) +{ + // the kHFEpid plugin + + AliMCVertex *mcPrimVtx = (AliMCVertex *)mcEvent->GetPrimaryVertex(); + Double_t mcPrimV[3]; + mcPrimV[0] = mcPrimVtx->GetX(); + mcPrimV[1] = mcPrimVtx->GetY(); + mcPrimV[2] = mcPrimVtx->GetZ(); + + Double_t mcVtxXY = TMath::Abs(mcPrimV[0]*mcPrimV[0] + mcPrimV[1]*mcPrimV[1]); + +// filling historgams track by track // obtaining reconstructed dca ------------------------------------------------------------------ - Float_t esdpx = track->Px(); - Float_t esdpy = track->Py(); - Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); - Float_t b[2]; // dca in cm - Float_t bCov[3]; // covariance matrix - track->GetImpactParameters(b,bCov); - + Float_t esdpx = track->Px(); + Float_t esdpy = track->Py(); + Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); + +// obtaining errors of dca ------------------------------------------------------------------ + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Double_t primV[3]; + primV[0] = primVtx->GetXv(); + primV[1] = primVtx->GetYv(); + primV[2] = primVtx->GetZv(); + + Float_t magneticField = 0; // initialized as 5kG + magneticField = esdEvent->GetMagneticField(); // in kG + + Double_t beampiperadius=3.; + Double_t dz[2]; // error of dca in cm + Double_t covardz[3]; + if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection + track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz); + + AliMCParticle *mctrack = dynamic_cast(mcEvent->GetTrack(TMath::Abs(track->GetLabel()))); + TParticle *part = mctrack->Particle(); + + Float_t vx = part->Vx(); // in cm + Float_t vy = part->Vy(); // in cm + Float_t vz = part->Vz(); // in cm + + Float_t vxy = TMath::Sqrt(vx*vx+vy*vy); + + Float_t mcpx = part->Px(); + Float_t mcpy = part->Py(); + Float_t mcpt = TMath::Sqrt(mcpx*mcpx+mcpy*mcpy); + + Int_t pdg = part->GetPdgCode(); + + Int_t charge = 1; + if(pdg==kPDGelectron || pdg==kPDGmuon + || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton) charge = -1; + + // calculate mcDca ------------------------------------------------------------------ + const Float_t conv[2] = {1.783/1.6, 2.99792458}; + Float_t radiusMc = mcpt/(TMath::Abs(magneticField)/10.)*conv[0]*conv[1]; // pt in GeV/c, magnetic field in Tesla, radius in meter + + Float_t nx = esdpx/mcpt; + Float_t ny = esdpy/mcpt; + + Float_t radius; + radius = TMath::Abs(radiusMc); + + Double_t dxy = vxy - mcVtxXY; // in cm + Double_t dvx = vx - mcPrimV[0]; // in cm + Double_t dvy = vy - mcPrimV[1]; // in cm + + Float_t mcDcaXY = (radius - TMath::Sqrt(dxy*dxy/100./100. + radius*radius + 2*radius*charge*(dvx*ny-dvy*nx)/100.)) ; // in meters + + Double_t mcDca[2] = {mcDcaXY*100, vz}; // in cm + Double_t residual[2] = {0, 0}; + Double_t pull[2] = {0, 0}; + Double_t error[2] ={TMath::Sqrt(covardz[0]), TMath::Sqrt(covardz[2])}; + for(Int_t i=0; i<2; i++){ + residual[i] = dz[i] - mcDca[i]; // in centimeters + if(error[i]!=0)pull[i] = residual[i]/error[i]; // unitless + } + + Int_t iPart = -1; + if(track->Charge()<0) iPart = 0; // electron + if(track->Charge()>0) iPart = 1; // positron + if(track->Charge()==0) { + printf("this is not an electron! Check HFEpid method"); + return; + } + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){ + fHistHPDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4); + fHistHPDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4); + fHistHPDcaXYPull[iPart][iPtBin]->Fill(pull[0]); + fHistHPDcaZPull[iPart][iPtBin]->Fill(pull[1]); + fHistHPDcaXY[iPart][iPtBin]->Fill(dz[0]*1.0e4); + fHistHPDcaZ[iPart][iPtBin]->Fill(dz[1]*1.0e4); + + } // pt range + + else + continue; + } // pt loop + + fHistHfePid[iPart][0]->Fill(esdpt); + fHistHfePid[iPart][1]->Fill(mcpt); + +} + + +//_______________________________________________________________________________________________ +void AliHFEdca::FillHistogramsHfeDataDca(AliESDEvent * const esdEvent, AliESDtrack * const track) +{ +// filling historgams track by track +// obtaining reconstructed dca -------------------------------------------------------------- + + Float_t esdpx = track->Px(); + Float_t esdpy = track->Py(); + Float_t esdpt = TMath::Sqrt(esdpx*esdpx+esdpy*esdpy); + Int_t charge = track->Charge(); + // obtaining errors of dca ------------------------------------------------------------------ - const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); - Float_t magneticField = 5; // initialized as 5kG - magneticField = esdEvent->GetMagneticField(); // in kG - - Double_t dz[2]; // error of dca in cm - Double_t covardz[3]; - track->PropagateToDCA(primVtx,magneticField, 1000., dz, covardz); - - // calculate mcDca ------------------------------------------------------------------ - - AliMCParticle *mctrack = dynamic_cast(mcEvent->GetTrack(TMath::Abs(track->GetLabel()))); - TParticle *part = mctrack->Particle(); - Int_t pdg = part->GetPdgCode(); - Int_t charge = 1; - if(pdg==kPDGelectron || pdg==kPDGmuon - || pdg==-kPDGpion || pdg==-kPDGkaon || pdg==-kPDGproton) charge = -1; - - Float_t vx = part->Vx(); // in cm - Float_t vy = part->Vy(); // in cm - Float_t vz = part->Vz(); // in cm - - Float_t vxy = TMath::Sqrt(vx*vx+vy*vy); - - Float_t mcpx = part->Px(); - Float_t mcpy = part->Py(); - Float_t mcpt = TMath::Sqrt(mcpx*mcpx+mcpy*mcpy); - - const Float_t conv[2] = {1.783/1.6, 2.99792458}; - Float_t radiusMc = mcpt/(TMath::Abs(magneticField)/10.)*conv[0]*conv[1]; // pt in GeV/c, magnetic field in Tesla - - Float_t nx = esdpx/mcpt; - Float_t ny = esdpy/mcpt; - - Float_t radius; - radius = TMath::Abs(radiusMc); - Float_t mcDcaXY = (radius - TMath::Sqrt(vxy*vxy/100./100. + radius*radius + 2*radius*charge*(vx*ny-vy*nx)/100.)) ; // in meters - -// printf("magnetic Field = %.3f \t", magneticField); -// printf("pt=esd %.3f/mc %.3f GeV/c, radius=esd %.3f/mc %.3f meter \n", esdpt, mcpt, radiusEsd, radiusMc); -// printf("mcDcaXY=%.5f micron, esdDcaXY=%.5f micron \t ", mcDcaXY*1.e6, b[0]*1e4); -// printf("mcDcaZ=%.5f micron, esdDcaZ=%.5f micron\n\n", vz*1e6, b[1]*1e4); - - Double_t mcDca[2] = {mcDcaXY*100, vz}; // in cm - - Double_t residual[2] = {0, 0}; - Double_t pull[2] = {0, 0}; - Double_t error[2] ={TMath::Sqrt(covardz[0]), TMath::Sqrt(covardz[2])}; - for(Int_t i=0; i<2; i++){ - residual[i] = dz[i] - mcDca[i]; // in centimeters - if(error[i]!=0)pull[i] = residual[i]/error[i]; // unitless - // printf("error[%d]=%.6f residual[%d]=%.6f pull[%d]=%.6f\n", i, error[i], i, residual[i], i, pull[i]); - } - - Int_t fPdgParticle[10] = { - kPDGelectron, kPDGmuon, -kPDGpion, -kPDGkaon, -kPDGproton, - -kPDGelectron, -kPDGmuon, kPDGpion, kPDGkaon, kPDGproton}; - - for(Int_t iPart=0; iPartfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1])) { - fHistDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1.0e4); // in microns - fHistDcaZRes[iPart][iPtBin]->Fill(residual[1]*1.0e4); // in microns - fHistDcaXYPull[iPart][iPtBin]->Fill(pull[0]); - fHistDcaZPull[iPart][iPtBin]->Fill(pull[1]); - } - else - continue; - } - } - - // for charged particles - for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]){ - Int_t iPart = 10; - if(charge>0) iPart = 11; - fHistDcaXYRes[iPart][iPtBin]->Fill(residual[0]*1e4); - fHistDcaZRes[iPart][iPtBin]->Fill(residual[1]*1e4); - fHistDcaXYPull[iPart][iPtBin]->Fill(pull[0]); - fHistDcaZPull[iPart][iPtBin]->Fill(pull[1]); - } - else - continue; - } - + const AliESDVertex *primVtx = esdEvent->GetPrimaryVertex(); + Double_t primV[3]; + primV[0] = primVtx->GetXv(); + primV[1] = primVtx->GetYv(); + primV[2] = primVtx->GetZv(); + + Float_t magneticField = 0; // initialized as 5kG + magneticField = esdEvent->GetMagneticField(); // in kG + Double_t beampiperadius=3.; + Double_t dz[2]; // error of dca in cm + Double_t covardz[3]; + if(!track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz)) return; // protection + track->PropagateToDCA(primVtx,magneticField, beampiperadius, dz, covardz); + + Double_t pull[2] = {0, 0}; + Double_t error[2] ={TMath::Sqrt(covardz[0]), TMath::Sqrt(covardz[2])}; + for(Int_t i=0; i<2; i++){ + if(error[i]!=0)pull[i] = dz[i]/error[i]; // unitless + } + + Int_t iPart = -1; + if(charge<0) iPart = 0; // electron + if(charge>0) iPart = 1; // positron + if(charge==0) { + printf("this is not an electron! Check HFEpid method\n"); + return; + } + + for(Int_t iPtBin=0; iPtBinfgkPtIntv[iPtBin] && esdpt<=fgkPtIntv[iPtBin+1]) { + fHistHPDataDcaXY[iPart][iPtBin]->Fill(dz[0]*1e4); + fHistHPDataDcaZ[iPart][iPtBin]->Fill(dz[1]*1e4); + fHistHPDataDcaXYPull[iPart][iPtBin]->Fill(pull[0]); + fHistHPDataDcaZPull[iPart][iPtBin]->Fill(pull[1]); + + } + else + continue; + } + + fHistDataHfePid[iPart]->Fill(esdpt); + } diff --git a/PWG3/hfe/AliHFEdca.h b/PWG3/hfe/AliHFEdca.h index f7203e4b405..a6446b3fa36 100644 --- a/PWG3/hfe/AliHFEdca.h +++ b/PWG3/hfe/AliHFEdca.h @@ -14,9 +14,11 @@ **************************************************************************/ // // Class for checking impact parameter (DCA) study -// Study DCA in rphi (xy) and z -// resolution and pull -// +// + study DCA in rphi (xy) and z +// + resolution and pull +// + handle both MC and data +// + add plugin for primary vertex +// #ifndef ALIHFEDCA_H #define ALIHFEDCA_H @@ -35,6 +37,7 @@ class TList; class TObjArray; class AliStack; class AliMCEvent; +class AliMCVertex; class AliESDEvent; class AliESDtrack; @@ -53,27 +56,63 @@ class AliHFEdca : public TObject{ enum{ kNParticles = 12, - kNPtBins = 43, + kNPtBins = 50, kNDcaVar = 2, + kNVertexVar = 3, kNPullVar = 2 }; - AliHFEdca(); - AliHFEdca(const AliHFEdca &p); // copy constructor - AliHFEdca &operator=(const AliHFEdca &); // assignment operator - - virtual ~AliHFEdca(); + AliHFEdca(); // default constructor + AliHFEdca(const AliHFEdca &ref); // copy constructor + AliHFEdca &operator=(const AliHFEdca &ref); // assignment operator + virtual ~AliHFEdca(); // destructor void Initialize(); void CreateHistogramsPull(TList *pullList); void CreateHistogramsResidual(TList *residualList); + void CreateHistogramsDca(TList *dcaList); + + void CreateHistogramsKfDca(TList *kfDcaList); + + void CreateHistogramsDataDca(TList *dataDcaList); + void CreateHistogramsDataPull(TList *dataPullList); + + void CreateHistogramsVertex(TList *vertexList); + void CreateHistogramsDataVertex(TList *vertexList); + + void CreateHistogramsPid(TList *pidList); + void CreateHistogramsDataPid(TList *pidList); + + void CreateHistogramsHfeDca(TList *hfeDcaList); + void CreateHistogramsHfeDataDca(TList *hfeDataDcaList); + + void InitAnalysis(); - void FillHistograms(AliESDEvent *esdEvent, AliESDtrack *track, AliMCEvent *mcEvent); + void FillHistogramsDca(AliESDEvent *esdEvent, AliESDtrack *track, AliMCEvent *mcEvent); + void FillHistogramsVtx(AliESDEvent *esdEvent, AliMCEvent *mcEvent); + void FillHistogramsPid(AliESDtrack *track, AliMCEvent *mcEvent); + + void FillHistogramsKfDca(AliESDEvent *esdEvent, AliESDtrack *track, AliMCEvent *mcEvent); + + void FillHistogramsDataDca(AliESDEvent *esdEvent, AliESDtrack *track, AliESDVertex *vtxESDSkip); + void FillHistogramsDataVtx(AliESDEvent *esdEvent); + void FillHistogramsDataPid(AliESDtrack *track); + + void FillHistogramsHfeDca(AliESDEvent *esdEvent, AliESDtrack *track, AliMCEvent *mcEvent); + void FillHistogramsHfeDataDca(AliESDEvent *esdEvent, AliESDtrack *track); + + + void ApplyExtraCuts(AliESDEvent * const esdEvent, Int_t nMinPrimVtxContributor); + void PostAnalysis() const; + Int_t GetCombinedPid(AliESDtrack *track); private: - static const Char_t *fgkParticles[kNParticles]; // particle names + + + static const Char_t* fgkParticles[kNParticles]; // particle names + static const Int_t fgkPdgParticle[kNParticles-2]; // identified particle's name static const Int_t fgkColorPart[kNParticles]; // colors for particles static const Float_t fgkPtIntv[kNPtBins+1]; // pt intervals @@ -81,17 +120,76 @@ class AliHFEdca : public TObject{ static const Char_t* fgkDcaVar[kNDcaVar]; // dca variables static const Char_t* fgkDcaVarTitle[kNDcaVar]; // titles for dca variables + static const Char_t* fgkVertexVar[kNVertexVar]; // dca variables + static const Char_t* fgkVertexVarTitle[kNVertexVar]; // titles for dca variables + + static const Char_t* fgkResDcaVar[kNDcaVar]; // dca variables + static const Char_t* fgkResDcaVarTitle[kNDcaVar]; // titles for dca variables + static const Char_t* fgkPullDcaVar[kNPullVar]; // pull variables static const Char_t* fgkPullDcaVarTitle[kNPullVar]; // titles for pull variables + static const Char_t* fgkPullDataDcaVarTitle[kNPullVar]; // titles for pull variables TH1F* fHistDcaXYRes[kNParticles][kNPtBins]; //! residuals in XY TH1F* fHistDcaZRes[kNParticles][kNPtBins]; //! residuals in Z + TH1F* fHistDcaXYPull[kNParticles][kNPtBins]; //! pulls XY TH1F* fHistDcaZPull[kNParticles][kNPtBins]; //! pulls Z - TList *fResidualList; //! collection of histograms of residual - TList *fPullList; //! collection of histograms of pull + TH1F* fHistDcaXY[kNParticles][kNPtBins]; //! dca XY + TH1F* fHistDcaZ[kNParticles][kNPtBins]; //! dca Z + + TH1F* fHistEPDcaXYRes[kNParticles-2][kNPtBins]; //! residuals in XY with esd pid + TH1F* fHistEPDcaZRes[kNParticles-2][kNPtBins]; //! residuals in Z with esd pid + + TH1F* fHistEPDcaXYPull[kNParticles-2][kNPtBins]; //! pulls XY with esd pid + TH1F* fHistEPDcaZPull[kNParticles-2][kNPtBins]; //! pulls Z with esd pid + + TH1F* fHistEPDcaXY[kNParticles-2][kNPtBins]; //! dca XY with esd pid + TH1F* fHistEPDcaZ[kNParticles-2][kNPtBins]; //! dca Z with esd pid + + TH1F* fHistKFDcaXY[kNParticles][kNPtBins]; //! KF dca XY + TH1F* fHistKFDcaZ[kNParticles][kNPtBins]; //! KF dca Z + TH1F* fHistDataDcaXY[kNParticles][kNPtBins]; //! data dca XY + TH1F* fHistDataDcaZ[kNParticles][kNPtBins]; //! data dca Z + TH1F* fHistDataWoDcaXY[kNParticles][kNPtBins]; //! data dca XY w/o current trk + TH1F* fHistDataWoDcaZ[kNParticles][kNPtBins]; //! data dca Z w/o current trk + + TH1F* fHistDataDcaXYPull[kNParticles][kNPtBins]; //! data pull dca XY + TH1F* fHistDataDcaZPull[kNParticles][kNPtBins]; //! data pull dca Z + TH1F* fHistDataWoDcaXYPull[kNParticles][kNPtBins]; //! data pull dca XY w/o current trk + TH1F* fHistDataWoDcaZPull[kNParticles][kNPtBins]; //! data pull dca Z w/o current trk + + TH1F* fHistMCvertex[kNVertexVar]; //! vertex MC + TH1F* fHistESDvertex[kNVertexVar]; //! vertex ESD + TH1F* fHistDatavertex[kNVertexVar]; //! vertex Data + + TH1F* fHistMcPid[kNParticles]; //! MC pid pt spectra + TH1F* fHistEsdPid[kNParticles]; //! ESD pid pt spectra + + TH1F *fHistDataEsdPid[kNParticles]; //! Data ESD pid + + // HFE pid part + // MC + TH1F* fHistHPDcaXYRes[2][kNPtBins]; //! residuals in XY + TH1F* fHistHPDcaZRes[2][kNPtBins]; //! residuals in Z + TH1F* fHistHPDcaXYPull[2][kNPtBins]; //! pulls XY + TH1F* fHistHPDcaZPull[2][kNPtBins]; //! pulls Z + TH1F* fHistHPDcaXY[2][kNPtBins]; //! dca XY + TH1F* fHistHPDcaZ[2][kNPtBins]; //! dca Z + + TH1F* fHistHfePid[2][2]; // ! HFE pid pt spectra only for electrons + + // Data + TH1F* fHistHPDataDcaXY[2][kNPtBins]; //! data dca XY with HFE pid + TH1F* fHistHPDataDcaZ[2][kNPtBins]; //! data dca Z with HFE pid + TH1F* fHistHPDataDcaXYPull[2][kNPtBins]; //! data pull dca XY + TH1F* fHistHPDataDcaZPull[2][kNPtBins]; //! data pull dca Z + + TH1F *fHistDataHfePid[2]; //! Data HFE pid + + TH1I* fStat; //! counting diff of dca calculated from HF particle and ESD ClassDef(AliHFEdca, 1); }; diff --git a/PWG3/hfe/AliHFEdisplacedElectrons.cxx b/PWG3/hfe/AliHFEdisplacedElectrons.cxx index aacf6f7d694..13174da436c 100644 --- a/PWG3/hfe/AliHFEdisplacedElectrons.cxx +++ b/PWG3/hfe/AliHFEdisplacedElectrons.cxx @@ -19,6 +19,7 @@ // // Authors: // Hongyan Yang +// Carlo Bombonati // #include "TMath.h" @@ -27,14 +28,21 @@ #include #include - #include "THnSparse.h" + #include "AliMCEvent.h" -#include "AliESDEvent.h" +#include "AliMCVertex.h" #include "AliMCParticle.h" +#include "AliStack.h" + +#include "AliESDEvent.h" #include "AliESDtrack.h" -#include "AliStack.h" +#include "AliKFParticle.h" +#include "AliKFVertex.h" + +#include "AliVertexerTracks.h" + #include "AliHFEdisplacedElectrons.h" @@ -79,11 +87,13 @@ const Char_t *AliHFEdisplacedElectrons::fgkKineVarTitle[3] ={ //__________________________________________________________ AliHFEdisplacedElectrons::AliHFEdisplacedElectrons(): - fDebugLevel(0) - , fTHnSparseDcaMcPionInfo(NULL) + fDeDebugLevel(0) + , fNclustersITS(0) + , fMinNprimVtxContributor(1) , fTHnSparseDcaMcEleInfo(NULL) + , fTHnSparseDcaEsdEleInfo(NULL) , fTHnSparseDcaDataEleInfo(NULL) - , fOutputList(0x0) + , fDeOutputList(0x0) { // // default constructor @@ -94,11 +104,13 @@ AliHFEdisplacedElectrons::AliHFEdisplacedElectrons(): //__________________________________________________________ AliHFEdisplacedElectrons::AliHFEdisplacedElectrons(const AliHFEdisplacedElectrons &ref): TObject(ref) - , fDebugLevel(ref.fDebugLevel) - , fTHnSparseDcaMcPionInfo(ref.fTHnSparseDcaMcPionInfo) + , fDeDebugLevel(ref.fDeDebugLevel) + , fNclustersITS(ref.fNclustersITS) + , fMinNprimVtxContributor(ref.fMinNprimVtxContributor) , fTHnSparseDcaMcEleInfo(ref.fTHnSparseDcaMcEleInfo) + , fTHnSparseDcaEsdEleInfo(ref.fTHnSparseDcaEsdEleInfo) , fTHnSparseDcaDataEleInfo(ref.fTHnSparseDcaDataEleInfo) - , fOutputList(ref.fOutputList) + , fDeOutputList(ref.fDeOutputList) { // @@ -117,12 +129,13 @@ AliHFEdisplacedElectrons&AliHFEdisplacedElectrons::operator=(const AliHFEdisplac if(this == &ref) return *this; AliHFEdisplacedElectrons::operator=(ref); - fDebugLevel = ref.fDebugLevel; - - fTHnSparseDcaMcPionInfo = ref.fTHnSparseDcaMcPionInfo; + fDeDebugLevel = ref.fDeDebugLevel; + fNclustersITS = ref.fNclustersITS; + fMinNprimVtxContributor = ref.fMinNprimVtxContributor; fTHnSparseDcaMcEleInfo = ref.fTHnSparseDcaMcEleInfo; + fTHnSparseDcaEsdEleInfo = ref.fTHnSparseDcaEsdEleInfo; fTHnSparseDcaDataEleInfo = ref.fTHnSparseDcaDataEleInfo; - fOutputList = ref.fOutputList; + fDeOutputList = ref.fDeOutputList; return *this; } @@ -134,16 +147,16 @@ AliHFEdisplacedElectrons::~AliHFEdisplacedElectrons() // default constructor // - if(fTHnSparseDcaMcPionInfo) - delete fTHnSparseDcaMcPionInfo; if(fTHnSparseDcaMcEleInfo) delete fTHnSparseDcaMcEleInfo; + if(fTHnSparseDcaEsdEleInfo) + delete fTHnSparseDcaEsdEleInfo; if(fTHnSparseDcaDataEleInfo) delete fTHnSparseDcaDataEleInfo; - if(fOutputList){ - fOutputList->Clear(); - delete fOutputList; + if(fDeOutputList){ + fDeOutputList->Clear(); + delete fDeOutputList; } @@ -166,13 +179,12 @@ void AliHFEdisplacedElectrons::InitAnalysis(){ void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){ // - // create output fOutputList + // create output fDeOutputList // // THnSparseF - // 8 interested electron sources: others, photon conv, direct photon, pi0, eta, b, b->c, c - // 21 possible DCA cuts XY - // 21 possible DCA cuts Z + // 8+? interested electron sources: others, photon conv, direct photon, pi0, eta, b, b->c, c + pion or missid, and missid pion + // 41 possible DCA cuts XY: // 13 pT bins // 10 rapidity bins // 10 azimuthal angle phi bins @@ -180,29 +192,36 @@ void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){ if(!displacedList) return; - fOutputList = displacedList; - fOutputList -> SetName("information"); + fDeOutputList = displacedList; + fDeOutputList -> SetName("displacedElectrons"); - // electron source - Int_t nBinsEleSource = 8; + Int_t nBinsEleSource = 10; Double_t minEleSource = -1.5; - Double_t maxEleSource = 6.5; + Double_t maxEleSource = 9.5; Double_t *binLimEleSource = new Double_t[nBinsEleSource+1]; for(Int_t i=0; i<=nBinsEleSource; i++) binLimEleSource[i] = minEleSource + i*(maxEleSource-minEleSource)/nBinsEleSource; - // dca bins: the same as XY and Z - // these should be variable bins as well - Int_t nBinsDca = kNDcaMin-1; // 12 bins - Double_t minDca = -0.5; - Double_t maxDca = 20.5; - Double_t dcaBinWidth = (maxDca-minDca)/nBinsDca; - Double_t *binLimDca = new Double_t[nBinsDca+1]; - for(Int_t i=0; i<=nBinsDca; i++) - binLimDca[i] = minDca + i*dcaBinWidth; + // dca bins: XY + Int_t nBinsDcaXY = kNDcaMin-1; // 41 bins + Double_t minDcaXY = -20.5; + Double_t maxDcaXY = 20.5; + Double_t dcaXYBinWidth = (maxDcaXY-minDcaXY)/nBinsDcaXY; + Double_t *binLimDcaXY = new Double_t[nBinsDcaXY+1]; + for(Int_t i=0; i<=nBinsDcaXY; i++) + binLimDcaXY[i] = minDcaXY + i*dcaXYBinWidth; + + + // dca bins: Z + Int_t nBinsDcaZ = kNDcaMin/2; // 21 bins + Double_t minDcaZ = -10.5; + Double_t maxDcaZ = 10.5; + Double_t dcaZBinWidth = (maxDcaZ-minDcaZ)/nBinsDcaZ; + Double_t *binLimDcaZ = new Double_t[nBinsDcaZ+1]; + for(Int_t i=0; i<=nBinsDcaZ; i++) + binLimDcaZ[i] = minDcaZ + i*dcaZBinWidth; - // pt bins Int_t nBinsPt = kNPtIntv-1; Double_t *binLimPt = new Double_t[nBinsPt+1]; @@ -226,140 +245,267 @@ void AliHFEdisplacedElectrons::CreateOutputs(TList* const displacedList){ binLimPhi[i] = minPhi + i*(maxPhi-minPhi)/nBinsPhi; + fTHnSparseDcaMcEleInfo = 0x0; + fTHnSparseDcaEsdEleInfo = 0x0; + fTHnSparseDcaDataEleInfo = 0x0; - //for MC pionss - const Int_t nVarPion = 5; - Int_t iBinPion[nVarPion] = {nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi}; - - // THnSparseF *fTHnSparseDcaMcPionInfo = NULL; // empty for the moment - if(HasMCData()){ - fTHnSparseDcaMcPionInfo = new THnSparseF("dcaMcPionInfo", - "MC info:;dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", - nVarPion, iBinPion); - fTHnSparseDcaMcPionInfo->SetBinEdges(0, binLimDca); // dca xy cut - fTHnSparseDcaMcPionInfo->SetBinEdges(1, binLimDca); // dca z cut - fTHnSparseDcaMcPionInfo->SetBinEdges(2, binLimPt); // pt - fTHnSparseDcaMcPionInfo->SetBinEdges(3, binLimRap); // rapidity - fTHnSparseDcaMcPionInfo->SetBinEdges(4, binLimPhi); // phi - fTHnSparseDcaMcPionInfo->Sumw2(); - - fOutputList -> AddAt(fTHnSparseDcaMcPionInfo, kMCpion); - } + // for MC only: MC electron ID + const Int_t nVarMc = 6; + Int_t iBinMc[nVarMc] = {nBinsEleSource, nBinsDcaXY, nBinsDcaZ, nBinsPt, nBinsRap, nBinsPhi}; + + fTHnSparseDcaMcEleInfo = new THnSparseF("dcaMcElectronInfo", + "MC electrons;electron source ID;mc dcaXY [50 #mum];mc dcaZ [100 #mum];mc pT [GeV/c];mc y [rapidity];mc #phi [rad];", + nVarMc, iBinMc); + fTHnSparseDcaMcEleInfo->SetBinEdges(0, binLimEleSource); // electron source + fTHnSparseDcaMcEleInfo->SetBinEdges(1, binLimDcaXY); // dca xy cut + fTHnSparseDcaMcEleInfo->SetBinEdges(2, binLimDcaZ); // dca z cut + fTHnSparseDcaMcEleInfo->SetBinEdges(3, binLimPt); // pt + fTHnSparseDcaMcEleInfo->SetBinEdges(4, binLimRap); // rapidity + fTHnSparseDcaMcEleInfo->SetBinEdges(5, binLimPhi); // phi + fTHnSparseDcaMcEleInfo->Sumw2(); + + // for ESD with MC: HFE pid and MC pid + const Int_t nVarEsd = 7; + Int_t iBin[nVarEsd] = {nBinsEleSource,nBinsDcaXY, nBinsDcaZ, nBinsDcaXY, nBinsPt, nBinsRap, nBinsPhi}; + + fTHnSparseDcaEsdEleInfo + = new THnSparseF("dcaEsdElectronInfo", + "ESD electrons;electron source ID;esd dcaXY [50 #mum];esd dcaZ [100 #mum];esd dcaXY KF [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", + nVarEsd, iBin); + + fTHnSparseDcaEsdEleInfo->SetBinEdges(0, binLimEleSource); // electron source + fTHnSparseDcaEsdEleInfo->SetBinEdges(1, binLimDcaXY); // dca xy without current track + fTHnSparseDcaEsdEleInfo->SetBinEdges(2, binLimDcaZ); // dca z without current track + fTHnSparseDcaEsdEleInfo->SetBinEdges(3, binLimDcaXY); // dca xy kf without current track + fTHnSparseDcaEsdEleInfo->SetBinEdges(4, binLimPt); // pt esd + fTHnSparseDcaEsdEleInfo->SetBinEdges(5, binLimRap); // rapidity esd + fTHnSparseDcaEsdEleInfo->SetBinEdges(6, binLimPhi); // phi esd + fTHnSparseDcaEsdEleInfo->Sumw2(); + + // for ESD data: HFE pid + const Int_t nVarData = 6; + Int_t iBinData[nVarData] = {nBinsDcaXY, nBinsDcaZ, nBinsDcaXY, nBinsPt, nBinsRap, nBinsPhi}; + + fTHnSparseDcaDataEleInfo + = new THnSparseF("dcaDataElectronInfo", + "Data electrons;dcaXY [50 #mum];dcaZ [100 #mum];dcaXYkf [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", + nVarData, iBinData); + fTHnSparseDcaDataEleInfo->SetBinEdges(0, binLimDcaXY); // dca xy cut w/o + fTHnSparseDcaDataEleInfo->SetBinEdges(1, binLimDcaZ); // dca z cut w/o + fTHnSparseDcaDataEleInfo->SetBinEdges(2, binLimDcaXY); // dca xy kf cut + fTHnSparseDcaDataEleInfo->SetBinEdges(3, binLimPt); // pt + fTHnSparseDcaDataEleInfo->SetBinEdges(4, binLimRap); // rapidity + fTHnSparseDcaDataEleInfo->SetBinEdges(5, binLimPhi); // phi + fTHnSparseDcaDataEleInfo->Sumw2(); - // for MC electrons - const Int_t nVar = 6; - Int_t iBin[nVar] = {nBinsEleSource,nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi}; - - // THnSparseF *fTHnSparseDcaMcEleInfo = NULL; // empty for the moment - if(HasMCData()){ - fTHnSparseDcaMcEleInfo = new THnSparseF("dcaMcElectronInfo", - "MC info:;ID [electron source id];dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", - nVar, iBin); - fTHnSparseDcaMcEleInfo->SetBinEdges(0, binLimEleSource); // electron source - fTHnSparseDcaMcEleInfo->SetBinEdges(1, binLimDca); // dca xy cut - fTHnSparseDcaMcEleInfo->SetBinEdges(2, binLimDca); // dca z cut - fTHnSparseDcaMcEleInfo->SetBinEdges(3, binLimPt); // pt - fTHnSparseDcaMcEleInfo->SetBinEdges(4, binLimRap); // rapidity - fTHnSparseDcaMcEleInfo->SetBinEdges(5, binLimPhi); // phi - fTHnSparseDcaMcEleInfo->Sumw2(); - fOutputList -> AddAt(fTHnSparseDcaMcEleInfo, kMCelectron); - } + fDeOutputList -> AddAt(fTHnSparseDcaMcEleInfo, kMcElectron); + fDeOutputList -> AddAt(fTHnSparseDcaEsdEleInfo, kEsdElectron); + fDeOutputList -> AddAt(fTHnSparseDcaDataEleInfo, kDataElectron); + + AliInfo("THnSparse histograms are created\n"); + fDeOutputList->Print(); + +} + +//__________________________________________________________ +void AliHFEdisplacedElectrons::FillMcOutput(AliESDEvent *const fESD, AliMCEvent* const fMC, AliMCParticle* const mctrack) +{ + + // fill output + //0. after mc event cut + //1. after checking stack, mcpart etc are valid + //2. after PID + //3. after event and track selection + + AliStack *stack = fMC->Stack(); + TParticle *part = mctrack->Particle(); + + // obtain impact parameters in xy and z + AliMCVertex *mcPrimVtx = (AliMCVertex *)fMC->GetPrimaryVertex(); + Double_t mcPrimV[3]; + mcPrimV[0] = mcPrimVtx->GetX(); + mcPrimV[1] = mcPrimVtx->GetY(); + mcPrimV[2] = mcPrimVtx->GetZ(); + + Double_t mcVtxXY = TMath::Abs(mcPrimV[0]*mcPrimV[0] + mcPrimV[1]*mcPrimV[1]); + + Float_t vx = part->Vx(); // in cm + Float_t vy = part->Vy(); // in cm + Float_t vz = part->Vz(); // in cm + + Float_t vxy = TMath::Sqrt(vx*vx+vy*vy); + + Float_t mcpx = part->Px(); + Float_t mcpy = part->Py(); + Float_t mcpt = TMath::Sqrt(mcpx*mcpx+mcpy*mcpy); + Float_t mceta = part->Eta(); + Float_t mcphi = part->Phi(); + + Int_t pdg = part->GetPdgCode(); + + Int_t charge = 1; + if(pdg==kPDGelectron || pdg==-kPDGpion) charge = -1; + + // calculate mcDca ------------------------------------------------------------------ + const Float_t conv[2] = {1.783/1.6, 2.99792458}; + Float_t magneticField = 0; // initialized as 5kG + magneticField = fESD->GetMagneticField(); // in kG + Float_t radiusMc = mcpt/(TMath::Abs(magneticField)/10.)*conv[0]*conv[1]; // pt in GeV/c, magnetic field in Tesla, radius in meter + + Float_t radius; + radius = TMath::Abs(radiusMc); + Float_t nx = mcpx/mcpt; + Float_t ny = mcpy/mcpt; + Double_t dxy = vxy - mcVtxXY; // in cm + Double_t dvx = vx - mcPrimV[0]; // in cm + Double_t dvy = vy - mcPrimV[1]; // in cm + Float_t mcDcaXYm = (radius - TMath::Sqrt(dxy*dxy/100./100. + radius*radius + 2*radius*charge*(dvx*ny-dvy*nx)/100.)) ; // in meters + Double_t mcDca[2] = {mcDcaXYm*100, vz}; // in cm + Double_t mcDcaXY = mcDca[0]*1.0e4; // conv dca in cm to dca in micron + Double_t mcDcaZ = mcDca[1]*1.0e4; + + const Int_t nvarMC=6; + Double_t var[nvarMC]; + var[0] = -1; - // for ESD: HFE pid + if(TMath::Abs(pdg)==kPDGelectron) { - // THnSparseF *fTHnSparseDcaDataEleInfo = NULL; // empty for the moment - const Int_t nVarData = 5; - Int_t iBinData[nVarData] = {nBinsDca, nBinsDca, nBinsPt, nBinsRap, nBinsPhi}; + Int_t eleLabel = mctrack->GetLabel(); + Int_t sourcePdg = ElectronFromSource(stack, eleLabel); + + if(sourcePdg==kPDGgamma){ // check direct photon or not + if(ElePhotonDirect(stack, eleLabel)!=-1) + var[0] = kEleDirectPhotonConv; + else + var[0] = kElePhotonConv; + if(fDeDebugLevel>=10) + printf("photonconv=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); + } // photon or direct photon -> e + + if(sourcePdg==kPDGpi0){ + var[0] = kElePi0; + if(fDeDebugLevel>=10) printf("pi0======this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); + } + + if(sourcePdg==kPDGeta){ + var[0] = kEleEta; + if(fDeDebugLevel>=10) + printf("eta=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); + } // from eta -> e + + if(TMath::Abs(sourcePdg%10000)/100==kPDGbeauty || // for special intermediate meson states: like 100553 + TMath::Abs(sourcePdg)/1000==kPDGbeauty || + TMath::Abs(sourcePdg)/100==kPDGbeauty || + TMath::Abs(sourcePdg)==kPDGbeauty){ + var[0]=kEleB; + if(fDeDebugLevel>=10) + printf("beauty======electron %d is from %d with id %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); + } // direct beauty -> e + if(TMath::Abs(sourcePdg%10000)/100==kPDGcharm || // for special intermediate meson states: like 1004** + TMath::Abs(sourcePdg)/1000==kPDGcharm || + TMath::Abs(sourcePdg)/100==kPDGcharm || + TMath::Abs(sourcePdg)==kPDGcharm){ + // two cases: + // electron from b->c->e + // electron from c->e + if(ElectronFromCharm(stack, eleLabel)!=-1){ + var[0] = ElectronFromCharm(stack, eleLabel); + if(fDeDebugLevel>=10) + printf("charm----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); + } + } // charm electrons: b->c->e or c->e + + if(fDeDebugLevel>=10) printf("others----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); + } // electron source endif - fTHnSparseDcaDataEleInfo = new THnSparseF("dcaDataElectronInfo", - "Data info:;dcaXY [50 #mum];dcaZ [50 #mum];pT [GeV/c];y [rapidity];#phi [rad];", - nVarData, iBinData); - fTHnSparseDcaDataEleInfo->SetBinEdges(0, binLimDca); // dca xy cut - fTHnSparseDcaDataEleInfo->SetBinEdges(1, binLimDca); // dca z cut - fTHnSparseDcaDataEleInfo->SetBinEdges(2, binLimPt); // pt - fTHnSparseDcaDataEleInfo->SetBinEdges(3, binLimRap); // rapidity - fTHnSparseDcaDataEleInfo->SetBinEdges(4, binLimPhi); // phi - fTHnSparseDcaDataEleInfo->Sumw2(); + else + if(TMath::Abs(pdg)==kPDGpion) + var[0] = kPion; - fOutputList -> AddAt(fTHnSparseDcaDataEleInfo, kData); + if(TMath::Abs(mcDcaXY)<1000) var[1] = Int_t(mcDcaXY)/50; // larger than 1mm should go to the last bin + else + var[1] = ((mcDcaXY>0)?1:-1)*20; - AliInfo("THnSparse histograms are created\n"); - fOutputList->Print(); + if(TMath::Abs(mcDcaZ)<1000) var[2] = Int_t(mcDcaZ)/100; + else + var[2] = ((mcDcaZ>0)?1:-1)*10; + + var[3] = mcpt; // pt + var[4] = mceta; // eta + var[5] = mcphi; // phi + (dynamic_cast(fDeOutputList->At(kMcElectron)))->Fill(var); } + //__________________________________________________________ -void AliHFEdisplacedElectrons::FillMCOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack, AliStack * const stack) +void AliHFEdisplacedElectrons::FillEsdOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack, AliStack * const stack) { + // after esd event selection, esd track cuts, and hfe pid + // this is the case for ESD tracks, with MC information - // fill output - if(!esdTrack) return; AliESDtrack *track = esdTrack; Double_t pt = track->Pt(); Double_t eta = track->Eta(); Double_t phi = track->Phi(); - Int_t label = track->GetLabel(); - if(label<0 || label>stack->GetNtrack()) return; + Int_t eleLabel = track->GetLabel(); + if(eleLabel<0 || eleLabel>stack->GetNtrack()) return; - TParticle *particle = stack->Particle(label); + TParticle *particle = stack->Particle(eleLabel); if(!particle) return; - - - // obtain impact parameters in xy and y - const AliESDVertex *primVtx = fESDEvent->GetPrimaryVertex(); + // obtain impact parameters in xy and z + Float_t magneticField = 5; // initialized as 5kG magneticField = fESDEvent->GetMagneticField(); // in kG - - - Double_t dz[2]; // error of dca in cm - Double_t covardz[3]; - track->PropagateToDCA(primVtx,magneticField, 1000., dz, covardz); - + Double_t beampiperadius=3.; + const AliESDVertex *primVtx = fESDEvent->GetPrimaryVertex(); - Double_t dcaXY = TMath::Abs(dz[0])*1.0e4; // conv dca in cm to dca in micron - Double_t dcaZ = TMath::Abs(dz[1])*1.0e4; + + const Int_t nvarESD = 7; + Double_t var[nvarESD]; + var[0] = -1; - // do PID with MC + Int_t sourcePdg = -1; - if(HasMCData() && TMath::Abs(GetMCpid(stack, label))==kPDGelectron){ + if(TMath::Abs(particle->GetPdgCode())!=kPDGelectron) + if(TMath::Abs(particle->GetPdgCode())!=kPDGpion) + var[0] = kEleMissID; + else + var[0] = kEleMissIDpion; - Int_t eleLabel = label; + else { + sourcePdg = ElectronFromSource(stack, eleLabel); - const Int_t nvarMC=6; - Double_t var[nvarMC]; - var[0] = -1; - Int_t sourcePdg = ElectronFromSource(stack, eleLabel); - - if(sourcePdg==kPDGgamma){ // check direct photon or not // fixme + if(sourcePdg==kPDGgamma){ // check direct photon or not if(ElePhotonDirect(stack, eleLabel)!=-1) var[0] = kEleDirectPhotonConv; else var[0] = kElePhotonConv; - if(fDebugLevel>=10) + if(fDeDebugLevel>=10) printf("photonconv=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); } // photon or direct photon -> e if(sourcePdg==kPDGpi0){ var[0] = kElePi0; - if(fDebugLevel>=10) printf("pi0======this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); + if(fDeDebugLevel>=10) printf("pi0======this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); } - + if(sourcePdg==kPDGeta){ var[0] = kEleEta; - if(fDebugLevel>=10) + if(fDeDebugLevel>=10) printf("eta=====this electron %d is from %d, source id=%.1f\n", eleLabel, sourcePdg, var[0]); } // from eta -> e - + if(TMath::Abs(sourcePdg%10000)/100==kPDGbeauty || // for special intermediate meson states: like 100553 TMath::Abs(sourcePdg)/1000==kPDGbeauty || TMath::Abs(sourcePdg)/100==kPDGbeauty || TMath::Abs(sourcePdg)==kPDGbeauty){ var[0]=kEleB; - if(fDebugLevel>=10) + if(fDeDebugLevel>=10) printf("beauty======electron %d is from %d with id %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); } // direct beauty -> e if(TMath::Abs(sourcePdg%10000)/100==kPDGcharm || // for special intermediate meson states: like 1004** @@ -371,61 +517,87 @@ void AliHFEdisplacedElectrons::FillMCOutput(AliESDEvent * const fESDEvent, AliES // electron from c->e if(ElectronFromCharm(stack, eleLabel)!=-1){ var[0] = ElectronFromCharm(stack, eleLabel); - if(fDebugLevel>=10) + if(fDeDebugLevel>=10) printf("charm----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); } } // charm electrons: b->c->e or c->e - - if(fDebugLevel>=10) printf("others----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); - - if(dcaXY<1000) var[1] = Int_t(dcaXY)/50; // larger than 1mm should go to the last bin - else - var[1] = 20; - if(dcaZ<1000) var[2] = Int_t(dcaZ)/50; - else - var[2] = 20; - - var[3] = pt; // pt - var[4] = eta; // eta - var[5] = phi; // phi - - (dynamic_cast(fOutputList->At(kMCelectron)))->Fill(var); - } - - if(HasMCData() && TMath::Abs(GetMCpid(stack, label))==kPDGpion){ - - const Int_t nvarPionMC=5; - Double_t varPion[nvarPionMC]; - if(dcaXY<1000) - varPion[0] = Int_t(dcaXY)/50; // dca xy - else - varPion[0] = 20; - if(dcaZ<1000) - varPion[1] = Int_t(dcaZ)/50; // dca Z - else - varPion[1] = 20; - -// varPion[0] = TMath::Abs(dcaXY); // dca xy -// varPion[1] = TMath::Abs(dcaZ); // dca z - varPion[2] = pt; // pt - varPion[3] = eta; //eta - varPion[4] = phi; // phi + } // correct pid - (dynamic_cast(fOutputList->At(kMCpion)))->Fill(varPion); + // excluding current track + // ---- beginning --- method from Andrea D 28.05.2010 + AliVertexerTracks *vertexer = new AliVertexerTracks(magneticField); + vertexer->SetITSMode(); + vertexer->SetMinClusters(fNclustersITS); + Int_t skipped[2]; + skipped[0] = (Int_t)track->GetID(); + vertexer->SetSkipTracks(1,skipped); + AliESDVertex *vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESDEvent); + delete vertexer; vertexer = NULL; + if(vtxESDSkip->GetNContributors()PropagateToDCA(vtxESDSkip,magneticField, beampiperadius, dz, covardz)) return; // protection + + Double_t dcaXY = dz[0]*1.0e4; // conv dca in cm to dca in micron + Double_t dcaZ = dz[1]*1.0e4; + + if(fDeDebugLevel>=10) printf("others----->electron %d has mother %d is from %.1f\n", eleLabel, ElectronFromSource(stack, eleLabel), var[0]); + + if(TMath::Abs(dcaXY)<1000) var[1] = Int_t(dcaXY)/50; // larger than 1mm should go to the last bin + else + var[1] = ((dcaXY>0)?1:-1)*20; + + if(TMath::Abs(dcaZ)<1000) var[2] = Int_t(dcaZ)/100; + else + var[2] = ((dcaZ>0)?1:-1)*10; + + // calculate dca using AliKFParticle class------------------------------------------------------------------ + Float_t kfDcaXY = 0; + Int_t trkID = track->GetID(); + AliKFParticle::SetField(magneticField); + AliKFParticle kfParticle(*track, particle->GetPdgCode()); + // prepare kfprimary vertex + AliKFVertex kfESDprimary; + // Reconstruct Primary Vertex (with ESD tracks) + Int_t n=primVtx->GetNIndices(); + if (n>0 && primVtx->GetStatus()){ + kfESDprimary = AliKFVertex(*primVtx); + UShort_t *priIndex = primVtx->GetIndices(); + for (Int_t i=0;i0?1:-1)*20; + + var[4] = pt; // pt + var[5] = eta; // eta + var[6] = phi; // phi + + (dynamic_cast(fDeOutputList->At(kEsdElectron)))->Fill(var); } - - //__________________________________________________________ -void AliHFEdisplacedElectrons::FillESDOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack) +void AliHFEdisplacedElectrons::FillDataOutput(AliESDEvent * const fESDEvent, AliESDtrack* const esdTrack) { + + // this is pure data, without MC information at all + // fill output: with HFE pid selection of electrons after all track quality cuts - // fill output if(!esdTrack) return; AliESDtrack *track = esdTrack; - + Double_t pt = track->Pt(); Double_t eta = track->Eta(); Double_t phi = track->Phi(); @@ -435,30 +607,75 @@ void AliHFEdisplacedElectrons::FillESDOutput(AliESDEvent * const fESDEvent, AliE Float_t magneticField = 5; // initialized as 5kG magneticField = fESDEvent->GetMagneticField(); // in kG + Double_t beampiperadius=3.; + + + const Int_t nvarData = 6; + Double_t varData[nvarData]; + + // + // excluding current track + // + + //------ beginning --- method from Andrea D 28.05.2010 + AliVertexerTracks *vertexer = new AliVertexerTracks(fESDEvent->GetMagneticField()); + vertexer->SetITSMode(); + vertexer->SetMinClusters(fNclustersITS); + Int_t skipped[2]; + skipped[0] = (Int_t)track->GetID(); + vertexer->SetSkipTracks(1,skipped); + AliESDVertex *vtxESDSkip = (AliESDVertex*)vertexer->FindPrimaryVertex(fESDEvent); + delete vertexer; vertexer = NULL; + if(vtxESDSkip->GetNContributors()PropagateToDCA(primVtx,magneticField, 1000., dz, covardz); - Double_t dcaXY = TMath::Abs(dz[0]*1.0e4); // conv dca in cm to dca in micron - Double_t dcaZ = TMath::Abs(dz[1]*1.0e4); - + + if(!track->PropagateToDCA(vtxESDSkip,magneticField, beampiperadius, dz, covardz)) return; // protection - const Int_t nvarData = 5; - Double_t varData[nvarData]; - // fixme - if(dcaXY<1000) - varData[0] = Int_t(dcaXY)/50; // dca xy - else - varData[0] = 20; - if(dcaZ<1000) - varData[1] = Int_t(dcaZ)/50; // dca Z + Double_t dcaXY = dz[0]*1.0e4; // conv dca in cm to dca in micron + Double_t dcaZ = dz[1]*1.0e4; + + if(TMath::Abs(dcaXY)<1000) varData[0] = Int_t(dcaXY)/50; // larger than 1mm should go to the last bin + else + varData[0] = (dcaXY>0?1:-1)*20; + if(TMath::Abs(dcaZ)<1000) varData[1] = Int_t(dcaZ)/100; + else + varData[1] = (dcaZ>0?1:-1)*10; + + + // calculate dca using AliKFParticle class------------------------------------------------------------------ + Float_t kfDcaXY = 0; + Int_t trkID = track->GetID(); + AliKFParticle::SetField(magneticField); + AliKFParticle kfParticle(*track, -11*track->Charge()); + // prepare kfprimary vertex + AliKFVertex kfESDprimary; + // Reconstruct Primary Vertex (with ESD tracks) + Int_t n=primVtx->GetNIndices(); + if (n>0 && primVtx->GetStatus()){ + kfESDprimary = AliKFVertex(*primVtx); + UShort_t *priIndex = primVtx->GetIndices(); + for (Int_t i=0;i0?1:-1)*20; + // end of KF dca - varData[2] = pt; // pt - varData[3] = eta; //eta - varData[4] = phi; // phi + varData[3] = pt; // pt + varData[4] = eta; //eta + varData[5] = phi; // phi - (dynamic_cast(fOutputList->At(kData)))->Fill(varData); + (dynamic_cast(fDeOutputList->At(kDataElectron)))->Fill(varData); } @@ -487,7 +704,7 @@ Int_t AliHFEdisplacedElectrons::ElectronFromSource(AliStack * const stack, Int_t Int_t pdgCode = TMath::Abs(motherPart->GetPdgCode()); if(pdgCode==kPDGelectron) { - if(fDebugLevel>=10) printf("particle label: %d...(motherLabel=%d : motherPdg=%d) grandmother's pdg code was returned...%d \n", + if(fDeDebugLevel>=10) printf("particle label: %d...(motherLabel=%d : motherPdg=%d) grandmother's pdg code was returned...%d \n", label, motherLabel, pdgCode, ElectronFromSource(stack, motherLabel)); return ElectronFromSource(stack, motherLabel); } @@ -515,7 +732,7 @@ Int_t AliHFEdisplacedElectrons::ElectronFromCharm(AliStack * const stack, Int_t Int_t pdgCode = gMotherPart->GetPdgCode(); if(TMath::Abs(pdgCode%10000)/100==kPDGbeauty || // for special intermediate meson states: like 100553 TMath::Abs(pdgCode)/1000==kPDGbeauty || TMath::Abs(pdgCode)/100==kPDGbeauty || TMath::Abs(pdgCode)==kPDGbeauty) { - if(fDebugLevel>=10) printf("this electron label %d is from mother %d, and finally from %d\n", label, ElectronFromSource(stack, label), pdgCode); + if(fDeDebugLevel>=10) printf("this electron label %d is from mother %d, and finally from %d\n", label, ElectronFromSource(stack, label), pdgCode); return kEleBC; } // for sure it is from BC diff --git a/PWG3/hfe/AliHFEdisplacedElectrons.h b/PWG3/hfe/AliHFEdisplacedElectrons.h index 8ab69284024..cba6f1e0272 100644 --- a/PWG3/hfe/AliHFEdisplacedElectrons.h +++ b/PWG3/hfe/AliHFEdisplacedElectrons.h @@ -18,7 +18,8 @@ // by DCA cuts, background subtraction // // Authors: -// Hongyan Yang +// Hongyan Yang +// Carlo Bombonati // #ifndef ALIHFEDISPLACEDELECTRONS_H @@ -49,6 +50,7 @@ class TObjArray; class AliStack; class AliMCEvent; class AliESDEvent; +class AliVEvent; class AliESDtrack; class AliESDVertex; @@ -76,14 +78,17 @@ class AliHFEdisplacedElectrons : public TObject{ void InitAnalysis(); void CreateOutputs(TList* const displacedList); - void FillMCOutput(AliESDEvent* fESDEvent, AliESDtrack *track, AliStack *stack); - void FillESDOutput(AliESDEvent* fESDEvent, AliESDtrack *track); + void FillMcOutput(AliESDEvent* fESD, AliMCEvent* fMC, AliMCParticle* mctrack); + void FillEsdOutput(AliESDEvent* fESDEvent, AliESDtrack *track, AliStack *stack); + void FillDataOutput(AliESDEvent* fESDEvent, AliESDtrack *track); Int_t GetMCpid(AliStack* stack, Int_t label) const; Bool_t HasMCData() const { return TestBit(kHasMCData); }; void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); }; - void SetDebugLevel(Int_t debugLevel){ fDebugLevel = debugLevel; }; + void SetDebugLevel(Int_t debugLevel){ fDeDebugLevel = debugLevel; }; + void SetNitsCluster(Int_t nITScls){ fNclustersITS = nITScls;}; + void SetMinPrimVtxContrib(Int_t nContrib){fMinNprimVtxContributor = nContrib;}; void PostAnalysis() const; @@ -104,23 +109,25 @@ class AliHFEdisplacedElectrons : public TObject{ kEleEta = 3, kEleB = 4, kEleC = 5, - kEleBC = 6 + kEleBC = 6, + kEleMissID = 7, + kEleMissIDpion = 8, + kPion = 8 }; // electron source index enum{ - kMCpion = 0, - kMCelectron = 1, - kData = 2 + kMcElectron = 0, + kEsdElectron = 1, + kDataElectron = 2 }; // MC or Data enum{ - kNDcaMin = 21, + kNDcaMin = 42, kNPtIntv = 14, kNKineVar = 3 }; // several constant to be used - UInt_t fDebugLevel; // debug level - + Int_t ElectronFromSource(AliStack *stack, Int_t eleLabel) const; Int_t ElePhotonDirect(AliStack *stack, Int_t label) const; Int_t ElectronFromCharm(AliStack *stack, Int_t eleLabel) const; @@ -136,12 +143,16 @@ class AliHFEdisplacedElectrons : public TObject{ static const Char_t *fgkKineVar[kNKineVar]; // particle names static const Char_t *fgkKineVarTitle[kNKineVar]; // particle names + + UInt_t fDeDebugLevel; // debug level + Int_t fNclustersITS; // ITS clusters + Int_t fMinNprimVtxContributor; // minimum number of contributors to the primary vtx - THnSparseF *fTHnSparseDcaMcPionInfo; //! container for MC pion part - THnSparseF *fTHnSparseDcaMcEleInfo; //! container for MC electron part + THnSparseF *fTHnSparseDcaMcEleInfo; //! container for MC pion part + THnSparseF *fTHnSparseDcaEsdEleInfo; //! container for MC electron part THnSparseF *fTHnSparseDcaDataEleInfo; //! container for Data electron part - TList *fOutputList; //! output container + TList *fDeOutputList; //! output container ClassDef(AliHFEdisplacedElectrons, 0); }; diff --git a/PWG3/hfe/AliHFEefficiency.cxx b/PWG3/hfe/AliHFEefficiency.cxx index fac7f61e004..d12813349ac 100644 --- a/PWG3/hfe/AliHFEefficiency.cxx +++ b/PWG3/hfe/AliHFEefficiency.cxx @@ -77,6 +77,8 @@ AliHFEefficiency::AliHFEefficiency(const Char_t *name): // DefineOutput(1, AliHFEcontainer::Class()); DefineOutput(2, TList::Class()); + + SetRunTerminate(); } AliHFEefficiency::~AliHFEefficiency(){ @@ -136,13 +138,11 @@ void AliHFEefficiency::UserCreateOutputObjects(){ // create additional histos for testing purpose fOutput = new AliHFEcollection("histos", "QA histograms"); fOutput->CreateTH1F("hNtracks","Number of Tracks per Event", 100, 0, 100); - fOutput->CreateTH1F("hPt","Pt of the tracks", 40, 0.1, 10); - fOutput->BinLogAxis("hPt", 0); + fOutput->CreateTH1F("hPt","Pt of the tracks", 40, 0.1, 10, 0); fOutput->CreateTH1F("kinkIndex", "Kink Index", 400, -200, 200); fOutput->CreateTH1F("itspixel", "ITS PIXEL", 2, 0, 2); fOutput->CreateTH1F("mcmother", "Mother PDG", 1000, -500, 500); - fOutput->CreateTH2F("ptres", "Pt Resolution", 40, 0.1, 10, 200, -1.5, 1.5); - fOutput->BinLogAxis("ptres", 0); + fOutput->CreateTH2F("ptres", "Pt Resolution", 40, 0.1, 10, 200, -1.5, 1.5, 0); } void AliHFEefficiency::UserExec(Option_t *){ @@ -172,14 +172,16 @@ void AliHFEefficiency::UserExec(Option_t *){ fOutput->Fill("itspixel",1); else fOutput->Fill("itspixel",0); - AliMCParticle *mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))); - if(mctrack){ - Int_t motherLabel = mctrack->Particle()->GetFirstMother(); - if(motherLabel){ - AliMCParticle *mother = dynamic_cast(fMCEvent->GetTrack(motherLabel)); - fOutput->Fill("mcmother", mother->Particle()->GetPdgCode()); + if(fMCEvent){ + AliMCParticle *mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))); + if(mctrack){ + Int_t motherLabel = mctrack->Particle()->GetFirstMother(); + if(motherLabel){ + AliMCParticle *mother = dynamic_cast(fMCEvent->GetTrack(motherLabel)); + if(mother)fOutput->Fill("mcmother", mother->Particle()->GetPdgCode()); + } + fOutput->Fill("ptres", mctrack->Pt(), (track->Pt() - mctrack->Pt())/mctrack->Pt()); } - fOutput->Fill("ptres", mctrack->Pt(), (track->Pt() - mctrack->Pt())/mctrack->Pt()); } } delete iter; @@ -193,7 +195,12 @@ void AliHFEefficiency::Terminate(Option_t *){ // Evaluate Results // fEfficiency = dynamic_cast(GetOutputData(1)); - if(!fEfficiency) return; + if(!fEfficiency){ + AliError("No Output data available"); + return; + } + + if(!IsRunningTerminate()) return; PostProcess(); TList *l = dynamic_cast(GetOutputData(2)); diff --git a/PWG3/hfe/AliHFEefficiency.h b/PWG3/hfe/AliHFEefficiency.h index 6de24e3d225..6de6d7eff23 100644 --- a/PWG3/hfe/AliHFEefficiency.h +++ b/PWG3/hfe/AliHFEefficiency.h @@ -49,6 +49,8 @@ class AliHFEefficiency : public AliAnalysisTaskSE{ void Load(const char* filename = "EffTask.root"); void PostProcess(); + Bool_t IsRunningTerminate() const { return TestBit(kTerminate); } + void SetRunTerminate(Bool_t terminate = kTRUE) { SetBit(kTerminate, terminate); } void CalculatePTsmearing(); void DrawPtResolution(TList *l); @@ -58,6 +60,9 @@ class AliHFEefficiency : public AliAnalysisTaskSE{ kNTracks, kPt }; + enum{ // Bit Definition + kTerminate = BIT(18) + }; AliHFEefficiency(const AliHFEefficiency &); AliHFEefficiency &operator=(const AliHFEefficiency &); void DrawSignalEfficiency(AliCFEffGrid *eff, AliCFContainer *cont, Int_t var); diff --git a/PWG3/hfe/AliHFEelecbackground.cxx b/PWG3/hfe/AliHFEelecbackground.cxx index a6d887b82c7..baa05f5c67e 100644 --- a/PWG3/hfe/AliHFEelecbackground.cxx +++ b/PWG3/hfe/AliHFEelecbackground.cxx @@ -1064,7 +1064,7 @@ Bool_t AliHFEelecbackground::SingleTrackCut(AliESDtrack* const trackPart) const //////////////////// if(fRequireITSStandalone==1) { - if(((status & AliESDtrack::kITSin) == 0 || (trackPart->IsPureITSStandalone()) || ((status&AliESDtrack::kITSrefit) ==0))) return kFALSE; + if(((status & AliESDtrack::kITSin) == 0 || (trackPart->IsPureITSStandalone()) || ((status&AliESDtrack::kITSrefit)==0))) return kFALSE; } if(fRequireITSStandalone==2) { diff --git a/PWG3/hfe/AliHFEmcQA.cxx b/PWG3/hfe/AliHFEmcQA.cxx index b430e5b9cc4..a9ed852b673 100644 --- a/PWG3/hfe/AliHFEmcQA.cxx +++ b/PWG3/hfe/AliHFEmcQA.cxx @@ -34,7 +34,7 @@ #include #include -#include +#include #include #include @@ -50,7 +50,7 @@ ClassImp(AliHFEmcQA) //_______________________________________________________________________________________________ AliHFEmcQA::AliHFEmcQA() : - fStack(NULL) + fMCEvent(NULL) ,fMCHeader(NULL) ,fMCArray(NULL) ,fQAhistos(NULL) @@ -63,7 +63,7 @@ AliHFEmcQA::AliHFEmcQA() : //_______________________________________________________________________________________________ AliHFEmcQA::AliHFEmcQA(const AliHFEmcQA&p): TObject(p) - ,fStack(NULL) + ,fMCEvent(NULL) ,fMCHeader(NULL) ,fMCArray(NULL) ,fQAhistos(p.fQAhistos) @@ -100,7 +100,7 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt) { // create histograms - if (kquark != kCharm && kquark != kBeauty) { + if (!(kquark == kCharm || kquark == kBeauty || kquark == kOthers)) { AliDebug(1, "This task is only for heavy quark QA, return\n"); return; } @@ -123,16 +123,42 @@ void AliHFEmcQA::CreateHistograms(const Int_t kquark, Int_t icut, TString hnopt) kqTypeLabel[kDeHadron]="bDeHadron"; kqTypeLabel[kElectron]="be"; kqTypeLabel[kElectron2nd]="bce"; + } else if (kquark == kOthers){ + kqTypeLabel[kGamma-4]="gammae"; + kqTypeLabel[kPi0-4]="pi0e"; + kqTypeLabel[kElse-4]="elsee"; + kqTypeLabel[kMisID-4]="miside"; } - - +/* + const Double_t kPtbound[2] = {0.001, 50.}; + Int_t iBin[1]; + iBin[0] = 100; // bins in pt + Double_t* binEdges[1]; + binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]); + */ + TString hname; + if(kquark == kOthers){ + for (Int_t iqType = 0; iqType < 4; iqType++ ){ + hname = hnopt+"Pt_"+kqTypeLabel[iqType]; + //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]); + fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50); + hname = hnopt+"Y_"+kqTypeLabel[iqType]; + fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5); + hname = hnopt+"Eta_"+kqTypeLabel[iqType]; + fHist[iq][iqType][icut].fEta = new TH1F(hname,hname,150,-7.5,7.5); + // Fill List + if(fQAhistos) fHist[iq][iqType][icut].FillList(fQAhistos); + } + return; + } for (Int_t iqType = 0; iqType < fgkqType; iqType++ ){ if (iqType < keHadron && icut > 0) continue; // don't duplicate histogram for quark and hadron hname = hnopt+"PdgCode_"+kqTypeLabel[iqType]; fHist[iq][iqType][icut].fPdgCode = new TH1F(hname,hname,20001,-10000.5,10000.5); hname = hnopt+"Pt_"+kqTypeLabel[iqType]; - fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",250,0,50); + //fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",iBin[0],binEdges[0]); + fHist[iq][iqType][icut].fPt = new TH1F(hname,hname+";p_{T} (GeV/c)",500,0,50); hname = hnopt+"Y_"+kqTypeLabel[iqType]; fHist[iq][iqType][icut].fY = new TH1F(hname,hname,150,-7.5,7.5); hname = hnopt+"Eta_"+kqTypeLabel[iqType]; @@ -198,12 +224,12 @@ void AliHFEmcQA::GetQuarkKine(TParticle *part, Int_t iTrack, const Int_t kquark) } Int_t iq = kquark - kCharm; - if (iTrack < 0) { - AliDebug(1, "Stack label is negative, return\n"); + if (iTrack < 0 || !part) { + AliDebug(1, "Stack label is negative or no mcparticle, return\n"); return; } - //TParticle *part = fStack->Particle(iTrack); + AliMCParticle *mctrack = NULL; Int_t partPdgcode = TMath::Abs(part->GetPdgCode()); // select heavy hadron or not fragmented heavy quark @@ -217,7 +243,8 @@ void AliHFEmcQA::GetQuarkKine(TParticle *part, Int_t iTrack, const Int_t kquark) iLabel = iTrack; } else{ // in case of heavy hadron, start to search for mother heavy parton iLabel = part->GetFirstMother(); - if (iLabel>-1) { partMother = fStack->Particle(iLabel); } + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return; + if (iLabel>-1) { partMother = mctrack->Particle(); } else { AliDebug(1, "Stack label is negative, return\n"); return; @@ -236,7 +263,8 @@ void AliHFEmcQA::GetQuarkKine(TParticle *part, Int_t iTrack, const Int_t kquark) Bool_t isSameString = kTRUE; for (Int_t i=1; i-1) { partMother = fStack->Particle(iLabel); } + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return; + if (iLabel>-1) { partMother = mctrack->Particle(); } else { AliDebug(1, "Stack label is negative, return\n"); return; @@ -391,7 +419,10 @@ void AliHFEmcQA::GetHadronKine(TParticle* mcpart, const Int_t kquark) } Int_t iq = kquark - kCharm; - //TParticle* mcpart = fStack->Particle(iTrack); + if(!mcpart){ + AliDebug(1, "no mc particle, return\n"); + return; + } Int_t iLabel = mcpart->GetFirstMother(); if (iLabel<0){ @@ -403,6 +434,8 @@ void AliHFEmcQA::GetHadronKine(TParticle* mcpart, const Int_t kquark) Int_t pdgcode = mcpart->GetPdgCode(); Int_t pdgcodeCopy = pdgcode; + AliMCParticle *mctrack = NULL; + // if the mother is charmed hadron Bool_t isDirectCharm = kFALSE; if ( int(abs(pdgcode)/100.) == kCharm || int(abs(pdgcode)/1000.) == kCharm ) { @@ -420,7 +453,8 @@ void AliHFEmcQA::GetHadronKine(TParticle* mcpart, const Int_t kquark) return; } // if there is an ancester - TParticle* mother = fStack->Particle(jLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return; + TParticle* mother = mctrack->Particle(); Int_t motherPDG = mother->GetPdgCode(); for (Int_t j=0; jParticle(iTrack); + if(kquark==kOthers){ + Int_t esource = -1; + if ( abs(mcpart->GetPdgCode()) != kdecayed ) esource = kMisID-4; + else esource =GetSource(mcpart)-4; // return for the cases kGamma=4, kPi0=5, kElse=6 + if(esource==0|| esource==1 || esource==2 || esource==3){ + fHist[iq][esource][icut].fPt->Fill(mcpart->Pt()); + fHist[iq][esource][icut].fY->Fill(AliHFEtools::GetRapidity(mcpart)); + fHist[iq][esource][icut].fEta->Fill(mcpart->Eta()); + return; + } + else { + AliDebug(1, "e source is out of defined ranges, return\n"); + return; + } + } if ( abs(mcpart->GetPdgCode()) != kdecayed ) return; @@ -474,12 +520,15 @@ void AliHFEmcQA::GetDecayedKine(TParticle* mcpart, const Int_t kquark, Int_t kde return; } - TParticle *partMother = fStack->Particle(iLabel); + AliMCParticle *mctrack = NULL; + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return; + TParticle *partMother = mctrack->Particle(); TParticle *partMotherCopy = partMother; Int_t maPdgcode = partMother->GetPdgCode(); Int_t maPdgcodeCopy = maPdgcode; // get mc primary vertex + /* TArrayF mcPrimVtx; if(fMCHeader) fMCHeader->PrimaryVertex(mcPrimVtx); @@ -489,6 +538,8 @@ void AliHFEmcQA::GetDecayedKine(TParticle* mcpart, const Int_t kquark, Int_t kde // calculated production vertex to primary vertex (in xy plane) Float_t decayLxy = TMath::Sqrt((mcPrimVtx[0]-ePoint[0])*(mcPrimVtx[0]-ePoint[0])+(mcPrimVtx[1]-ePoint[1])*(mcPrimVtx[1]-ePoint[1])); + */ + Float_t decayLxy = 0; // if the mother is charmed hadron Bool_t isMotherDirectCharm = kFALSE; @@ -515,7 +566,8 @@ void AliHFEmcQA::GetDecayedKine(TParticle* mcpart, const Int_t kquark, Int_t kde } // if there is an ancester - TParticle* grandMa = fStack->Particle(jLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return; + TParticle* grandMa = mctrack->Particle(); Int_t grandMaPDG = grandMa->GetPdgCode(); for (Int_t j=0; jGetPdgCode()) != kdecayed ) return; // mother @@ -679,7 +736,9 @@ void AliHFEmcQA::IdentifyMother(Int_t motherlabel, Int_t &motherpdg, Int_t &gran AliDebug(1, "Stack label is negative, return\n"); return; } - TParticle *heavysMother = fStack->Particle(motherlabel); + AliMCParticle *mctrack = NULL; + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(motherlabel))))) return; + TParticle *heavysMother = mctrack->Particle(); motherpdg = heavysMother->GetPdgCode(); grandmotherlabel = heavysMother->GetFirstMother(); AliDebug(1,Form("ancestor pdg code= %d\n",motherpdg)); @@ -690,8 +749,12 @@ void AliHFEmcQA::HardScattering(const Int_t kquark, Int_t &motherID, Int_t &moth { // mothertype -1 means this heavy quark coming from hard vertex - TParticle *afterinitialrad1 = fStack->Particle(4); - TParticle *afterinitialrad2 = fStack->Particle(5); + AliMCParticle *mctrack1 = NULL; + AliMCParticle *mctrack2 = NULL; + if(!(mctrack1 = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(4))))) return; + if(!(mctrack2 = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(5))))) return; + TParticle *afterinitialrad1 = mctrack1->Particle(); + TParticle *afterinitialrad2 = mctrack2->Particle(); motherlabel = -1; @@ -723,8 +786,10 @@ Bool_t AliHFEmcQA::IsFromInitialShower(Int_t inputmotherlabel, Int_t &motherID, { // mothertype -2 means this heavy quark coming from initial state + AliMCParticle *mctrack = NULL; if (inputmotherlabel==2 || inputmotherlabel==3){ // mother exist before initial state radiation - TParticle *heavysMother = fStack->Particle(inputmotherlabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(inputmotherlabel))))) return kFALSE; + TParticle *heavysMother = mctrack->Particle(); motherID = heavysMother->GetPdgCode(); mothertype = -2; // there is mother before initial state radiation motherlabel = inputmotherlabel; @@ -741,8 +806,10 @@ Bool_t AliHFEmcQA::IsFromFinalParton(Int_t inputmotherlabel, Int_t &motherID, In { // mothertype 2 means this heavy quark coming from final state + AliMCParticle *mctrack = NULL; if (inputmotherlabel > 5){ // mother exist after hard scattering - TParticle *heavysMother = fStack->Particle(inputmotherlabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(inputmotherlabel))))) return kFALSE; + TParticle *heavysMother = mctrack->Particle(); motherID = heavysMother->GetPdgCode(); mothertype = 2; // motherlabel = inputmotherlabel; @@ -774,6 +841,11 @@ Int_t AliHFEmcQA::GetSource(AliAODMCParticle * const mcpart) Int_t origin = -1; Bool_t isFinalOpenCharm = kFALSE; + if(!mcpart){ + AliDebug(1, "Stack label is negative or no mcparticle, return\n"); + return -1; + } + // mother Int_t iLabel = mcpart->GetMother(); if (iLabel<0){ @@ -851,13 +923,20 @@ Int_t AliHFEmcQA::GetSource(TParticle * const mcpart) Int_t origin = -1; Bool_t isFinalOpenCharm = kFALSE; + if(!mcpart){ + AliDebug(1, "no mcparticle, return\n"); + return -1; + } + Int_t iLabel = mcpart->GetFirstMother(); if (iLabel<0){ AliDebug(1, "Stack label is negative, return\n"); return -1; } - TParticle *partMother = fStack->Particle(iLabel); + AliMCParticle *mctrack = NULL; + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return -1; + TParticle *partMother = mctrack->Particle(); Int_t maPdgcode = partMother->GetPdgCode(); // if the mother is charmed hadron @@ -884,7 +963,8 @@ Int_t AliHFEmcQA::GetSource(TParticle * const mcpart) } // if there is an ancester - TParticle* grandMa = fStack->Particle(jLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1; + TParticle* grandMa = mctrack->Particle(); Int_t grandMaPDG = grandMa->GetPdgCode(); for (Int_t j=0; j #include +#include #include #include #include @@ -31,6 +32,7 @@ #include #include +#include "AliESDpid.h" #include "AliESDtrack.h" #include "AliLog.h" #include "AliPID.h" @@ -50,13 +52,13 @@ AliHFEpid::AliHFEpid(): fEnabledDetectors(0), fPIDstrategy(0), fQAlist(0x0), - fDebugLevel(0) + fDebugLevel(0), + fCommonObjects(NULL) { // // Default constructor // memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID); - memset(fTPCBetheBlochParameters, 0, sizeof(Double_t) * 5); } //____________________________________________________________ @@ -65,13 +67,13 @@ AliHFEpid::AliHFEpid(const AliHFEpid &c): fEnabledDetectors(c.fEnabledDetectors), fPIDstrategy(0), fQAlist(0x0), - fDebugLevel(c.fDebugLevel) + fDebugLevel(c.fDebugLevel), + fCommonObjects(NULL) { // // Copy Constructor // memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID); - memcpy(fTPCBetheBlochParameters, c.fTPCBetheBlochParameters, sizeof(Double_t)*5); if(c.fDetectorPID[kMCpid]) fDetectorPID[kMCpid] = new AliHFEpidMC(*(dynamic_cast(c.fDetectorPID[kMCpid]))); if(c.fDetectorPID[kTPCpid]) @@ -102,13 +104,10 @@ AliHFEpid& AliHFEpid::operator=(const AliHFEpid &c){ fDebugLevel = c.fDebugLevel; memset(fDetectorPID, 0, sizeof(AliHFEpidBase *) * kNdetectorPID); - memcpy(fTPCBetheBlochParameters, c.fTPCBetheBlochParameters, sizeof(Double_t)*5); if(c.fDetectorPID[kMCpid]) fDetectorPID[kMCpid] = new AliHFEpidMC(*(dynamic_cast(c.fDetectorPID[kMCpid]))); if(c.fDetectorPID[kTPCpid]) fDetectorPID[kTPCpid] = new AliHFEpidTPC(*(dynamic_cast(c.fDetectorPID[kTPCpid]))); - if(fTPCBetheBlochParameters[0] > 1e-6) - (dynamic_cast(fDetectorPID[kTPCpid])->SetBetheBlochParameters(fTPCBetheBlochParameters)); if(c.fDetectorPID[kTRDpid]) fDetectorPID[kTRDpid] = new AliHFEpidTRD(*(dynamic_cast(c.fDetectorPID[kTOFpid]))); if(c.fDetectorPID[kTOFpid]) @@ -133,6 +132,28 @@ AliHFEpid::~AliHFEpid(){ delete fDetectorPID[idet]; } if(fQAlist) delete fQAlist; fQAlist = 0x0; // Each detector has to care about its Histograms + ClearCommonObjects(); +} + +//____________________________________________________________ +void AliHFEpid::AddCommonObject(TObject * const o){ + // + // Add common object to the garbage collection + // + if(!fCommonObjects) fCommonObjects = new TObjArray; + fCommonObjects->Add(o); +} + +//____________________________________________________________ +void AliHFEpid::ClearCommonObjects(){ + // + // empty garbage collection + // + if(fCommonObjects){ + fCommonObjects->Delete(); + delete fCommonObjects; + fCommonObjects = NULL; + } } //____________________________________________________________ @@ -152,12 +173,14 @@ Bool_t AliHFEpid::InitializePID(TString arg){ AliInfo(Form("PID Strategy %d enabled", fPIDstrategy)); Int_t strategyStatus = kTRUE; switch(fPIDstrategy){ + case 0: break; // Pure MC PID - only valid in MC mode case 1: InitStrategy1(); break; case 2: InitStrategy2(); break; case 3: InitStrategy3(); break; case 4: InitStrategy4(); break; case 5: InitStrategy5(); break; case 6: InitStrategy6(); break; + case 7: InitStrategy7(); break; default: strategyStatus = kFALSE; } return strategyStatus; @@ -174,8 +197,6 @@ Bool_t AliHFEpid::InitializePID(TString arg){ if(det->String().CompareTo("TPC") == 0){ AliInfo("Doing TPC PID"); fDetectorPID[kTPCpid] = new AliHFEpidTPC("TPC PID"); - if(fTPCBetheBlochParameters[0] > 1e-6) - (dynamic_cast(fDetectorPID[kTPCpid])->SetBetheBlochParameters(fTPCBetheBlochParameters)); SETBIT(fEnabledDetectors, kTPCpid); } else if(det->String().CompareTo("TRD") == 0){ fDetectorPID[kTRDpid] = new AliHFEpidTRD("TRD PID"); @@ -209,15 +230,17 @@ Bool_t AliHFEpid::IsSelected(AliHFEpidObject *track){ // MC Event return (TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11); } - if(fPIDstrategy > 0 && fPIDstrategy < 7){ + if(fPIDstrategy < 8){ Int_t pid = 0; switch(fPIDstrategy){ + case 0: pid = IdentifyStrategy0(track); break; case 1: pid = IdentifyStrategy1(track); break; case 2: pid = IdentifyStrategy2(track); break; case 3: pid = IdentifyStrategy3(track); break; case 4: pid = IdentifyStrategy4(track); break; case 5: pid = IdentifyStrategy5(track); break; case 6: pid = IdentifyStrategy6(track); break; + case 7: pid = IdentifyStrategy7(track); break; default: break; } return pid; @@ -252,6 +275,8 @@ Bool_t AliHFEpid::MakePidTpcTof(AliHFEpidObject *track){ if(track->fAnalysisType != AliHFEpidObject::kESDanalysis) return kFALSE; AliESDtrack *esdTrack = dynamic_cast(track->fRecTrack); if(!esdTrack) return kFALSE; + // return if TOF information not available + if(!(esdTrack->GetStatus() & AliESDtrack::kTOFpid)) return kFALSE; AliHFEpidTOF *tofPID = dynamic_cast(fDetectorPID[kTOFpid]); if(!tofPID){ @@ -259,62 +284,30 @@ Bool_t AliHFEpid::MakePidTpcTof(AliHFEpidObject *track){ return kFALSE; } - AliHFEpidTPC *tpcPID = dynamic_cast(fDetectorPID[kTPCpid]); if(!tpcPID){ AliWarning("TPC pid object is NULL"); return kFALSE; } - // charge of the particle - Int_t charge = 0; - if(esdTrack->GetOuterParam()) charge = esdTrack->GetOuterParam()->Charge(); - else charge = esdTrack->GetInnerParam()->Charge(); - - // setup the TPC PID - const Int_t cTPCsigma = 2; - // set the number of sigmas in the TPC - tpcPID->SetTPCnSigma(cTPCsigma); - // turn on the the dEdx line crossing for kaons and protons - tpcPID->AddTPCdEdxLineCrossing(3, cTPCsigma); // for kaons - tpcPID->AddTPCdEdxLineCrossing(4, cTPCsigma); // for protons - // request the tpc PID information - Int_t pidTPC = tpcPID->IsSelected(track); - - // without TPC pid it makes no sense to look at the TOF pid with this detector combination - //if(0 == pidTPC){ - // return kFALSE; - //} + // Use TOF PID to select particles with a sigma to the electron line > defined in initialize PID + if(TMath::Abs(tofPID->IsSelected(track)) != 11) return kFALSE; + // request TOF PID information, reject if no TOF information is available or if TOF identified as Proton or Kaon + // apply cut only up to certain upper momentum cut + /*Int_t pidTOF = tofPID->IsSelected(track); + Bool_t isRejected = kFALSE; + switch(TMath::Abs(pidTOF)){ + case 321: if(track->fRecTrack->P() < 1.5) isRejected = kTRUE; break; + case 2212: if(track->fRecTrack->P() < 3) isRejected = kTRUE; break; + case 0: if(track->fRecTrack->P() < 3) isRejected = kTRUE; break; // No TOF information available + default: break; + }; + if(isRejected) return kFALSE;*/ - // is the TPC in the crossing line region? 0 - no crossing, otherwise the AliPID of the crossing - // particle returned - 3 for Kaon and 4 for Proton - Int_t crossing = tpcPID->GetCrossingType(); + // Particle passed TOF, let TPC decide, no line crossings defined anymore - // setup the TOF pid - const Int_t cTOFsigma = 3; - tofPID->SetTOFnSigma(cTOFsigma); - // request TOF PID information - Int_t pidTOF = tofPID->IsSelected(track); - - // case that the TOF for some reason does not deliver a PID information - // or the TPC is not in the crossing point region, only the TPC will be used - if(0 != pidTOF && 0 != crossing){ - if(3 == crossing){ - return (321 == pidTOF) ? kFALSE : kTRUE; - } - else if(4 == crossing){ - return (2212 == pidTOF) ? kFALSE : kTRUE; - } - else{ - // something went wrong - AliError("Wrong crossing type returned from AliHFEpidTPC - check your code!!"); - return kFALSE; - } - } - else{ - // tpc ONLY - return (11 == pidTPC) ? kTRUE : kFALSE; - } + // request the tpc PID information + return (TMath::Abs(tpcPID->IsSelected(track)) == 11); } //____________________________________________________________ @@ -388,6 +381,16 @@ void AliHFEpid::MakePlotsItsTpc(AliHFEpidObject *track){ } } +//____________________________________________________________ +void AliHFEpid::SetESDpid(AliESDpid *pid){ + // + // Set ESD PID to the Detector PID objects + // + for(Int_t idet = 0; idet < kNdetectorPID; idet++){ + if(fDetectorPID[idet]) fDetectorPID[idet]->SetESDpid(pid); + } +} + //____________________________________________________________ void AliHFEpid::SetQAOn(){ // @@ -446,8 +449,6 @@ void AliHFEpid::InitStrategy1(){ // TPC alone, 3-sigma cut // AliHFEpidTPC *pid = new AliHFEpidTPC("strat1TPCpid"); - if(fTPCBetheBlochParameters[0] > 1e-6) - pid->SetBetheBlochParameters(fTPCBetheBlochParameters); pid->SetTPCnSigma(1); Bool_t status = pid->InitializePID(); if(IsQAOn() && status) pid->SetQAOn(fQAlist); @@ -461,8 +462,6 @@ void AliHFEpid::InitStrategy2(){ // TPC alone, symmetric 3 sigma cut and asymmetric sigma cut in the momentum region between 2GeV/c and 10 GeV/c and sigma between -1 and 100 // AliHFEpidTPC *pid = new AliHFEpidTPC("strat2TPCpid"); - if(fTPCBetheBlochParameters[0] > 1e-6) - pid->SetBetheBlochParameters(fTPCBetheBlochParameters); pid->SetTPCnSigma(3); pid->SetAsymmetricTPCsigmaCut(2., 10., 0., 4.); Bool_t status = pid->InitializePID(); @@ -477,8 +476,6 @@ void AliHFEpid::InitStrategy3(){ // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection // AliHFEpidTPC *pid = new AliHFEpidTPC("strat3TPCpid"); - if(fTPCBetheBlochParameters[0] > 1e-6) - pid->SetBetheBlochParameters(fTPCBetheBlochParameters); pid->SetTPCnSigma(3); pid->SetRejectParticle(AliPID::kPion, 0., -100., 10., 1.); Bool_t status = pid->InitializePID(); @@ -519,10 +516,22 @@ void AliHFEpid::InitStrategy6(){ // Combined TPC-TOF PID, combination is discribed in the funtion MakePidTpcTof // AliHFEpidTPC *tpcpid = new AliHFEpidTPC("strat6TPCpid"); - if(fTPCBetheBlochParameters[0] > 1e-6) - tpcpid->SetBetheBlochParameters(fTPCBetheBlochParameters); AliHFEpidTOF *tofpid = new AliHFEpidTOF("strat6TOFpid"); + tpcpid->SetTPCnSigma(2); + tofpid->SetTOFnSigma(3); Bool_t status = tpcpid->InitializePID(); + //TF1 *upperCut = new TF1("upperCut", "[0] * TMath::Exp([1]*x)", 0, 20); + TF1 *upperCut = new TF1("upperCut", "[0]", 0, 20); // Use constant upper cut + TF1 *lowerCut = new TF1("lowerCut", "[0] * TMath::Exp([1]*x)", 0, 20); + upperCut->SetParameter(0, 3.); + //upperCut->SetParameter(0, 2.7); + //upperCut->SetParameter(1, -0.4357); + lowerCut->SetParameter(0, -2.7); + lowerCut->SetParameter(1, -0.4357); + tpcpid->SetUpperSigmaCut(upperCut); + tpcpid->SetLowerSigmaCut(lowerCut); + AddCommonObject(upperCut); + AddCommonObject(lowerCut); if(!status) AliError("Initialization of TPC PID failed"); Bool_t status1 = tofpid->InitializePID(); @@ -541,6 +550,27 @@ void AliHFEpid::InitStrategy6(){ fDetectorPID[kTOFpid] = tofpid; } +//____________________________________________________________ +void AliHFEpid::InitStrategy7(){ + // + // TPC alone, symmetric 3 sigma cut and 2 - -100 sigma pion rejection + // + AliHFEpidTPC *pid = new AliHFEpidTPC("strat7TPCpid"); + pid->SetTPCnSigma(2); + pid->SetRejectParticle(AliPID::kProton, 0., -3., 10., 3.); + pid->SetRejectParticle(AliPID::kKaon, 0., -3., 10., 3.); + Bool_t status = pid->InitializePID(); + if(IsQAOn() && status) pid->SetQAOn(fQAlist); + if(HasMCData() && status) pid->SetHasMCData(); + fDetectorPID[kTPCpid] = pid; +} + + +//____________________________________________________________ +Bool_t AliHFEpid::IdentifyStrategy0(AliHFEpidObject *track){ + return TMath::Abs(fDetectorPID[kMCpid]->IsSelected(track)) == 11; +} + //____________________________________________________________ Bool_t AliHFEpid::IdentifyStrategy1(AliHFEpidObject *track){ return TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11; @@ -572,3 +602,14 @@ Bool_t AliHFEpid::IdentifyStrategy6(AliHFEpidObject *track){ return MakePidTpcTof(track); } +//____________________________________________________________ +Bool_t AliHFEpid::IdentifyStrategy7(AliHFEpidObject *track){ + // + // Do PID in strategy 7: Proton and Kaon rejection and + // lower cut on TPC Signal + // + if(!(TMath::Abs(fDetectorPID[kTPCpid]->IsSelected(track)) == 11)) + return kFALSE; + return kTRUE; +} + diff --git a/PWG3/hfe/AliHFEpid.h b/PWG3/hfe/AliHFEpid.h index 80a8f23200f..bce1e20a0b9 100644 --- a/PWG3/hfe/AliHFEpid.h +++ b/PWG3/hfe/AliHFEpid.h @@ -28,7 +28,9 @@ #include "AliHFEpidBase.h" #endif +class AliESDpid; class AliESDtrack; +class AliHFEpidBase; class AliVParticle; class AliMCParticle; @@ -46,12 +48,12 @@ class AliHFEpid : public TObject{ Bool_t IsQAOn() const { return TestBit(kIsQAOn); }; Bool_t HasMCData() const { return TestBit(kHasMCData); }; + void SetESDpid(AliESDpid *pid); void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; } void SetQAOn(); void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData, hasMCdata); }; TList *GetQAhistograms() const { return fQAlist; }; - inline void SetTPCBetheBlochParameters(Double_t *pars); protected: Bool_t MakePidTpcTof(AliHFEpidObject *track); Bool_t MakePidTpcTrd(AliHFEpidObject *track); @@ -64,12 +66,15 @@ class AliHFEpid : public TObject{ void InitStrategy4(); void InitStrategy5(); void InitStrategy6(); + void InitStrategy7(); + Bool_t IdentifyStrategy0(AliHFEpidObject *track); Bool_t IdentifyStrategy1(AliHFEpidObject *track); Bool_t IdentifyStrategy2(AliHFEpidObject *track); Bool_t IdentifyStrategy3(AliHFEpidObject *track); Bool_t IdentifyStrategy4(AliHFEpidObject *track); Bool_t IdentifyStrategy5(AliHFEpidObject *track); Bool_t IdentifyStrategy6(AliHFEpidObject *track); + Bool_t IdentifyStrategy7(AliHFEpidObject *track); private: enum{ kIsQAOn = BIT(14), @@ -91,18 +96,18 @@ class AliHFEpid : public TObject{ kTRDSignal = 0, kITSSignal = 1 }; + + void AddCommonObject(TObject * const o); + void ClearCommonObjects(); + AliHFEpidBase *fDetectorPID[kNdetectorPID]; //! Detector PID classes UInt_t fEnabledDetectors; // Enabled Detectors UInt_t fPIDstrategy; // PID Strategy - Double_t fTPCBetheBlochParameters[5]; // TPC Bethe-Bloch Parameters TList *fQAlist; //! QA histograms Int_t fDebugLevel; // Debug Level + TObjArray *fCommonObjects; // Garbage Collector ClassDef(AliHFEpid, 1) // Steering class for Electron ID }; -void AliHFEpid::SetTPCBetheBlochParameters(Double_t *pars){ - memcpy(fTPCBetheBlochParameters, pars, sizeof(Double_t)*5); -} - #endif diff --git a/PWG3/hfe/AliHFEpidBase.cxx b/PWG3/hfe/AliHFEpidBase.cxx index 8a86011e6d2..2da8eb52a69 100644 --- a/PWG3/hfe/AliHFEpidBase.cxx +++ b/PWG3/hfe/AliHFEpidBase.cxx @@ -20,13 +20,26 @@ // Authors: // Markus Fasel // +#include "AliESDpid.h" #include "AliHFEpidBase.h" ClassImp(AliHFEpidBase) +//___________________________________________________________________ +AliHFEpidBase::AliHFEpidBase(): + TNamed(), + fESDpid(NULL), + fDebugLevel(0) +{ + // + // Default constructor + // +} + //___________________________________________________________________ AliHFEpidBase::AliHFEpidBase(const Char_t *name): TNamed(name, ""), + fESDpid(NULL), fDebugLevel(0) { // @@ -37,6 +50,7 @@ AliHFEpidBase::AliHFEpidBase(const Char_t *name): //___________________________________________________________________ AliHFEpidBase::AliHFEpidBase(const AliHFEpidBase &c): TNamed(), + fESDpid(NULL), fDebugLevel(0) { // @@ -64,6 +78,7 @@ void AliHFEpidBase::Copy(TObject &ref) const { // AliHFEpidBase &target = dynamic_cast(ref); + target.fESDpid = fESDpid; target.fDebugLevel = fDebugLevel; TNamed::Copy(ref); diff --git a/PWG3/hfe/AliHFEpidBase.h b/PWG3/hfe/AliHFEpidBase.h index fd7eff88a1d..99670098a4d 100644 --- a/PWG3/hfe/AliHFEpidBase.h +++ b/PWG3/hfe/AliHFEpidBase.h @@ -24,6 +24,7 @@ #endif class TList; +class AliESDpid; class AliVParticle; class AliMCParticle; @@ -40,6 +41,7 @@ struct AliHFEpidObject{ class AliHFEpidBase : public TNamed{ public: + AliHFEpidBase(); AliHFEpidBase(const Char_t *name); AliHFEpidBase(const AliHFEpidBase &c); AliHFEpidBase &operator=(const AliHFEpidBase &c); @@ -53,11 +55,13 @@ class AliHFEpidBase : public TNamed{ Bool_t IsQAon() const { return TestBit(kQAon);}; Bool_t HasMCData() const { return TestBit(kHasMCData); }; + void SetESDpid(AliESDpid * const pid) { fESDpid = pid; } void SetDebugLevel(Int_t debugLevel) { fDebugLevel = debugLevel; }; inline void SetQAOn(TList *fQAlist); void SetHasMCData(Bool_t hasMCdata = kTRUE) { SetBit(kHasMCData,hasMCdata); }; protected: + AliESDpid *fESDpid; // ESD PID object void Copy(TObject &ref) const; virtual void AddQAhistograms(TList *){}; private: diff --git a/PWG3/hfe/AliHFEpidQA.cxx b/PWG3/hfe/AliHFEpidQA.cxx index 38b3a51cc06..206da7339c6 100644 --- a/PWG3/hfe/AliHFEpidQA.cxx +++ b/PWG3/hfe/AliHFEpidQA.cxx @@ -1,17 +1,17 @@ /************************************************************************** -* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * -* * -* Author: The ALICE Off-line Project. * -* Contributors are mentioned in the code where appropriate. * -* * -* Permission to use, copy, modify and distribute this software and its * -* documentation strictly for non-commercial purposes is hereby granted * -* without fee, provided that the above copyright notice appears in all * -* copies and that both the copyright notice and this permission notice * -* appear in the supporting documentation. The authors make no claims * -* about the suitability of this software for any purpose. It is * -* provided "as is" without express or implied warranty. * -**************************************************************************/ + * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ // // Class for PID QA // Several studies done on clean samples of electrons, pions and kaons @@ -23,52 +23,85 @@ // Markus Heide // Markus Fasel // -#include -#include -#include + + #include #include -#include #include #include +#include +#include #include "AliAODMCParticle.h" -#include "AliAODPid.h" +#include "AliAODEvent.h" #include "AliAODTrack.h" #include "AliESDtrack.h" -#include "AliLog.h" +#include "AliESDEvent.h" #include "AliMCEvent.h" #include "AliMCParticle.h" #include "AliPID.h" #include "AliESDpid.h" -//#include "AliTRDPIDResponseLQ1D.h" -#include "AliVEvent.h" #include "AliVParticle.h" -#include "AliExternalTrackParam.h" #include "AliHFEcollection.h" #include "AliHFEpidQA.h" +#include "AliHFEV0info.h" #include "AliHFEV0pid.h" #include "AliHFEV0pidMC.h" -#include "AliHFEpidTRD.h" +#include "AliHFEtrdPIDqa.h" + ClassImp(AliHFEpidQA) -//__________________________________________ -AliHFEpidQA::AliHFEpidQA(): - fMC(NULL) - , fV0pid(NULL) - , fV0pidMC(NULL) - , fOutput(NULL) - , fT0(0) - , fRun(0) - , fESDpid(NULL) + //__________________________________________ + AliHFEpidQA::AliHFEpidQA(): + fEvent(NULL), + fMC(NULL), + fV0pid(NULL), + fV0pidMC(NULL), + fTRDpidQA(NULL), + fOutput(NULL), + fESDpid(NULL), + fNNref(NULL) { // // Default constructor // - fESDpid = new AliESDpid; + for(Int_t mom = 0; mom < 11; mom++){ + fNet[mom] = NULL; + } +} + +//__________________________________________ +AliHFEpidQA::AliHFEpidQA(const AliHFEpidQA &ref): + TObject(ref), + fEvent(NULL), + fMC(NULL), + fV0pid(NULL), + fV0pidMC(NULL), + fTRDpidQA(NULL), + fOutput(NULL), + fESDpid(NULL), + fNNref(NULL) +{ + // + // Copy constructor + // + for(Int_t mom = 0; mom < 11; mom++){ + fNet[mom] = NULL; + } + ref.Copy(*this); +} + +//__________________________________________ +AliHFEpidQA &AliHFEpidQA::operator=(const AliHFEpidQA &ref){ + // + // Assignment operator + // + if(this != &ref) + ref.Copy(*this); + return *this; } //__________________________________________ @@ -78,9 +111,42 @@ AliHFEpidQA::~AliHFEpidQA(){ // if(fV0pid) delete fV0pid; if(fV0pidMC) delete fV0pidMC; + if(fTRDpidQA) delete fTRDpidQA; if(fOutput) delete fOutput; - if(fESDpid) delete fESDpid; -// if(fTRDpidResponse) delete fTRDpidResponse; + // if(fTRDpidResponse) delete fTRDpidResponse; +} + +//__________________________________________ +void AliHFEpidQA::Copy(TObject &o) const { + // + // Copy function + // + + TObject::Copy(o); + + AliHFEpidQA &target = dynamic_cast(o); + target.fMC = fMC; + + if(target.fESDpid) delete target.fESDpid; + target.fESDpid = new AliESDpid; + if(target.fV0pid) delete target.fV0pid; + if(fV0pid) + target.fV0pid = dynamic_cast(fV0pid->Clone()); + else + target.fV0pid = NULL; + if(target.fV0pidMC) delete target.fV0pidMC; + if(fV0pidMC) + target.fV0pidMC = dynamic_cast(fV0pidMC->Clone()); + else + target.fV0pidMC = NULL; + if(target.fTRDpidQA) delete target.fTRDpidQA; + if(fTRDpidQA) + target.fTRDpidQA = dynamic_cast(fTRDpidQA->Clone()); + else + target.fTRDpidQA = NULL; + if(target.fOutput) delete target.fOutput; + if(fOutput) + target.fOutput = dynamic_cast(fOutput->Clone()); } //__________________________________________ @@ -89,131 +155,172 @@ void AliHFEpidQA::Init(){ // Prepare task output // + if(fNNref){ + for(Int_t mom = 0; mom < 11; mom++){ // load networks + fNet[mom] = (TMultiLayerPerceptron*) fNNref->Get(Form("NN_Mom%d", mom)); + if(!fNet[mom]){ + AliError(Form("No reference network for momentum bin %d!", mom)); + } + } + } + fV0pid = new AliHFEV0pid; if(HasV0pidQA()) fV0pid->InitQA(); fV0pidMC = new AliHFEV0pidMC(); fV0pidMC->Init(); + fTRDpidQA = new AliHFEtrdPIDqa; + fTRDpidQA->Init(); + fOutput = new AliHFEcollection("pidQA", "PID QA output"); - // 1st: Histos for purity studies - fOutput->CreateTH2F("purityElectron", "Electron Putrity", 2, -0.5, 1.5, 20, 0.1, 10); - fOutput->BinLogAxis("purityElectron" ,1); - fOutput->CreateTH2F("purityPionK0", "K0 Pion Putrity", 2, -0.5, 1.5, 20, 0.1, 10); - fOutput->BinLogAxis("purityPionK0" ,1); - fOutput->CreateTH2F("purityPionL", "Lambda Pion Putrity", 2, -0.5, 1.5, 20, 0.1, 10); - fOutput->BinLogAxis("purityPionL" ,1); - fOutput->CreateTH2F("purityProton", "Proton Putrity", 2, -0.5, 1.5, 20, 0.1, 10); - fOutput->BinLogAxis("purityProton" ,1); - - // Histograms for TRD Electron Likelihood - fOutput->CreateTH2F("hTRDelLikeElectron", "TRD Electron Likelihoods for Electrons; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.); - fOutput->BinLogAxis("hTRDelLikeElectron", 0); - fOutput->CreateTH2F("hTRDelLikePionK0", "TRD Electron Likelihoods for K0 Pions; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.); - fOutput->BinLogAxis("hTRDelLikePionK0", 0); - fOutput->CreateTH2F("hTRDelLikePionL", "TRD Electron Likelihoods for Lambda Pions; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.); - fOutput->BinLogAxis("hTRDelLikePionL", 0); - fOutput->CreateTH2F("hTRDelLikeProton", "TRD Electron Likelihoods for Protons; p (GeV/c); likelihood", 20, 0.1, 10, 100, 0., 1.); - fOutput->BinLogAxis("hTRDelLikeProton", 0); - - // TPC pid response - fOutput->CreateTH2F("hTPC_dEdx_Electron", "TPC dEdx for conversion electrons; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200); - fOutput->BinLogAxis("hTPC_dEdx_Electron", 0); - fOutput->CreateTH2F("hTPC_dEdx_PionK0", "TPC dEdx for K0 pions; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200); - fOutput->BinLogAxis("hTPC_dEdx_PionK0", 0); - fOutput->CreateTH2F("hTPC_dEdx_PionL", "TPC dEdx for Lambda pions; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200); - fOutput->BinLogAxis("hTPC_dEdx_PionL", 0); - fOutput->CreateTH2F("hTPC_dEdx_Proton", "TPC dEdx for Lambda proton; p (GeV/c); dEdx (a.u.)", 20, 0.1, 10, 200, 0, 200); - fOutput->BinLogAxis("hTPC_dEdx_Proton", 0); - - fOutput->CreateTH2F("hTPCnSigmaElectron", "TPC number of sigmas for conversion electrons; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7); - fOutput->BinLogAxis("hTPCnSigmaElectron", 0); - fOutput->CreateTH2F("hTPCnSigmaPionK0", "TPC number of sigmas for K0 pions; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7); - fOutput->BinLogAxis("hTPCnSigmaPionK0", 0); - fOutput->CreateTH2F("hTPCnSigmaPionL", "TPC number of sigmas for Lambda pions; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7); - fOutput->BinLogAxis("hTPCnSigmaPionL", 0); - fOutput->CreateTH2F("hTPCnSigmaProton", "TPC number of sigmas for Lambda protons; p (GeV/c); number of sigmas", 20, 0.1, 10, 100, -7, 7); - fOutput->BinLogAxis("hTPCnSigmaProton", 0); + const char *name[4] = {"Electron", "PionK0", "PionL", "Proton"}; + const char *title[4] = {"Electron", "K0 Pion", "Lambda Pion", "Proton"}; + const char *det[4] = {"ITS", "TPC", "TRD", "TOF"}; + for(Int_t i = 0; i < 4; i++){ + fOutput->CreateTH2F(Form("purity%s", name[i]), Form("%s Purity", title[i]), 2, -0.5, 1.5, 20, 0.1, 10, 1); + + for(Int_t idet = 0; idet < 4; idet++){ + // create all the histograms which all the detectors have in common + if(idet != 2){ // no nSigma histogram for TRD + fOutput->CreateTH2F(Form("h%s_nSigma_%s", det[idet], name[i]), Form("%s number of sigmas for %ss; p (GeV/c); number of sigmas", det[idet], title[i]), 20, 0.1, 10, 100, -7, 7, 0); + } + fOutput->CreateTH2F(Form("h%s_PID_p_%s", det[idet], name[i]), Form("%s PID for %ss; p (GeV/c); ITS PID", det[idet], title[i]), 100, 0.1, 10, 5, -0.5, 4.5, 0); + fOutput->CreateTH2F(Form("h%s_El_like_%s", det[idet], name[i]), Form("%s Electron Likelihoods for %ss; p (GeV/c); likelihood", det[idet], title[i]), 25, 0.1, 10, 1000, 0., 1., 0); + fOutput->CreateTH2F(Form("h%s_El_like_MC_%s", det[idet], name[i]), Form("%s Electron Likelihoods for MC %ss; p (GeV/c); likelihood", det[idet], title[i]), 25, 0.1, 10, 1000, 0., 1., 0); + } + // + // ITS pid response + // + fOutput->CreateTH2F(Form("hITS_Signal_%s", name[i]), Form("ITS Signal org. for %ss", title[i]), 40, 0.1, 10, 400, 0, 1000, 0); + fOutput->CreateTH2Fvector1(5, Form("hITS_dEdx_%s", name[i]), Form("ITS dEdx for %ss; p (GeV/c); dEdx (a.u.)", title[i]), 40, 0.1, 10, 400, 0, 1000, 0); + + // + // TPC pid response + // + fOutput->CreateTH2F(Form("hTPC_dEdx_%s", name[i]), Form("TPC dEdx for %ss; p (GeV/c); dEdx (a.u.)", title[i]), 20, 0.1, 10, 200, 0, 200, 0); + + // + // TRD pid response + // + fOutput->CreateTH2F(Form("hTRD_trk_%s", name[i]), Form("%s PID tracklets; p (GeV/c); N TRD tracklets", title[i]), 100, 0.1, 10, 7, -0.5, 6.5, 0); + // number of the non 0 slices per tracklet + fOutput->CreateTH2F(Form("hTRD_Nslc_%s", name[i]), Form("%s PID slices > 0; p (GeV/c); N slc > 0", title[i]), 100, 0.1, 10, 9, -0.5, 8.5, 0); + // location of the slices > 0 - where are the emtpy slices located ? + fOutput->CreateTH2F(Form("hTRD_slc_%s", name[i]), Form("%s PID slices > 0 position; p (GeV/c); slice", title[i]), 100, 0.1, 10, 9, -0.5, 8.5, 0); + fOutput->CreateTH2F(Form("hTRD_cls_%s", name[i]), Form("TRD clusters for %s candidates; p (GeV/c); N cls", title[i]), 25, 0.1, 10, 1000, 0, 1000); + fOutput->CreateTH2F(Form("hTRD_dEdx_%s", name[i]), Form("TRD dEdx (trk) for %s candidates; p (GeV/c); tracklet dEdx (a.u.)", title[i]), 25, 0.1, 10, 1000, 0, 100000, 0); + + // + // TOF pid response + // + fOutput->CreateTH2F(Form("hTOF_beta_%s", name[i]), Form("TOF beta for %s; p (GeV/c); #beta", title[i]), 50, 0.1, 5, 350, 0.4, 1.1, 0); + }//.. loop over identified particle species + + // Global histograms + fOutput->CreateTH1F("hITS_dEdx_nSamples", "ITS - number of non 0 dEdx samples", 4, 0.5, 4.5); fOutput->CreateTH2F("hTPC_PID", "TPC pid all tracks; tpc pid probability; species",100, 0, 1, 5, -0.5, 4.5 ); - fOutput->CreateTH2F("hTPC_PID_p_Electron", "TPC PID for conversion electrons; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTPC_PID_p_Electron", 0); - fOutput->CreateTH2F("hTPC_PID_p_PionK0", "TPC PID for K0 pions; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTPC_PID_p_PionK0", 0); - fOutput->CreateTH2F("hTPC_PID_p_PionL", "TPC PID for Lambda pions; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTPC_PID_p_PionL", 0); - fOutput->CreateTH2F("hTPC_PID_p_Proton", "TPC PID for Lambda protons; p (GeV/c); TPC PID", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTPC_PID_p_Proton", 0); - - - // TRD pid response - fOutput->CreateTH2F("hTRD_Electron_trk", "all Electron candidate tracklets; p (GeV/c); N TRD tracklets", 100, 0.1, 10, 7, -0.5, 6.5); - fOutput->BinLogAxis("hTRD_Electron_trk", 0); - fOutput->CreateTH1F("hTRD_Electron_Y_like", "YES - V0 electron eff. for fixed likelihood cut; p (GeV/c); counts", 25, 0.1, 10); - fOutput->BinLogAxis("hTRD_Electron_Y_like", 0); - fOutput->CreateTH1F("hTRD_Electron_N_like", "NO - V0 electron eff. for fixed likelihood cut; p (GeV/c); counts", 25, 0.1, 10); - fOutput->BinLogAxis("hTRD_Electron_N_like", 0); - fOutput->CreateTH2F("hTRD_El_like_Electron", "V0 electron likelihoods for electrons; p (GeV/c); likelihood", 25, 0.1, 10, 1000, 0., 1.); - fOutput->BinLogAxis("hTRD_El_like_Electron", 0); - fOutput->CreateTH2F("hTRD_El_like_Pion", "V0 electron likelihoods for poins; p (GeV/c); likelihood", 25, 0.1, 10, 1000, 0., 1.); - fOutput->BinLogAxis("hTRD_El_like_Pion", 0); - fOutput->CreateTH2F("hTRD_El_like_Proton", "V0 electron likelihoods for protons; p (GeV/c); likelihood", 25, 0.1, 10, 1000, 0., 1.); - fOutput->BinLogAxis("hTRD_El_like_Proton", 0); - - - // TOF pid response - fOutput->CreateTH2F("hTOF_PID", "TOF pid all tracks; tof pid probability; species",100, 0, 1,5, -0.5, 4.5 ); - - fOutput->CreateTH2F("hTOF_PID_p_Electron", "TOF PID for gamma converisons; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTOF_PID_p_Electron", 0); - fOutput->CreateTH2F("hTOF_PID_p_PionK0", "TOF PID for K0 pions; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTOF_PID_p_PionK0", 0); - fOutput->CreateTH2F("hTOF_PID_p_PionL", "TOF PID for Lambda pions; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTOF_PID_p_PionL", 0); - fOutput->CreateTH2F("hTOF_PID_p_Proton", "TOF PID for Lambda protons; p_T (GeV/c); counts", 100, 0.1, 10, 5, -0.5, 4.5); - fOutput->BinLogAxis("hTOF_PID_p_Proton", 0); - - fOutput->CreateTH2F("hTOF_beta_Electron", "TOF beta for gamma conversions; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10); - fOutput->BinLogAxis("hTOF_beta_Electron", 1); - fOutput->CreateTH2F("hTOF_beta_PionK0", "TOF beta for K0 pions; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10); - fOutput->BinLogAxis("hTOF_beta_PionK0", 1); - fOutput->CreateTH2F("hTOF_beta_PionL", "TOF beta Lambda pions; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10); - fOutput->BinLogAxis("hTOF_beta_PionL", 1); - fOutput->CreateTH2F("hTOF_beta_Proton", "TOF beta for Lambda protons; #beta; p (GeV/c)", 120, 0, 1.2, 100, 0.1, 10); - fOutput->BinLogAxis("hTOF_beta_Proton", 1); + fOutput->CreateTH2F("hTOF_beta_all", "TOF beta for all nice single tracks; p (GeV/c); #beta", 100, 0.1, 10, 480, 0, 1.2, 0); + fOutput->CreateTH2F("hTOF_qa_TmT0mT", "TOF (t - t0 - t[pion]) qa verus run", 10000, 114000, 124000, 200, -200, 200); + fOutput->CreateTH2F("hTOF_qa_length", "TOF track length verus run", 10000, 114000, 112400, 200, 0, 1000); + + // + // debug histograms + // + fOutput->CreateTH2F("hITS_kFlags", "ITS flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5); + fOutput->CreateTH2F("hTPC_kFlags", "TPC flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5); + fOutput->CreateTH2F("hTRD_kFlags", "TRD flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5); + fOutput->CreateTH2F("hTOF_kFlags", "TOF flags; flag; V0 candidates", 5, 0.5, 5.5, 5, -0.5, 4.5); + // + // event based histograms + // + Int_t n_T0[2] = {10000, 100}; + Double_t min_T0[2] = {114500, -1000}; + Double_t max_T0[2] = {124500, 1000}; + fOutput->CreateTHnSparse("hEvent_T0", "T0 as a function of run number; run number; T0 (ns)", 2, n_T0, min_T0, max_T0); + + // + // test the tender V0 supply + // + fOutput->CreateTH2F("h_tender_check_01", "tender -vs- HFEpidQA; HFEpidQA V0 candiadates; tender V0 candidates", 4, -1.5, 2.5, 4, -1.5, 2.5); + fOutput->CreateTH2Fvector1(3, "h_tender_check_02", "tender -vs- HFEpidQA per type; AliHFEpidQA V0 ; tender V0", 4, -1.5, 2.5, 4, -1.5, 2.5); - // Prepare TRD PID -/* if(HasRecalculateTRDpid()){ - fTRDpidResponse = new AliTRDPIDResponseLQ1D; - fTRDpidResponse->LoadReferences(); - }*/ -} -//__________________________________________ -void AliHFEpidQA::Process(AliVEvent *inputEvent){ // - // Run PID QA + // THnSpasre objects // - if(fRun >= 104065 && fRun <= 104892){ - CorrectT0(); + // Create Illumination Plot + // bins: species, pt, eta, phi, TPC status, TRD status + { + Int_t nbins[6] = {4, 40, 16, 72, 2, 2}; + Double_t min[6] = { 0, 0.1, -0.8, 0., 0., 0.}; + Double_t max[6] = { 4., 20., 0.8, 2*TMath::Pi(), 2., 2.}; + fOutput->CreateTHnSparse("hIllumination", "Illumination", 6, nbins, min, max); + fOutput->BinLogAxis("hIllumination", 1); + } + + // TPC THnSparse + // bins: species, pt, n TPC clusters., TPC electron likelihood, TPC n sigmas, TPC signal + { + Int_t nbins[6] = { 5, 40, 20, 100, 100, 200}; + Double_t min[6] = { -0.5, 0.1, 0., 0., -5., 0.}; + Double_t max[6] = { 4.5, 20., 200, 1., 5., 120.}; + TString htitle = "TPC info sparse; VO identified species; p (GeV/c); n TPC clusters; TPC N sigma; TPC signal"; + fOutput->CreateTHnSparse("hTPCclusters",htitle,6, nbins, min, max); + fOutput->BinLogAxis("hTPCclusters", 1); + } + // TRD THnSparse - entries per tracklet + // species, p, tracklet position, number of PID tracklets, number of slices (non 0), number of clusters, electron likelihood, + { + Int_t nbins[7] = {5, 20, 6, 7, 9, 45, 100}; + Double_t min[7] = {-0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.}; + Double_t max[7] = {4.5, 10, 5.5, 6.5, 8.5, 179.5, 1.}; + TString htitle = "TRD tracklets; VO identified species; p (GeV/c); tracklet position; No. PID tacklets; No. slices; No. clusters; El. likelihood"; + fOutput->CreateTHnSparse("hTRDtracklets",htitle,7, nbins, min, max); + fOutput->BinLogAxis("hTRDtracklets", 1); } + + +} +//__________________________________________ +void AliHFEpidQA::Process(){ + // + // Run PID QA + // if(!fV0pid){ AliError("V0pid not available! Forgotten to initialize?"); return; } + if(!fESDpid){ + AliError("fESDpid not initialized, I am leaving this!"); + return; + } + + // to be udpated to AOD save mdoe + if(!fEvent){ + AliError("AliVEvent not available, returning"); + } if(fMC) fV0pidMC->SetMCEvent(fMC); - fV0pid->Process(inputEvent); - TObjArray *electrons = fV0pid->GetListOfElectrons(); - TObjArray *pionsK0 = fV0pid->GetListOfPionsK0(); - TObjArray *pionsL = fV0pid->GetListOfPionsL(); - TObjArray *protons = fV0pid->GetListOfProtons(); + fV0pid->Process(fEvent); + TObjArray *hfeelectrons = fV0pid->GetListOfElectrons(); + TObjArray *hfepionsK0 = fV0pid->GetListOfPionsK0(); + TObjArray *hfepionsL = fV0pid->GetListOfPionsL(); + TObjArray *hfeprotons = fV0pid->GetListOfProtons(); + + // Get Track list for normal purpose + TObjArray *electrons = MakeTrackList(hfeelectrons); + TObjArray *pionsK0 = MakeTrackList(hfepionsK0); + TObjArray *pionsL = MakeTrackList(hfepionsL); + TObjArray *protons = MakeTrackList(hfeprotons); + TObjArray *cleanElectrons = MakeCleanListElectrons(hfeelectrons); if(fMC){ fV0pidMC->Process(electrons, AliHFEV0pid::kRecoElectron); @@ -234,20 +341,112 @@ void AliHFEpidQA::Process(AliVEvent *inputEvent){ MakePurity(pionsL, AliHFEV0pid::kRecoPionL); MakePurity(protons, AliHFEV0pid::kRecoProton); } + + // some event wise checks + CheckEvent(); + + // Make Illumination Plot + FillIllumination(electrons, AliHFEV0pid::kRecoElectron); + FillIllumination(pionsK0, AliHFEV0pid::kRecoPionK0); + FillIllumination(pionsL, AliHFEV0pid::kRecoPionL); + FillIllumination(protons, AliHFEV0pid::kRecoProton); + // Now we can do studies on the PID itself - // TRD PID: Fill electron Likelihoods for the particle species - FillTRDelectronLikelihoods(electrons, AliHFEV0pid::kRecoElectron); - FillTRDelectronLikelihoods(pionsK0, AliHFEV0pid::kRecoPionK0); - FillTRDelectronLikelihoods(pionsL, AliHFEV0pid::kRecoPionL); - FillTRDelectronLikelihoods(protons, AliHFEV0pid::kRecoProton); + // For TRD use the TRD PID QA object + fTRDpidQA->ProcessTracks(cleanElectrons, AliPID::kElectron); + fTRDpidQA->ProcessTracks(pionsK0, AliPID::kPion); + fTRDpidQA->ProcessTracks(pionsL, AliPID::kPion); + fTRDpidQA->ProcessTracks(protons, AliPID::kProton); + + FillElectronLikelihoods(electrons, AliHFEV0pid::kRecoElectron); + FillElectronLikelihoods(pionsK0, AliHFEV0pid::kRecoPionK0); + FillElectronLikelihoods(pionsL, AliHFEV0pid::kRecoPionL); + FillElectronLikelihoods(protons, AliHFEV0pid::kRecoProton); FillPIDresponse(electrons, AliHFEV0pid::kRecoElectron); FillPIDresponse(pionsK0, AliHFEV0pid::kRecoPionK0); FillPIDresponse(pionsL, AliHFEV0pid::kRecoPionL); FillPIDresponse(protons, AliHFEV0pid::kRecoProton); + // check the tender V0s + CheckTenderV0pid(electrons, AliHFEV0pid::kRecoElectron); + CheckTenderV0pid(pionsK0, AliHFEV0pid::kRecoPionK0); + CheckTenderV0pid(pionsL, AliHFEV0pid::kRecoPionL); + CheckTenderV0pid(protons, AliHFEV0pid::kRecoProton); + // Analysis done, flush the containers fV0pid->Flush(); + + delete electrons; + delete pionsL; + delete pionsK0; + delete protons; + delete cleanElectrons; +} + +//__________________________________________ +void AliHFEpidQA::FillIllumination(TObjArray * const tracks, Int_t species){ + // + // Fill Illumination Plot + // + THnSparseF *hIllumination = dynamic_cast(fOutput->Get("hIllumination")); + if(!hIllumination) return; + + Double_t quantities[6]; memset(quantities, 0, sizeof(Double_t) *6); + TIter trackIter(tracks); + + quantities[0] = species; + TObject *o = NULL; AliESDtrack *esdtrack = NULL; + while((o = trackIter())){ + if(!TString(o->IsA()->GetName()).CompareTo("AliESDtrack")){ + // work on local copy in order to not spoil others + esdtrack = new AliESDtrack(*(dynamic_cast(o))); + } else if(!TString(o->IsA()->GetName()).CompareTo("AliAODrack")){ + // Bad hack: Fill ESD track with AOD information + esdtrack = new AliESDtrack(dynamic_cast(o)); + } else { + // Non usable + continue; + } + + // Propagate to the entrance of the TRD + esdtrack->PropagateTo(300, fEvent->GetMagneticField()); + quantities[1] = esdtrack->Pt(); + quantities[2] = esdtrack->Eta(); + quantities[3] = esdtrack->Phi(); + quantities[4] = (esdtrack->GetStatus() & AliESDtrack::kTPCrefit) ? 1 : 0; + quantities[5] = (esdtrack->GetStatus() & AliESDtrack::kTRDout) ? 1. : 0.; + hIllumination->Fill(quantities); + + delete esdtrack; + } +} +//__________________________________________ +void AliHFEpidQA::FillTPCinfo(AliESDtrack *const esdtrack, Int_t species){ + // + // Fill TPC Cluster Plots + // + THnSparseF *hTPCclusters = dynamic_cast(fOutput->Get("hTPCclusters")); + if(!hTPCclusters) return; + + Double_t quantities[6]; memset(quantities, 0, sizeof(Double_t) *6); + + Double_t pidProbs[5]; + const Int_t typePID[5] = {0, 2, 2, 3, 4}; + + + quantities[0] = species; + + + esdtrack->GetTPCpid(pidProbs); + + quantities[1] = esdtrack->P(); + quantities[2] = esdtrack->GetTPCNcls(); + quantities[3] = pidProbs[0]; + quantities[4] = fESDpid->NumberOfSigmasTPC(esdtrack,(AliPID::EParticleType)typePID[species]); + quantities[5] = esdtrack->GetTPCsignal(); + hTPCclusters->Fill(quantities); + } //__________________________________________ @@ -257,33 +456,31 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){ // if(!fMC) return; AliDebug(3, Form("Doing Purity checks for species %d", species)); - Int_t pdg = 0; + Int_t pdg = GetPDG(species); Char_t hname[256]; + switch(species){ - case AliHFEV0pid::kRecoElectron: - pdg = TMath::Abs(kElectron); - sprintf(hname, "purityElectron"); - break; - case AliHFEV0pid::kRecoPionK0: - pdg = TMath::Abs(kPiPlus); - sprintf(hname, "purityPionK0"); - break; - case AliHFEV0pid::kRecoPionL: - pdg = TMath::Abs(kPiPlus); - sprintf(hname, "purityPionL"); - break; - case AliHFEV0pid::kRecoProton: - pdg = TMath::Abs(kProton); - sprintf(hname, "purityProton"); - break; - default: // non investigated species - AliDebug(3, "Species not investigated"); - return; - } + case AliHFEV0pid::kRecoElectron: + sprintf(hname, "purityElectron"); + break; + case AliHFEV0pid::kRecoPionK0: + sprintf(hname, "purityPionK0"); + break; + case AliHFEV0pid::kRecoPionL: + sprintf(hname, "purityPionL"); + break; + case AliHFEV0pid::kRecoProton: + sprintf(hname, "purityProton"); + break; + default: // non investigated species + AliDebug(3, "Species not investigated"); + return; + } + AliDebug(3, Form("Number of tracks: %d", tracks->GetEntries())); - TIterator *trackIter = tracks->MakeIterator(); + TIter trackIter(tracks); AliVParticle *recTrack = NULL, *mcTrack = NULL; - while((recTrack = dynamic_cast(trackIter->Next()))){ + while((recTrack = dynamic_cast(trackIter()))){ Int_t label = recTrack->GetLabel(); AliDebug(4, Form("MC Label %d", label)); mcTrack =fMC->GetTrack(TMath::Abs(label)); @@ -304,77 +501,108 @@ void AliHFEpidQA::MakePurity(TObjArray *tracks, Int_t species){ trackPdg = TMath::Abs(aodmcp->GetPdgCode()); } if(trackPdg == pdg) // Correct identification - fOutput->Fill(hname, 0., recTrack->Pt()); + { + fOutput->Fill(hname, 0., recTrack->Pt()); + } else // Wrong identification fOutput->Fill(hname, 1., recTrack->Pt()); } - delete trackIter; } //__________________________________________ -void AliHFEpidQA::FillTRDelectronLikelihoods(TObjArray * const particles, Int_t species){ +void AliHFEpidQA::FillElectronLikelihoods(TObjArray * const particles, Int_t species){ // - // Fill electron Likelihoods for the TRD + // Fill electron Likelihoods for the ITS, TPC and TOF // Required for the calculation of the electron efficiency, // pion and proton efficiency and the thresholds // - Char_t hname[256] = "hTRDelLike"; + Long_t status = 0; + Char_t *detname[4] = {"ITS", "TPC", "TRD", "TOF"}; + Char_t specname[256]; + switch(species){ - case AliHFEV0pid::kRecoElectron: - sprintf(hname, "%sElectron", hname); - break; - case AliHFEV0pid::kRecoPionK0: - sprintf(hname, "%sPionK0", hname); - break; - case AliHFEV0pid::kRecoPionL: - sprintf(hname, "%sPionL", hname); - break; - case AliHFEV0pid::kRecoProton: - sprintf(hname, "%sProton", hname); - break; - default: - AliDebug(2, Form("Species %d not investigated", species)); - return; + case AliHFEV0pid::kRecoElectron: + sprintf(specname, "Electron"); + break; + case AliHFEV0pid::kRecoPionK0: + sprintf(specname, "PionK0"); + break; + case AliHFEV0pid::kRecoPionL: + sprintf(specname, "PionL"); + break; + case AliHFEV0pid::kRecoProton: + sprintf(specname, "Proton"); + break; + default: + AliDebug(2, Form("Species %d not investigated", species)); + return; }; AliVParticle *recTrack = NULL; - TIterator *trackIter = particles->MakeIterator(); - Double_t quantities[2] = {0., 0.}; - Double_t trdPidProbs[5]; - while((recTrack = dynamic_cast(trackIter->Next()))){ + // mcTrack =fMC->GetTrack(TMath::Abs(label)); + // if(!mcTrack){ + // AliDebug(4, "MC track not available"); + // continue; // we don't know + // } + + TIter trackIter(particles); + + Double_t quantities[2]; + Double_t pidProbs[5]; + + while((recTrack = dynamic_cast(trackIter()))){ if(!TString(recTrack->IsA()->GetName()).CompareTo("AliESDtrack")){ // case ESD AliESDtrack *esdTrack = dynamic_cast(recTrack); - if(!esdTrack->GetTRDntracklets()) continue; // require at least 1 tracklet - // take momentum at the innermost TRD layer - Double_t p = 0.; - for(Int_t ily = 0; ily < 6; ily++){ - if((p = esdTrack->GetTRDmomentum(ily)) > 1e-6) break; - } - quantities[0] = p; - if(HasRecalculateTRDpid()) - RecalculateTRDpid(esdTrack, trdPidProbs); - else - esdTrack->GetTRDpid(trdPidProbs); - quantities[1] = trdPidProbs[ AliPID::kElectron]; - } - else{ - AliAODTrack *aodTrack = dynamic_cast(recTrack); - if(!aodTrack->GetDetPid()) continue; - Float_t *trdMom = aodTrack->GetDetPid()->GetTRDmomentum(), p = 0.; - for(Int_t ily = 0; ily < 6; ily++){ - if((p = trdMom[ily]) > 1e-6) break; + status = esdTrack->GetStatus(); + + //TPC momentum and likelihoods + Double_t pTPC = 0.; + pTPC = esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(); + Bool_t mcFound = kFALSE; + if(fMC){ + Int_t label = esdTrack->GetLabel(); + AliMCParticle *mcTrack = dynamic_cast(fMC->GetTrack(label)); + Int_t pdg = GetPDG(species); + Int_t trackPdg = 0; + if(mcTrack){ + trackPdg = TMath::Abs(mcTrack->Particle()->GetPdgCode()); + } + if(pdg == trackPdg) mcFound = kTRUE; } - quantities[0] = p; - // case AOD (for the moment lacks) - if(HasRecalculateTRDpid()){ - RecalculateTRDpid(aodTrack, trdPidProbs); - quantities[1] = trdPidProbs[AliPID::kElectron]; + quantities[0] = pTPC; + Bool_t detFlagSet = kFALSE; + for(Int_t idet = 0; idet < 4; idet++){ + Char_t histname[256], histnameMC[256]; + sprintf(histname, "h%s_El_like_%s", detname[idet], specname); + sprintf(histnameMC, "h%s_El_like_MC_%s", detname[idet], specname); + switch(idet){ + case kITS: esdTrack->GetITSpid(pidProbs); + detFlagSet = status & AliESDtrack::kITSpid; + break; + case kTPC: esdTrack->GetTPCpid(pidProbs); + detFlagSet = status & AliESDtrack::kTPCpid; + break; + case kTRD: esdTrack->GetTRDpid(pidProbs); + detFlagSet = status & AliESDtrack::kTRDpid; + break; + case kTOF: esdTrack->GetTOFpid(pidProbs); + detFlagSet = status & AliESDtrack::kTOFpid; + break; + }; + quantities[1] = pidProbs[AliPID::kElectron]; + // in case of TRD require 6 PID tracklets + if(kTRD == idet && esdTrack->GetTRDntrackletsPID() != 6) continue; + if(detFlagSet){ + fOutput->Fill(histname, quantities[0], quantities[1]); + if(mcFound) + fOutput->Fill(histnameMC, quantities[0], quantities[1]); + } } - else - continue; - } - fOutput->Fill(hname, quantities[0], quantities[1]); - } + }//.. ESD + else{ + //AOD + }//.. aod + }//.. while tracks } //__________________________________________ void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){ @@ -382,102 +610,261 @@ void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){ // Fill the PID response of different detectors to V0 daughter particles // Char_t hname[256] = ""; + Char_t hname2[256] = ""; + Char_t hname3[256] = ""; + const Char_t *typeName[5] = {"Electron", "PionK0", "PionL", "Kaon", "Proton"}; const Int_t typePID[5] = {0, 2, 2, 3, 4}; - - AliHFEpidTRD *pidTRD = new AliHFEpidTRD("TRDpid"); - + + // PID THnSparse + // axes: + // 0) species, 1) momentum, 2) DCA xy, 3) DCA z + // 4) ITS signal + // 5) TPC Ncls 6) TPC signal 7) TPC nSigma, + // 8) TRD Ntrk, 9) TRD Ncls, 10) TRD dEdx, + + Double_t data[12]; + memset(data, -99, sizeof(Double_t) *12); + + Int_t run = fEvent->GetRunNumber(); + AliVParticle *recTrack = NULL; - TIterator *trackIter = particles->MakeIterator(); - while((recTrack = dynamic_cast(trackIter->Next()))){ + TIter trackIter(particles); + while((recTrack = dynamic_cast(trackIter()))){ + memset(data, -99, sizeof(Double_t) *10); // ESD if(!TString(recTrack->IsA()->GetName()).CompareTo("AliESDtrack")){ // case ESD AliESDtrack *esdTrack = dynamic_cast(recTrack); - const AliExternalTrackParam *tpcIn = esdTrack->GetTPCInnerParam(); - if(!tpcIn) continue; + if(!esdTrack) continue; - // track kinematics - Double_t p = tpcIn->P(); - //Double_t pt = tpcIn->Pt(); - - // TPC dEdx - Double_t dEdx = esdTrack->GetTPCsignal(); - sprintf(hname, "hTPC_dEdx_%s", typeName[species]); - fOutput->Fill(hname, p, dEdx); - - //TPC number of sigmas - Double_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack,(AliPID::EParticleType)typePID[species]); - sprintf(hname, "hTPCnSigma%s", typeName[species]); - fOutput->Fill(hname, p, nsigma); - - // TPC PID response - sprintf(hname, "hTPC_PID_p_%s", typeName[species]); - Double_t tpcPID[5] = {-1, -1, -1, -1, -1}; - esdTrack->GetTPCpid(tpcPID); - Int_t ix = 0; - Double_t tmp = 0.; - for(Int_t k=0; k<5; ++k){ - if(tpcPID[k] > tmp){ - ix = k; - tmp = tpcPID[k]; + // for the PID THnSparse + data[0] = species; + data[1] = esdTrack->P(); + Float_t impactR = -1.; + Float_t impactZ = -1.; + esdTrack->GetImpactParameters(impactR, impactZ); + data[2] = impactR; + data[3] = impactZ; + data[11] = 0; // initialize the TOF pid cut on elecgrons to false + // use ONLY tracks with PID flag TRUE + ULong_t status = 0; + status = esdTrack->GetStatus(); + + // + // DEBUG + // + + fOutput->Fill("hITS_kFlags", 5., species); + if(status & AliESDtrack::kITSin) fOutput->Fill("hITS_kFlags", 1., species); + if(status & AliESDtrack::kITSout) fOutput->Fill("hITS_kFlags", 2., species); + if(status & AliESDtrack::kITSrefit) fOutput->Fill("hITS_kFlags", 3., species); + if(status & AliESDtrack::kITSpid) fOutput->Fill("hITS_kFlags", 4., species); + + fOutput->Fill("hTPC_kFlags", 5., species); + if(status & AliESDtrack::kTPCin) fOutput->Fill("hTPC_kFlags", 1., species); + if(status & AliESDtrack::kTPCout) fOutput->Fill("hTPC_kFlags", 2., species); + if(status & AliESDtrack::kTPCrefit) fOutput->Fill("hTPC_kFlags", 3., species); + if(status & AliESDtrack::kTPCpid) fOutput->Fill("hTPC_kFlags", 4., species); + + fOutput->Fill("hTRD_kFlags", 5., species); + if(status & AliESDtrack::kTRDin) fOutput->Fill("hTRD_kFlags", 1., species); + if(status & AliESDtrack::kTRDout) fOutput->Fill("hTRD_kFlags", 2., species); + if(status & AliESDtrack::kTRDrefit) fOutput->Fill("hTRD_kFlags", 3., species); + if(status & AliESDtrack::kTRDpid) fOutput->Fill("hTRD_kFlags", 4., species); + + fOutput->Fill("hTOF_kFlags", 5., species); + if(status & AliESDtrack::kTOFin) fOutput->Fill("hTOF_kFlags", 1., species); + if(status & AliESDtrack::kTOFout) fOutput->Fill("hTOF_kFlags", 2., species); + if(status & AliESDtrack::kTOFrefit) fOutput->Fill("hTOF_kFlags", 3., species); + if(status & AliESDtrack::kTOFpid) fOutput->Fill("hTOF_kFlags", 4., species); + + + // + // ITS - + // + if(status & AliESDtrack::kITSpid){ + Double_t p = esdTrack->P(); + + // ITS signal + //Double_t itsSignal = esdTrack->GetITSsignal(); + + // ITS dEdx + Double_t dEdxSamples[4]; + esdTrack->GetITSdEdxSamples(dEdxSamples); + Int_t nSamples = 0; + Double_t dEdxSum = 0.; + sprintf(hname, "hITS_dEdx_%s", typeName[species]); + for(Int_t i=0; i<4; ++i){ + if(dEdxSamples[i] > 0){ + nSamples++; + fOutput->Fill(hname, i+1, p, dEdxSamples[i]); + dEdxSum += dEdxSamples[i]; + } } - fOutput->Fill("hTPC_PID", tpcPID[k], k); - } - if(tpcPID[ix] > 0){ + if(4 == nSamples)fOutput->Fill(hname, 0, p, dEdxSum); + fOutput->Fill("hITS_dEdx_nSamples", nSamples); + + Double_t signal = esdTrack->GetITSsignal(); + sprintf(hname, "hITS_Signal_%s", typeName[species]); + fOutput->Fill(hname, p, signal); + data[4] = signal; + + // ITS number of signas + Double_t nsigma = fESDpid->NumberOfSigmasITS(esdTrack,(AliPID::EParticleType)typePID[species]); + sprintf(hname, "hITS_nSigma_%s", typeName[species]); + fOutput->Fill(hname, p, nsigma); + + // ITS PID response + Double_t itsPID[5] = {-1, -1, -1, -1, -1}; + esdTrack->GetITSpid(itsPID); + Int_t ix = GetMaxPID(itsPID); + sprintf(hname, "hITS_PID_p_%s", typeName[species]); fOutput->Fill(hname, p, ix); - } + }//.. kITSpid + + // + // TPC + // + if(status & AliESDtrack::kTPCpid){ + // Make TPC clusters Plot + data[5] = esdTrack->GetTPCNcls(); + FillTPCinfo(esdTrack, species); - // TOF PID response - sprintf(hname, "hTOF_PID_p_%s", typeName[species]); - Double_t tofPID[5] = {-1., -1., -1., -1., -1}; - esdTrack->GetTOFpid(tofPID); - tmp = 0.; - for(Int_t k=0; k<5; ++k){ - if(tofPID[k] > tmp){ - ix = k; - tmp = tofPID[k]; - } - if(tofPID[k] > 0) - fOutput->Fill("hTOF_PID", tofPID[k], k); - } - if(tofPID[ix] > 0){ + Double_t p = esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(); + // TPC dEdx + Double_t dEdx = esdTrack->GetTPCsignal(); + sprintf(hname, "hTPC_dEdx_%s", typeName[species]); + fOutput->Fill(hname, p, dEdx); + data[6] = dEdx; + + //TPC number of sigmas + Double_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack,(AliPID::EParticleType)typePID[species]); + sprintf(hname, "hTPC_nSigma_%s", typeName[species]); + fOutput->Fill(hname, p, nsigma); + data[7] = nsigma; + + // TPC PID response + sprintf(hname, "hTPC_PID_p_%s", typeName[species]); + Double_t tpcPID[5] = {-1, -1, -1, -1, -1}; + esdTrack->GetTPCpid(tpcPID); + Int_t ix = GetMaxPID(tpcPID); + fOutput->Fill(hname, p, ix); + }//.. kTPCpid + + // + // TRD + // + + if(status & AliESDtrack::kTRDpid){ + Double_t p = esdTrack->GetOuterParam() ? esdTrack->GetOuterParam()->P() : esdTrack->P(); + + // TRD number of tracklets + Int_t ntrk = esdTrack->GetTRDntrackletsPID(); + sprintf(hname, "hTRD_trk_%s", typeName[species]); + fOutput->Fill(hname, p, ntrk); + data[8] = ntrk; + + // TRD PID response + sprintf(hname, "hTRD_PID_p_%s", typeName[species]); + Double_t trdPID[5] = {-1., -1., -1., -1., -1}; + esdTrack->GetTRDpid(trdPID); + Int_t ix = GetMaxPID(trdPID); fOutput->Fill(hname, p, ix); - } + // TRD n clusters + Int_t ncls = esdTrack->GetTRDncls(); + sprintf(hname, "hTRD_cls_%s", typeName[species]); + fOutput->Fill(hname, p, ncls); + data[9] = ncls; + + // TRD - per tracklet - dEdx per, likelihood + sprintf(hname, "hTRD_Nslc_%s", typeName[species]); + sprintf(hname2, "hTRD_slc_%s", typeName[species]); + sprintf(hname3, "hTRD_dEdx_%s", typeName[species]); + Int_t nSlices = esdTrack->GetNumberOfTRDslices(); + Double_t sumTot = 0.; + Int_t not0Tot = 0; + for(Int_t l=0; l< 6; ++l){ + Double_t trkData[7] = {-1.,-1, -1, -1, -1, -1, -1}; + trkData[0] = species; + trkData[1] = p; + trkData[2] = l; + trkData[3] = ntrk; + trkData[5] = ncls; + Double_t sum = 0.; + Int_t not0 = 0; + for(Int_t s=0; sGetTRDslice(l, s); + sum += slice; + if(slice > 0){ + not0 += 1; + fOutput->Fill(hname2, p, s); + } + }//..slices + + trkData[4] = not0; + fOutput->Fill(hname, p, not0); + fOutput->Fill(hname3, p, sum); + if(sum > 0){ + sumTot += sum; + not0Tot += 1; + } + // lkelihoods per layer + if(not0Tot > 0 && fNNref){ + Double_t likelihoods[5] = {-1., -1., -1., -1., -1}; + TRDlikeTracklet(l, esdTrack, likelihoods); + trkData[6] = likelihoods[0]; + //printf(" -D: species: %i, P; %f : %f, s: %f\n", species, p, likelihoods[0], s); + } + if(not0Tot) fOutput->Fill("hTRDtracklets", trkData); + }//..layers + // average dEx per number of tracklets + if(0 < not0Tot) + data[10] = sumTot / not0Tot; + }//.. kTRDpid - //TRD first electron only - Int_t nTRK = (int)esdTrack->GetTRDntrackletsPID(); - if(AliHFEV0pid::kRecoElectron == species){ - sprintf(hname, "hTRD_%s_trk", typeName[species]); - fOutput->Fill(hname, p, nTRK); - } - Char_t n1[256] = ""; - Char_t n2[256] = ""; - Double_t pidProbs[AliPID::kSPECIES]; - esdTrack->GetTRDpid(pidProbs); - Double_t threshold = pidTRD->GetTRDthresholds(0.9, p); - if(AliHFEV0pid::kRecoElectron == species && 6 == nTRK){ - sprintf(n1, "hTRD_%s_Y_like", typeName[species]); - sprintf(n2, "hTRD_%s_N_like", typeName[species]); - if(pidProbs[typePID[0]] > threshold) fOutput->Fill(n1, p); - else fOutput->Fill(n2, p); - sprintf(hname, "hTRD_El_like_Electron"); - fOutput->Fill(hname, p, pidProbs[typePID[species]]); - } - if( ((AliHFEV0pid::kRecoPionK0 == species) || (AliHFEV0pid::kRecoPionL == species)) && 6 == nTRK ){ - sprintf(hname, "hTRD_El_like_Pion"); - fOutput->Fill(hname, p, pidProbs[typePID[0]]); - } - if(AliHFEV0pid::kRecoProton == species && 6 == nTRK){ - sprintf(hname,"hTRD_El_like_Proton"); - fOutput->Fill(hname, p, pidProbs[typePID[0]]); - } - + + // + // TOF + // + if(status & AliESDtrack::kTOFpid){ + Double_t p = esdTrack->GetOuterParam() ? esdTrack->GetOuterParam()->P() : esdTrack->P(); + Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); + + //TOF beta + sprintf(hname, "hTOF_beta_%s", typeName[species]); + Float_t beta = TOFbeta(esdTrack); + fOutput->Fill(hname, p, beta); + fOutput->Fill("hTOF_beta_all", p, beta); + // TOF nSigma + Double_t nsigma = fESDpid->NumberOfSigmasTOF(esdTrack,(AliPID::EParticleType)typePID[species], t0); + sprintf(hname, "hTOF_nSigma_%s", typeName[species]); + fOutput->Fill(hname, p, nsigma); + if(beta > 0.97 && beta < 1.03){ + data[11] = 1; + } + + // TOF PID response + sprintf(hname, "hTOF_PID_p_%s", typeName[species]); + Double_t tofPID[5] = {-1., -1., -1., -1., -1}; + esdTrack->GetTOFpid(tofPID); + Int_t ix = GetMaxPID(tofPID); + fOutput->Fill(hname, p, ix); + + // time of flight QA + // - distribution of (time - t0 - pion_time) + Double_t times[5]; + esdTrack->GetIntegratedTimes(times); + Double_t tItrackL = esdTrack->GetIntegratedLength(); + Double_t tTOFsignal = esdTrack->GetTOFsignal(); + Double_t dT = tTOFsignal - t0 - times[2]; + fOutput->Fill("hTOF_qa_TmT0mT", run*1.0, dT); + fOutput->Fill("hTOF_qa_length", run*1.0, tItrackL); - //TOF beta - sprintf(hname, "hTOF_beta_%s", typeName[species]); - Float_t beta = TOFbeta(esdTrack); - fOutput->Fill(hname, beta, p); + + }//.. kTOFpid + // temporary - the PIDsparse needs rebuilding + //fOutput->Fill("PIDsparse", data); } // AOD - comming soon else{ @@ -485,10 +872,22 @@ void AliHFEpidQA::FillPIDresponse(TObjArray * const particles, Int_t species){ } }// .. tracks in TObjArray - if(pidTRD) delete pidTRD; } +//__________________________________________ +void AliHFEpidQA:: CheckEvent(){ + // + // check some event variables + // + // check the T0 as a function of run number (less than one bin per number + Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); + Int_t run = fEvent->GetRunNumber(); + Double_t data[2] = {run*1.0, t0*1000.}; + fOutput->Fill("hEvent_T0", data); + + +} //__________________________________________ TList *AliHFEpidQA::GetOutput(){ // @@ -517,86 +916,27 @@ TList *AliHFEpidQA::GetV0pidMC(){ //__________________________________________ void AliHFEpidQA::RecalculateTRDpid(AliESDtrack * /*track*/, Double_t * /*pidProbs*/) const{ -// fTRDpidResponse->MakePID(track); -// track->GetTRDpid(pidProbs); + // fTRDpidResponse->MakePID(track); + // track->GetTRDpid(pidProbs); } //__________________________________________ void AliHFEpidQA::RecalculateTRDpid(AliAODTrack * /*track*/, Double_t * /*pidProbs*/) const{ -// fTRDpidResponse->MakePID(track, pidProbs); -} -//___________________________________________________________________ -void AliHFEpidQA::CorrectT0(){ - // temporary solutions for correction the T0 for pass4 & pass5 - // returns corrected T0 for known runs - // returns 0 if the correction failed - if(! fRun > 0){ - AliError("Run number not set"); - fT0 = 0.; - return; - } - Bool_t runFound = kFALSE; - const Int_t corr[31][2] = {{104065, 1771614}, - {104068, 1771603}, - {104070, 1771594}, - {104073, 1771610}, - {104080, 1771305}, - {104083, 1771613}, - {104157, 1771665}, - {104159, 1771679}, - {104160, 1771633}, - {104316, 1764344}, - {104320, 1764342}, - {104321, 1764371}, - {104439, 1771750}, - {104792, 1771755}, - {104793, 1771762}, - {104799, 1771828}, - {104800, 1771788}, - {104801, 1771796}, - {104802, 1771775}, - {104803, 1771795}, - {104824, 1771751}, - {104825, 1771763}, - {104845, 1771792}, - {104852, 1771817}, - {104864, 1771825}, - {104865, 1771827}, - {104867, 1771841}, - {104876, 1771856}, - {104878, 1771847}, - {104879, 1771830}, - {104892, 1771837}}; - - for(Int_t i=0; i<31; ++i){ - if(fRun == corr[i][0]){ - runFound = kTRUE; - fT0 = (float)corr[i][1]; - // for the pass4 & pass5 - fT0 -= 37*1024*24.4 - 170.; - //.. - break; - } - } - - if(!runFound){ - TString error = "Setting T0 correction FAILED, no TOF pid available for run: "; - error += fRun; - AliError(error); - fT0 = 0.; - } - //cout<<" -D: run: "<MakePID(track, pidProbs); } //___________________________________________________________________ Float_t AliHFEpidQA::TOFbeta(AliESDtrack * const track) const { // computes the TOF beta Double_t l = track->GetIntegratedLength(); // cm Double_t t = track->GetTOFsignal(); - Double_t t0 = fT0; // ps + Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); // ps + + //printf("-D: l: %f, t: %f, t0: %f\n", l, t, t0); + if(l < 360. || l > 800.) return 0.; if(t <= 0.) return 0.; - if(t0 <= 0.) return 0.; + if(t0 >999990.0) return 0.; + t -= t0; // subtract the T0 @@ -609,4 +949,255 @@ Float_t AliHFEpidQA::TOFbeta(AliESDtrack * const track) const { return beta; } - +//____________________________________________ +Int_t AliHFEpidQA::GetMaxPID(Double_t *pidProbs) const { + // + // return the index of maximal PID probability + // + Int_t ix = -1; + Double_t tmp = 0.2; + for(Int_t i=0; i<5; ++i){ + if(pidProbs[i] > tmp){ + ix = i; + tmp = pidProbs[i]; + } + } + return ix; +} +//_____________________________________________ +Int_t AliHFEpidQA::GetPDG(Int_t species){ + // + // return the PDG particle code + // + + Int_t pdg = 0; + + switch(species){ + case AliHFEV0pid::kRecoElectron: + pdg = TMath::Abs(kElectron); + break; + case AliHFEV0pid::kRecoPionK0: + pdg = TMath::Abs(kPiPlus); + break; + case AliHFEV0pid::kRecoPionL: + pdg = TMath::Abs(kPiPlus); + break; + case AliHFEV0pid::kRecoProton: + pdg = TMath::Abs(kProton); + break; + default: // non investigated species + AliDebug(3, "Species not recognised"); + return 0; + } + + return pdg; + +} + +//_____________________________________________ +TObjArray * AliHFEpidQA::MakeTrackList(TObjArray *tracks) const { + // + // convert list of AliHFEV0Info into a list of AliVParticle + // + TObjArray *output = new TObjArray; + TIter trackInfos(tracks); + AliHFEV0info *trackInfo = NULL; + while((trackInfo = dynamic_cast(trackInfos()))) + output->Add(trackInfo->GetTrack()); + + return output; +} + +//_____________________________________________ +TObjArray * AliHFEpidQA::MakeCleanListElectrons(TObjArray *electrons) const { + // + // Cleanup electron sample using TPC PID + // PID requirement will allways be implemented to the pair + // Strategy + // + TObjArray *tracks = new TObjArray; + TIter candidates(electrons); + AliESDEvent *esd; AliAODEvent *aod; + AliHFEV0info *hfetrack; + if((esd = dynamic_cast(fEvent))){ + AliESDtrack *track = NULL, *partnerTrack = NULL; + while((hfetrack = dynamic_cast(candidates()))){ + track = dynamic_cast(hfetrack->GetTrack()); + partnerTrack = esd->GetTrack(hfetrack->GetPartnerID()); + Double_t nSigmaTrack = TMath::Abs(fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron)); + Double_t nSigmaPartner = TMath::Abs(fESDpid->NumberOfSigmasTPC(partnerTrack, AliPID::kElectron)); + if((nSigmaTrack < 1 && nSigmaPartner < 4) || (nSigmaTrack < 4 && nSigmaPartner < 1)) + tracks->Add(track); + } + } else { + aod = dynamic_cast(fEvent); + AliAODTrack *track = NULL, *partnerTrack = NULL; + while((hfetrack = dynamic_cast(candidates()))){ + track = dynamic_cast(hfetrack->GetTrack()); + partnerTrack = aod->GetTrack(hfetrack->GetPartnerID()); + // will be coming soon + } + } + return tracks; +} +//___________________________________________________________ +void AliHFEpidQA::CheckTenderV0pid(TObjArray * const particles, Int_t species){ + + // + // retrieve the status bits from the TObject used to flag + // the V0 daughter tracks and return the found PID + // 0 - electron, 1 - pion, 2 - proton + // + + const Int_t id[5] = {0, 1, 1, -1, 2}; // convert AliHFEpid to simple 0, 1, 2 + + AliVParticle *recTrack = NULL; + TIter trackIter(particles); + while((recTrack = dynamic_cast(trackIter()))){ + if(!TString(recTrack->IsA()->GetName()).CompareTo("AliESDtrack")){ + // case ESD + AliESDtrack *track = dynamic_cast(recTrack); + if(!track) continue; + Int_t tPID = GetTenderV0pid(track); + fOutput->Fill("h_tender_check_01", id[species]*1.0, tPID); + fOutput->Fill("h_tender_check_02", id[species], id[species]*1.0, tPID); + + } //.. case ESD + + }//.. iterate of tracks +} +//___________________________________________________________ +Int_t AliHFEpidQA::GetTenderV0pid(AliESDtrack * const track){ + // + // retrieve the PID nformation stored in the status flags by the train tender + // + + + Int_t pid = -1; + if(!track){ + return pid; + } + + Int_t nTimes = 0; + + if(track->TestBit(2<<14)){ + pid = 0; + nTimes++; + } + if(track->TestBit(2<<15)){ + pid = 1; + nTimes++; + } + if(track->TestBit(2<<16)){ + pid = 2; + nTimes++; + } + + if(nTimes > 1){ + AliWarning("V0 track labeled multiple times by the V0 tender"); + pid = -1; + } + + return pid; + +} +//___________________________________________________________ +Double_t AliHFEpidQA::TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Double_t *likelihood){ + // + // compute the TRD electron likelihoods for 1 tracklet + // based on teh AliTRDpidRecalculator in train/until/tender + // returns sum of the likelihoods (which should be 1) + // + + const Double_t cScaleGain = 1./ 16000.; + const Float_t pBins[11] ={0.6, 0.8, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0}; // momentum bins + + if(!track) return kFALSE; + Float_t p = track->GetTRDmomentum(layer); // momentum for a tracklet in the ESDtrack + if(p < 0) return kFALSE; + + Int_t mombin = TRDmomBin(p); // momentum bin + Float_t dEdxTRDsum = 0; // dEdxTRDsum for checking if tracklet is available + Float_t dEdxTRD[8]; // dEdx for a tracklet in the ESD slices + Double_t ddEdxTRD[8]; // dEdx as Double_t for TMultiLayerPerceptron::Evaluate() + + Double_t prob[AliPID::kSPECIES]; // probabilities for all species in all layers + + for(Int_t is = 0; is < AliPID::kSPECIES; is++){ + likelihood[is] = 0.2; // init probabilities + prob[is] = 0.2; + } + + Double_t sum = 0.; + + for(Int_t islice = 0; islice<8; islice++){ + dEdxTRD[islice]=0.; // init dE/dx + ddEdxTRD[islice]=0.; // init dE/dx + dEdxTRD[islice]=track->GetTRDslice(layer,islice); // get the dE/dx values + dEdxTRDsum += dEdxTRD[islice]; + ddEdxTRD[islice]=(Double_t)dEdxTRD[islice]*cScaleGain; // rescale dE/dx + + } + for(Int_t is = 0; is < AliPID::kSPECIES; is++){ + Double_t probloc1, probloc2; + if(mombin == 0 && mombin < pBins[0]){ // calculate PID for p > 0.6 GeV/c + prob[is] = fNet[mombin]->Evaluate(is, ddEdxTRD); + } + else if(mombin == 10 && mombin >= pBins[10]){ // calculate PID for p >= 10.0 GeV/c + prob[is] = fNet[mombin]->Evaluate(is, ddEdxTRD); + } + else{ // standard calculation + Int_t mombin1 = 0, mombin2 = 0; // lower and upper momentum bin + if(p < pBins[mombin]) {mombin1 = mombin -1; mombin2 = mombin;} + if(p >= pBins[mombin]) {mombin1 = mombin; mombin2 = mombin+1;} + probloc1 = fNet[mombin1]->Evaluate(is, ddEdxTRD); + probloc2 = fNet[mombin2]->Evaluate(is, ddEdxTRD); + // weighting of the probability with regard to the track momentum + prob[is] = probloc1 + (probloc2-probloc1)*(p-pBins[mombin1])/(pBins[mombin2]-pBins[mombin1]); + } + likelihood[is] = prob[is]; + sum += likelihood[is]; + } + + return sum; +} +//__________________________________________________________________________ +Int_t AliHFEpidQA::TRDmomBin(Double_t p){ + // + // compute the momentum bin position + // + + const Float_t pBins[11] ={0.6, 0.8, 1.0, 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0}; // momentum bins + + Int_t pBin1 = -1; // check bin1 + Int_t pBin2 = -1; // check bin2 + + if(p < 0) return -1; // return -1 if momentum < 0 + if(p < pBins[0]) return 0; // smallest momentum bin + if(p >= pBins[10]) return 10; // largest momentum bin + + + // calculate momentum bin for non extremal momenta + for(Int_t iMomBin = 1; iMomBin < 11; iMomBin++){ + if(p < pBins[iMomBin]){ + pBin1 = iMomBin - 1; + pBin2 = iMomBin; + } + else + continue; + + if(p - pBins[pBin1] >= pBins[pBin2] - p){ + return pBin2; + } + else{ + return pBin1; + } + } + + return -1; + + +} +//__________________________________________________________________________ + + diff --git a/PWG3/hfe/AliHFEpidQA.h b/PWG3/hfe/AliHFEpidQA.h index 0434c56cccd..9c2c2b21a9a 100644 --- a/PWG3/hfe/AliHFEpidQA.h +++ b/PWG3/hfe/AliHFEpidQA.h @@ -27,24 +27,36 @@ class TList; class TObjArray; +class TPDGCode; +class TParticle; +class TFile; +class TMultiLayerPerceptron; class AliAODTrack; class AliESDtrack; -class AliHFEcollection; -class AliHFEV0pid; class AliMCEvent; -//class AliTRDPIDResponseLQ1D; class AliVEvent; class AliESDpid; +class AliExternalTrackParam; +class AliLog; + class AliHFEV0pidMC; +class AliHFEcollection; +class AliHFEtrdPIDqa; +class AliHFEV0pid; +class AliHFEpidTRD; + class AliHFEpidQA : public TObject{ public: AliHFEpidQA(); ~AliHFEpidQA(); + AliHFEpidQA(const AliHFEpidQA &ref); + AliHFEpidQA &operator=(const AliHFEpidQA &ref); + virtual void Copy(TObject &o) const; void Init(); - void Process(AliVEvent *inputEvent); + void Process(); TList *GetOutput(); TList *GetV0pidQA(); @@ -53,15 +65,18 @@ class AliHFEpidQA : public TObject{ Bool_t HasV0pidQA() const { return TestBit(kV0pidQA); }; Bool_t HasRecalculateTRDpid() const { return TestBit(kRecalculateTRDpid); }; + void SetEvent(AliVEvent* const ev) { fEvent = ev; }; void SetMCEvent(AliMCEvent * const mc) { fMC = mc; }; void SetV0pidQA(Bool_t v0pidQA = kTRUE) { SetBit(kV0pidQA, v0pidQA); }; void SetRecalculateTRDpid(Bool_t recal = kTRUE) { SetBit(kRecalculateTRDpid, recal); }; - void SetRun(Int_t run) { fRun = run; }; - // temporary solutions for correction the T0 for pass4 & pass5 - void CorrectT0(); - void SetT0(Float_t t0) { fT0 = t0; }; - Float_t TOFbeta(AliESDtrack *const track) const; + void SetESDpid(AliESDpid* const pid) { fESDpid = pid; } + Float_t TOFbeta(AliESDtrack* const track) const; + + void CheckEvent(); + void SetNNref(TFile *f) { fNNref = f; }; + + AliHFEtrdPIDqa *GetTRDQA() const { return fTRDpidQA; } protected: enum{ @@ -72,27 +87,41 @@ class AliHFEpidQA : public TObject{ kITS = 0, kTPC = 1, kTRD = 2, - kTOF = 4 + kTOF = 3 }; + TObjArray *MakeTrackList(TObjArray *tracks) const; + TObjArray *MakeCleanListElectrons(TObjArray *tracks) const; + void MakePurity(TObjArray *tracks, Int_t species); - void FillTRDelectronLikelihoods(TObjArray * const particles, Int_t species); + TObjArray *MakeCleanListForTRD(TObjArray * const track, Int_t species); + void FillElectronLikelihoods(TObjArray * const particles, Int_t species); void FillPIDresponse(TObjArray * const particles, Int_t species); + void FillIllumination(TObjArray *const particles, Int_t species); + void FillTPCinfo(AliESDtrack * const track, Int_t species); void RecalculateTRDpid(AliESDtrack *track, Double_t *pidProbs) const; void RecalculateTRDpid(AliAODTrack *track, Double_t *pidProbs) const; + void CheckTenderV0pid(TObjArray * const particles, Int_t species); + Int_t GetTenderV0pid(AliESDtrack * const track); + + Double_t TRDlikeTracklet(Int_t layer, AliESDtrack * const track, Double_t *likelihood); + Int_t TRDmomBin(Double_t p); + protected: + Int_t GetMaxPID(Double_t *pidProbs) const; + Int_t GetPDG(Int_t index); + private: - AliHFEpidQA(const AliHFEpidQA &ref); - AliHFEpidQA &operator=(const AliHFEpidQA &ref); - + AliVEvent *fEvent; // event pointer AliMCEvent *fMC; // MC Event AliHFEV0pid *fV0pid; // V0 PID AliHFEV0pidMC *fV0pidMC; // V0 MC PID - //AliTRDPIDResponseLQ1D *fTRDpidResponse; // TRD PID + AliHFEtrdPIDqa *fTRDpidQA; //! TRD PID QA object AliHFEcollection *fOutput; // Output container - Float_t fT0; // corrected T0 for pass4 & pass5 - Int_t fRun; // Run Number - AliESDpid *fESDpid; // ESD PID object + AliESDpid *fESDpid; // ESD PID object + private: + TFile *fNNref; // reference file for NN pid + TMultiLayerPerceptron *fNet[11]; // reference networks ClassDef(AliHFEpidQA, 1) // PID QA tool }; diff --git a/PWG3/hfe/AliHFEpidTOF.cxx b/PWG3/hfe/AliHFEpidTOF.cxx index 11e10e9d635..a29990a2e34 100644 --- a/PWG3/hfe/AliHFEpidTOF.cxx +++ b/PWG3/hfe/AliHFEpidTOF.cxx @@ -22,18 +22,19 @@ // Matus Kalisky (contact) // -#include #include #include +#include +#include #include "AliAODTrack.h" #include "AliAODMCParticle.h" #include "AliESDtrack.h" -#include "AliLog.h" #include "AliMCParticle.h" #include "AliPID.h" #include "AliESDpid.h" +#include "AliHFEcollection.h" #include "AliHFEpidTOF.h" #include "AliHFEpidBase.h" @@ -45,22 +46,17 @@ AliHFEpidTOF::AliHFEpidTOF(const Char_t *name): AliHFEpidBase(name) , fPID(0x0) , fQAList(0x0) - , fESDpid(NULL) , fNsigmaTOF(3) { // // Constructor // - - fESDpid = new AliESDpid; - } //___________________________________________________________________ AliHFEpidTOF::AliHFEpidTOF(const AliHFEpidTOF &c): AliHFEpidBase("") , fPID(0x0) , fQAList(0x0) - , fESDpid(NULL) , fNsigmaTOF(3) { // @@ -87,7 +83,6 @@ AliHFEpidTOF::~AliHFEpidTOF(){ // Destructor // if(fPID) delete fPID; - if(fESDpid) delete fESDpid; if(fQAList){ fQAList->Delete(); delete fQAList; @@ -102,7 +97,6 @@ void AliHFEpidTOF::Copy(TObject &ref) const { target.fPID = fPID; target.fQAList = fQAList; - target.fESDpid = new AliESDpid(*fESDpid); AliHFEpidBase::Copy(ref); } @@ -131,7 +125,7 @@ Int_t AliHFEpidTOF::IsSelected(AliHFEpidObject *vtrack) AliESDtrack *esdTrack = dynamic_cast(vtrack->fRecTrack); if(!esdTrack) return 0; AliMCParticle *mcTrack = dynamic_cast(vtrack->fMCtrack); - return MakePIDesd(esdTrack, mcTrack); + return MakePIDesdV3(esdTrack, mcTrack); } else { AliAODTrack *aodTrack = dynamic_cast(vtrack->fRecTrack); if(!aodTrack) return 0; @@ -145,31 +139,35 @@ Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){ // // Does particle identification as discribed in IsSelected // + if(!fESDpid){ + AliError("No ESD PID object available"); + return kFALSE; + } Long_t status = 0; status = track->GetStatus(); if(!(status & AliESDtrack::kTOFout)) return 0; - if(IsQAon())(dynamic_cast(fQAList->At(kHistTOFpidFlags)))->Fill(0.); + if(IsQAon()) fQAList->Fill("hTOF_flags", 0.); Double_t tItrackL = track->GetIntegratedLength(); Double_t tTOFsignal = track->GetTOFsignal(); if(IsQAon()){ if(tItrackL > 0) - (dynamic_cast(fQAList->At(kHistTOFpidFlags)))->Fill(1.); + fQAList->Fill("hTOF_flags", 1.); if(tTOFsignal > 0) - (dynamic_cast(fQAList->At(kHistTOFpidFlags)))->Fill(2.); + fQAList->Fill("hTOF_flags", 2.); } if(tItrackL <=0 || tTOFsignal <=0) return 0; if(IsQAon()){ - (dynamic_cast(fQAList->At(kHistTOFpidFlags)))->Fill(3.); - (dynamic_cast(fQAList->At(kHistTOFsignal)))->Fill(tTOFsignal/1000.); - (dynamic_cast(fQAList->At(kHistTOFlength)))->Fill(tItrackL); + fQAList->Fill("hTOF_flags", 3.); + fQAList->Fill("hTOF_signal", tTOFsignal/1000.); + fQAList->Fill("hTOF_length", tItrackL); } // get the TOF pid probabilities Double_t tESDpid[5] = {0., 0., 0., 0., 0.}; @@ -188,12 +186,13 @@ Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){ Int_t pdg = 0; + TString specname; switch(tMAXindex){ - case 0: pdg = 11; break; - case 1: pdg = 13; break; - case 2: pdg = 211; break; - case 3: pdg = 321; break; - case 4: pdg = 2212; break; + case 0: pdg = 11; specname = "electron"; break; + case 1: pdg = 13; specname = "muon"; break; + case 2: pdg = 211; specname = "pion"; break; + case 3: pdg = 321; specname = "kaon"; break; + case 4: pdg = 2212; specname = "proton"; break; default: pdg = 0; }; @@ -211,13 +210,146 @@ Int_t AliHFEpidTOF::MakePIDesd(AliESDtrack *track, AliMCParticle * /*mcTrack*/){ // should be the same as AliPID flags if(IsQAon()){ - (dynamic_cast(fQAList->At(kHistTOFpid0+tMAXindex)))->Fill(beta, p); - (dynamic_cast(fQAList->At(kHistTOFpidBetavP)))->Fill(beta, p); + TString histname = "hTOFpid_" + specname; + fQAList->Fill(histname.Data(), beta, p); + fQAList->Fill("fTOFbeta_v_P_no", beta, p); } //return tMAXindex; return pdg; } +//__________________________________________________________________ +Int_t AliHFEpidTOF::MakePIDesdV2(AliESDtrack *track, AliMCParticle * /*mcTrack*/){ + // + // Computes the PID response based on TOF & T0 signal + // + + if(!fESDpid){ + AliError("No ESD PID object available"); + return kFALSE; + } + Long_t status = 0; + status = track->GetStatus(); + if(!(status & AliESDtrack::kTOFpid)) return 0; + + Double_t p = track->GetOuterParam()->P(); + // track integrated times for 5 different hypothesis and T0 time + Double_t times[5]; + track->GetIntegratedTimes(times); + Double_t tItrackL = track->GetIntegratedLength(); + Double_t tTOFsignal = track->GetTOFsignal(); + Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); + //printf("-D: tof: %f, T0: %f\n", tTOFsignal, t0); + // suppress missing or wrong T0 information + if(t0 > 999990.0) return 0; + Double_t tof = tTOFsignal - t0; + Double_t beta = (tItrackL/100.)/((TMath::C()*tof)/1e12); + //if(IsQAon())fQAList->Fill("hTOFbetaV2all", p, beta); + + const Int_t pdg[5] = {11, 13, 211, 321, 2212}; + const Double_t invMass[5] = {TDatabasePDG::Instance()->GetParticle(11)->Mass(), + TDatabasePDG::Instance()->GetParticle(13)->Mass(), + TDatabasePDG::Instance()->GetParticle(211)->Mass(), + TDatabasePDG::Instance()->GetParticle(321)->Mass(), + TDatabasePDG::Instance()->GetParticle(2212)->Mass()}; + + + // accepted beta bands as function of momentum - parameters + // line: par[0]/p + par[1] + expected_tof + const Double_t bMin[5][2] = {{0., -0.03}, {-0.005, -0.02}, {-0.005, -0.02}, {-0.02, -0.006}, {-0.03, -0.005}}; + const Double_t bMax[5][2] = {{0., 0.03}, {0.005, 0.02}, {0.005, 0.02}, {0.02, 0.006}, {0.03, 0.005}}; + + Int_t index = -1; + Double_t rdiff = 1.; + for(Int_t i=0; i<5; ++i){ + Double_t d = (TMath::Abs(times[i] - tof))/times[i]; + if(d < rdiff){ + rdiff = d; + index = i; + } + } + + // stupid and unnecessary complicated - to be improved soon + Double_t a = p/(invMass[index]); + a *= a; + Double_t betaMatch = TMath::Sqrt(a/(1+a)); + + // check wheter the most probable match is within allowed region of beta for given momentum and species + Double_t min = bMin[index][0]/p + bMin[index][1] + betaMatch; + Double_t max = bMax[index][0]/p + bMax[index][1] + betaMatch; + + // debug + //printf("-D: p: %f, beta: %f, pdg: %i, min: %f, max: %f\n", p, beta, pdg[index], min, max); + + // + // PID decision - can be simpler than the QA histograms above could indicate ! + // + + // suppress nonsense + if(beta < 0.2) return 0; + + // 1) Simple version - protect electrons + if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){ + //if(IsQAon())fQAList->Fill("hTOFbetaV2electron", p, beta); + return 11; + } + else return 0; + + + // NOT ACTIVE when (1) activated + // 2) more complex version - return true PID of the particle based on the best TOF estimate + // under development - still keep protecting electrons + if(beta > (1+bMin[0][1]) && beta < (1+bMax[0][1])){ + if(IsQAon())fQAList->Fill("hTOFbetaV2_electron", p, beta); + return 11; + } + // above 3 GeV/c the supression gets weak + if(p > 3.0) return 0; + if(beta > min && beta < max) { + if(IsQAon())fQAList->Fill("hTOFbetaV2selected", p, beta); + return pdg[index]; + } + + + return 0; +} + +//___________________________________________________________________ +Int_t AliHFEpidTOF::MakePIDesdV3(AliESDtrack *track, AliMCParticle * /*mctrack*/){ + // + // TOF PID based on n-Sigma cut + // Selects Protons and Kaons via n-sigma cut up to 3 GeV/c + // In addition histos for n-sigma before (all species) and after (only closest species) are filled + // + if(!fESDpid){ + AliError("No ESD pid Object available. Return"); + return 0; + } + if(!(track->GetStatus() & AliESDtrack::kTOFpid)) return 0; + Double_t t0 = fESDpid->GetTOFResponse().GetTimeZero(); + Double_t p = track->GetOuterParam() ? track->GetOuterParam()->P() : track->P(); + + // Fill before selection + Double_t sigEle = fESDpid->NumberOfSigmasTOF(track, AliPID::kElectron, t0); + //printf("-D: p: %f, t0: %f, nSigma: %f\n", p, t0, sigEle); + Int_t pdg = 0; + if(TMath::Abs(sigEle) < fNsigmaTOF) + pdg = 11; + if(IsQAon()){ + Double_t hcontent[3] = {p, sigEle, 0}; + hcontent[0] = p; + hcontent[1] = sigEle; + hcontent[2] = 0; + THnSparseF * hptr = dynamic_cast(fQAList->Get("hTOFsigmaElectron")); + hptr->Fill(hcontent); + if(pdg == 11){ + hcontent[2] = 1; + hptr->Fill(hcontent); + } + } + + return pdg; +} //___________________________________________________________________ Double_t AliHFEpidTOF::Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig){ @@ -259,19 +391,28 @@ void AliHFEpidTOF::AddQAhistograms(TList *qaList){ // Create QA histograms for TOF PID // - fQAList = new TList; - fQAList->SetName("fTOFqaHistos"); - fQAList->AddAt(new TH1F("hTOF_flags", "TOF flags;flags (see code for info);counts", 10, -0.25, 4.75), kHistTOFpidFlags); - fQAList->AddAt(new TH2F("fTOFbeta_v_P_no","beta -v- P; beta;momentum [GeV/c]", 120, 0, 1.2, 200, 0, 20), kHistTOFpidBetavP); - fQAList->AddAt(new TH1F("hTOF_signal", "TOF signal; TOF signal [ns];counts", 1000, 12, 50), kHistTOFsignal); - fQAList->AddAt(new TH1F("hTOF_length", "TOF track length; length [cm];counts", 400, 300, 700), kHistTOFlength); - fQAList->AddAt(new TH2F("hTOFpid_electron", "TOF reco electron; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid0); - fQAList->AddAt(new TH2F("hTOFpid_muon", "TOF reco muon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid1); - fQAList->AddAt(new TH2F("hTOFpid_pion", "TOF reco pion; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid2); - fQAList->AddAt(new TH2F("hTOFpid_kaon", "TOF reco kaon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid3); - fQAList->AddAt(new TH2F("hTOFpid_proton", "TOF reco proton; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5), kHistTOFpid4); - - qaList->AddLast(fQAList); + fQAList = new AliHFEcollection("TOFqaHistos", "Collection for TOF PID histograms"); + //fQAList->SetName("fTOFqaHistos"); + fQAList->CreateTH1F("hTOF_flags", "TOF flags;flags (see code for info);counts", 10, -0.25, 4.75); + fQAList->CreateTH2F("fTOFbeta_v_P_no","beta -v- P; beta;momentum [GeV/c]", 120, 0, 1.2, 200, 0, 20); + fQAList->CreateTH1F("hTOF_signal", "TOF signal; TOF signal [ns];counts", 1000, 12, 50); + fQAList->CreateTH1F("hTOF_length", "TOF track length; length [cm];counts", 400, 300, 700); + fQAList->CreateTH2F("hTOFpid_electron", "TOF reco electron; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); + fQAList->CreateTH2F("hTOFpid_muon", "TOF reco muon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); + fQAList->CreateTH2F("hTOFpid_pion", "TOF reco pion; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); + fQAList->CreateTH2F("hTOFpid_kaon", "TOF reco kaon; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); + fQAList->CreateTH2F("hTOFpid_proton", "TOF reco proton; beta ; momentum [GeV/c]", 120, 0, 1.2, 200, 0, 5); + //fQAList->CreateTH2F("hTOFbetaV2all", "TOF #beta vs p for all tracks; momentum [GeV/c]; beta ", 400, 0.1, 10., 1200, 0, 1.2, 0); + //fQAList->CreateTH2F("hTOFbetaV2electron", "TOF #beta vs p for selected electron tracks; momentum [GeV/c]; beta", 400, 0.1, 10., 1200, 0, 1.2, 0); + + // histograms for sigma cut + const Int_t kNdim= 3; + Int_t nBins[kNdim] = {1000, 1400, 2}; + Double_t binMin[kNdim] = {0.1, -12., 0}; + Double_t binMax[kNdim] = {20, 12., 2}; + fQAList->CreateTHnSparse("hTOFsigmaElectron", "TOF N#sigma around the Electron Line for all tracks; p (GeV/c); N sigma; Selection Step", kNdim, nBins, binMin, binMax); + + qaList->AddLast(fQAList->GetList()); } diff --git a/PWG3/hfe/AliHFEpidTOF.h b/PWG3/hfe/AliHFEpidTOF.h index 234816efd2e..a64b1b7dd7c 100644 --- a/PWG3/hfe/AliHFEpidTOF.h +++ b/PWG3/hfe/AliHFEpidTOF.h @@ -21,6 +21,9 @@ class AliAODMCParticle; class AliESDtrack; class AliMCParticle; class AliESDpid; +class AliLog; + +class AliHFEcollection; class AliHFEpidTOF : public AliHFEpidBase{ public: @@ -41,6 +44,8 @@ class AliHFEpidTOF : public AliHFEpidBase{ void Copy(TObject &ref) const; void AddQAhistograms(TList *qaHist); Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack); + Int_t MakePIDesdV2(AliESDtrack *esdTrack, AliMCParticle *mcTrack); + Int_t MakePIDesdV3(AliESDtrack *esdTrack, AliMCParticle *mcTrack); Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack); private: @@ -57,10 +62,9 @@ class AliHFEpidTOF : public AliHFEpidBase{ } QAHist_t; AliPID *fPID; //! PID Object - TList *fQAList; //! QA histograms - AliESDpid *fESDpid; //! ESD pid object + AliHFEcollection *fQAList; //! QA histograms - Short_t fNsigmaTOF; // TOF sigma band + Short_t fNsigmaTOF; // TOF sigma band ClassDef(AliHFEpidTOF, 1) }; diff --git a/PWG3/hfe/AliHFEpidTPC.cxx b/PWG3/hfe/AliHFEpidTPC.cxx index c8bdd8d1089..41cae9411e5 100644 --- a/PWG3/hfe/AliHFEpidTPC.cxx +++ b/PWG3/hfe/AliHFEpidTPC.cxx @@ -25,10 +25,10 @@ // Markus Fasel // Markus Heide // -#include +#include #include #include -//#include +#include #include "AliAODTrack.h" #include "AliAODMCParticle.h" @@ -38,12 +38,11 @@ #include "AliMCParticle.h" #include "AliPID.h" #include "AliESDpid.h" -//#include "AliVParticle.h" #include "AliHFEcollection.h" #include "AliHFEpidTPC.h" - +ClassImp(AliHFEpidTPC) //___________________________________________________________________ AliHFEpidTPC::AliHFEpidTPC(const char* name) : @@ -51,10 +50,11 @@ AliHFEpidTPC::AliHFEpidTPC(const char* name) : AliHFEpidBase(name) , fLineCrossingType(0) , fLineCrossingsEnabled(0) + , fUpperSigmaCut(NULL) + , fLowerSigmaCut(NULL) , fNsigmaTPC(3) , fRejectionEnabled(0) , fPID(NULL) - , fESDpid(NULL) , fQAList(NULL) { // @@ -64,7 +64,6 @@ AliHFEpidTPC::AliHFEpidTPC(const char* name) : memset(fPAsigCut, 0, sizeof(Float_t) * 2); memset(fNAsigmaTPC, 0, sizeof(Float_t) * 2); fPID = new AliPID; - fESDpid = new AliESDpid; } //___________________________________________________________________ @@ -72,10 +71,11 @@ AliHFEpidTPC::AliHFEpidTPC(const AliHFEpidTPC &ref) : AliHFEpidBase("") , fLineCrossingType(0) , fLineCrossingsEnabled(0) + , fUpperSigmaCut(NULL) + , fLowerSigmaCut(NULL) , fNsigmaTPC(2) , fRejectionEnabled(0) , fPID(NULL) - , fESDpid(NULL) , fQAList(NULL) { // @@ -94,7 +94,6 @@ AliHFEpidTPC &AliHFEpidTPC::operator=(const AliHFEpidTPC &ref){ } return *this; } - //___________________________________________________________________ void AliHFEpidTPC::Copy(TObject &o) const{ // @@ -104,10 +103,11 @@ void AliHFEpidTPC::Copy(TObject &o) const{ AliHFEpidTPC &target = dynamic_cast(o); target.fLineCrossingsEnabled = fLineCrossingsEnabled; + target.fUpperSigmaCut = fUpperSigmaCut; + target.fLowerSigmaCut = fLowerSigmaCut; target.fNsigmaTPC = fNsigmaTPC; target.fRejectionEnabled = fRejectionEnabled; target.fPID = new AliPID(*fPID); - target.fESDpid = new AliESDpid(*fESDpid); target.fQAList = new AliHFEcollection(*fQAList); memcpy(target.fLineCrossingSigma, fLineCrossingSigma, sizeof(Double_t) * AliPID::kSPECIES); memcpy(target.fPAsigCut, fPAsigCut, sizeof(Float_t) * 2); @@ -122,7 +122,6 @@ AliHFEpidTPC::~AliHFEpidTPC(){ // Destructor // if(fPID) delete fPID; - if(fESDpid) delete fESDpid; if(fQAList){ delete fQAList; } @@ -163,11 +162,12 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){ // // Doing TPC PID as explained in IsSelected for ESD tracks // - Float_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron); - if(IsQAon()){ - FillTPChistograms(esdTrack, mctrack); - fQAList->Fill("fHistSigmaElectronAll", esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(), nsigma); + if(!fESDpid){ + AliError("No ESD PID object available"); + return kFALSE; } + Float_t nsigma = fESDpid->NumberOfSigmasTPC(esdTrack, AliPID::kElectron); + if(IsQAon()) FillTPChistograms(esdTrack, mctrack, kFALSE); // exclude crossing points: // Determine the bethe values for each particle species Bool_t isLineCrossing = kFALSE; @@ -189,21 +189,21 @@ Int_t AliHFEpidTPC::MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mctrack){ Int_t reject = Reject(esdTrack); if(reject != 0) return reject; } - // Check whether distance from the electron line is smaller than n-sigma - // Perform Asymmetric n-sigma cut if required, else perform symmetric TPC sigma cut - Float_t p = 0.; + // Check if we have an asymmetric sigma model set Int_t pdg = 0; - if(HasAsymmetricSigmaCut() && (p = esdTrack->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ - if(nsigma >= fNAsigmaTPC[0] && nsigma <= fNAsigmaTPC[1]) pdg = 11; - } else { - if(TMath::Abs(nsigma) < fNsigmaTPC ) pdg = 11; - } - if(IsQAon() && pdg != 0){ - fQAList->Fill("fHistTPCselected", esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(), esdTrack->GetTPCsignal()); - fQAList->Fill("fHistSigmaElectronSelected", esdTrack->GetInnerParam() ? esdTrack->GetInnerParam()->P() : esdTrack->P(), nsigma); + if(fUpperSigmaCut || fLowerSigmaCut){ + pdg = CutSigmaModel(esdTrack) ? 11 : 0; + } else { + // Perform Asymmetric n-sigma cut if required, else perform symmetric TPC sigma cut + Float_t p = 0.; + if(HasAsymmetricSigmaCut() && (p = esdTrack->P()) >= fPAsigCut[0] && p <= fPAsigCut[1]){ + if(nsigma >= fNAsigmaTPC[0] && nsigma <= fNAsigmaTPC[1]) pdg = 11; + } else { + if(TMath::Abs(nsigma) < fNsigmaTPC ) pdg = 11; + } } - + if(IsQAon() && pdg != 0) FillTPChistograms(esdTrack, mctrack, kTRUE); return pdg; } @@ -213,6 +213,19 @@ Int_t AliHFEpidTPC::MakePIDaod(AliAODTrack * /*aodTrack*/, AliAODMCParticle * /* return 0; } +//___________________________________________________________________ +Bool_t AliHFEpidTPC::CutSigmaModel(AliESDtrack *track){ + // + // N SigmaCut using parametrization of the cuts + // + Bool_t isSelected = kTRUE; + Float_t nsigma = fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron); + Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P(); + if(fUpperSigmaCut && nsigma > fUpperSigmaCut->Eval(p)) isSelected = kFALSE; + if(fLowerSigmaCut && nsigma < fLowerSigmaCut->Eval(p)) isSelected = kFALSE; + return isSelected; +} + //___________________________________________________________________ Int_t AliHFEpidTPC::Reject(AliESDtrack *track){ // @@ -294,7 +307,7 @@ Double_t AliHFEpidTPC::Suppression(const AliESDtrack *track, Int_t species) } //___________________________________________________________________ -void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack){ +void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected){ // // Fill the QA histogtrams // @@ -303,51 +316,48 @@ void AliHFEpidTPC::FillTPChistograms(const AliESDtrack *track, const AliMCPartic Double_t tpcSignal = track->GetTPCsignal(); Double_t p = track->GetInnerParam() ? track->GetInnerParam()->P() : track->P(); - if(HasMCData()){ + Int_t species = -1; + THnSparse *hptr = NULL; + if(HasMCData() && mctrack){ switch(TMath::Abs(mctrack->Particle()->GetPdgCode())){ - case 11: fQAList->Fill("fHistTPCelectron", p, tpcSignal); - fQAList->Fill("fHistTPCprobEl", p, Likelihood(track, 0)); - //histograms with ratio of likelihood to be electron/to be other species (a check for quality of likelihood PID); - fQAList->Fill("fHistTPCenhanceElPi", p, -Suppression(track, 2)); - fQAList->Fill("fHistTPCenhanceElMu", p, -Suppression(track, 1)); - fQAList->Fill("fHistTPCenhanceElKa", p, -Suppression(track, 3)); - fQAList->Fill("fHistTPCenhanceElPro", p, -Suppression(track, 4)); - //___________________________________________________________________________________________ - //Likelihoods for electrons to be other particle species - fQAList->Fill("fHistTPCElprobPi", p, Likelihood(track, 2)); - fQAList->Fill("fHistTPCElprobMu", p, Likelihood(track, 1)); - fQAList->Fill("fHistTPCElprobKa", p, Likelihood(track, 3)); - fQAList->Fill("fHistTPCElprobPro", p, Likelihood(track, 4)); - break; - //___________________________________________________________________________________________ - case 13: fQAList->Fill("fHistTPCmuon", p, tpcSignal); - //Likelihood of muon to be an electron - fQAList->Fill("fHistTPCprobMu", p, Likelihood(track, 0)); - //ratio of likelihood for muon to be a muon/an electron -> indicator for quality of muon suppression - //below functions are the same for other species - fQAList->Fill("fHistTPCsuppressMu", p, Suppression(track, 1)); - break; - case 211: fQAList->Fill("fHistTPCpion", p, tpcSignal); - fQAList->Fill("fHistTPCprobPi", p, Likelihood(track, 0)); - fQAList->Fill("fHistTPCsuppressPi", p, Suppression(track, 2)); - break; - case 321: fQAList->Fill("fHistTPCkaon", p, tpcSignal); - fQAList->Fill("fHistTPCprobKa", p, Likelihood(track, 0)); - fQAList->Fill("fHistTPCsuppressKa", p, Suppression(track, 3)); - break; - case 2212: fQAList->Fill("fHistTPCproton", p, tpcSignal); - fQAList->Fill("fHistTPCprobPro", p, Likelihood(track, 0)); - fQAList->Fill("fHistTPCsuppressPro", p, Suppression(track, 4)); - break; - default: fQAList->Fill("fHistTPCothers", p, tpcSignal); - fQAList->Fill("fHistTPCprobOth", p, Likelihood(track, 0)); - - break; + case 11: + species = AliPID::kElectron; + if(!stepSelected){ + Double_t contentElHist[4]; + for(Int_t ispec = AliPID::kMuon; ispec < AliPID::kSPECIES; ispec++){ + contentElHist[0] = ispec; + contentElHist[1] = p; + contentElHist[2] = -Suppression(track, ispec); + contentElHist[3] = Likelihood(track, ispec); + hptr = dynamic_cast(fQAList->Get("fHistTPCel")); + hptr->Fill(contentElHist); + } + } + break; + case 13: species = AliPID::kMuon; break; + case 211: species = AliPID::kPion; break; + case 321: species = AliPID::kKaon; break; + case 2212: species = AliPID::kProton; break; + default: species = -1; break; + } + if(!stepSelected){ + // Fill Probability Histogram + Double_t contentProb[3] = {species , p, Likelihood(track, 0)}; + hptr = dynamic_cast(fQAList->Get("fHistTPCprob")); + hptr->Fill(contentProb); + // Fill suppression Histogram + if(species > 0 && species < AliPID::kSPECIES){ + Double_t contentSup[3] = {species, p, Suppression(track, species)}; + hptr = dynamic_cast(fQAList->Get("fHistTPCsuppression")); + hptr->Fill(contentSup); + } } } - //TPC signal and Likelihood to be electron for all tracks (independent of MC information) - fQAList->Fill("fHistTPCall", p, tpcSignal); - fQAList->Fill("kHistTPCprobAll", p, Likelihood(track, 0)); + + // Fill signal histogram + Double_t contentSignal[5] = {species, p, tpcSignal, fESDpid->NumberOfSigmasTPC(track, AliPID::kElectron), stepSelected ? 1 : 0}; + hptr = dynamic_cast(fQAList->Get("fHistTPCsignal")); + hptr->Fill(contentSignal); } //___________________________________________________________________ @@ -355,50 +365,33 @@ void AliHFEpidTPC::AddQAhistograms(TList *qaList){ // // Create QA histograms for TPC PID // - fQAList = new AliHFEcollection; - - fQAList->CreateTH2F("fHistTPCelectron","TPC signal for Electrons", 200, 0, 20, 60, 0, 600); - fQAList->CreateTH2F("fHistTPCmuon","TPC signal for Muons", 200, 0, 20, 60, 0, 600); - fQAList->CreateTH2F("fHistTPCpion","TPC signal for Pions", 200, 0, 20, 60, 0, 600); - fQAList->CreateTH2F("fHistTPCkaon","TPC signal for Kaons", 200, 0, 20, 60, 0, 600); - fQAList->CreateTH2F("fHistTPCproton","TPC signal for Protons", 200, 0, 20, 60, 0, 600); - fQAList->CreateTH2F("fHistTPCothers","TPC signal for other species", 200, 0, 20, 60, 0, 600); - fQAList->CreateTH2F("fHistTPCall","TPC signal for all species", 200, 0, 20, 60, 0, 600); - fQAList->CreateTH2F("fHistTPCselected","TPC signal for all selected particles", 200, 0, 20, 60, 0, 600); - - fQAList->CreateTH2F("fHistTPCprobEl","TPC likelihood for electrons to be an electron vs. p", 200, 0.,20.,200,0.,1.); - fQAList->CreateTH2F("fHistTPCprobPi","TPC likelihood for pions to be an electron vs. p", 200, 0.,20.,200, 0.,1.); - fQAList->CreateTH2F("fHistTPCprobMu","TPC likelihood for muons to be an electron vs. p", 200, 0.,20.,200, 0.,1.); - fQAList->CreateTH2F("fHistTPCprobKa","TPC likelihood for kaons to be an electron vs. p", 200, 0.,20.,200, 0.,1.); - fQAList->CreateTH2F("fHistTPCprobPro","TPC likelihood for protons to be an electron vs. p", 200, 0.,20.,200, 0.,1.); - fQAList->CreateTH2F("fHistTPCprobOth","TPC likelihood for other particles to be an electron vs. p", 200, 0.,20.,200, 0.,1.); - fQAList->CreateTH2F("fHistTPCprobAll","TPC likelihood for all particles to be an electron vs. p", 200, 0.,20.,200, 0.,1.); - - fQAList->CreateTH2F("fHistTPCsuppressPi","log10 of TPC Likelihood(pion)/Likelihood(elec) for pions vs. p", 200, 0.,20.,200,-1.,5.8); - fQAList->CreateTH2F("fHistTPCsuppressMu","log10 of TPC Likelihood(muon)/Likelihood(elec) for muons vs. p", 200, 0.,20.,200,-1.,5.8); - fQAList->CreateTH2F("fHistTPCsuppressKa","log10 of TPC Likelihood(kaon)/Likelihood(elec) for kaons vs. p", 200, 0.,20.,200,-1.,5.8); - fQAList->CreateTH2F("fHistTPCsuppressPro","log10 of TPC Likelihood(proton)/Likelihood(elec)for protons vs. p", 200, 0.,20.,200,-1.,5.8); - - fQAList->CreateTH2F("fHistTPCenhanceElPi","log10 of TPC Likelihood(elec)/Likelihood(pion) for electrons vs. p", 200, 0.,20.,200,-1.,5.8); - fQAList->CreateTH2F("fHistTPCenhanceElMu","log10 of TPC Likelihood(elec)/Likelihood(muon) for electrons vs. p", 200, 0.,20.,200,-1.,5.8); - fQAList->CreateTH2F("fHistTPCenhanceElKa","log10 of TPC Likelihood(elec)/Likelihood(kaon) for electrons vs. p", 200, 0.,20.,200,-1.,5.8); - fQAList->CreateTH2F("fHistTPCenhanceElPro","log10 of TPC Likelihood(elec)/Likelihood(proton) for electrons vs. p", 200, 0.,20.,200,-1.,5.8); - - fQAList->CreateTH2F("fHistTPCElprobPi","TPC likelihood for electrons to be a pion vs. p", 200, 0.,20.,200,0.,1.); - fQAList->CreateTH2F("fHistTPCElprobMu","TPC likelihood for electrons to be a muon vs. p", 200, 0.,20.,200,0.,1.); - fQAList->CreateTH2F("fHistTPCElprobKa","TPC likelihood for electrons to be a kaon vs. p", 200, 0.,20.,200,0.,1.); - fQAList->CreateTH2F("fHistTPCElprobPro","TPC likelihood for electrons to be a proton vs. p", 200, 0.,20.,200,0.,1.); - - fQAList->CreateTH2F("fHistSigmaElectronAll", "TPC NSigma around the Electron Line", 200, 0, 20, 40, -10, 10); - fQAList->CreateTH2F("fHistSigmaElectronSelected", "TPC NSigma around the Electron Line for selected Tracks", 200, 0, 20, 40, -10, 10); + fQAList = new AliHFEcollection("fQAhistosTPC", "TPC QA histos"); + + // First THnSparse we fill with the signal + const Int_t kNdimSignal = 5; + Int_t nBins[kNdimSignal]; + Double_t binMin[kNdimSignal], binMax[kNdimSignal]; + nBins[0] = AliPID::kSPECIES + 1; binMin[0] = -1.; binMax[0] = AliPID::kSPECIES; // MC Species; + nBins[1] = 1000; binMin[1] = 0.; binMax[1] = 20.; + nBins[2] = 6000; binMin[2] = 0.; binMax[2] = 600.; + nBins[3] = 1400; binMin[3] = -12.; binMax[3] = 12.; + nBins[4] = 2; binMin[4] = 0.; binMax[4] = nBins[4]; // Selected or not + 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); + + const Int_t kNdimProbEl = 3; + nBins[2] = 200; binMin[2] = 0.; binMax[2] = 1.; + fQAList->CreateTHnSparse("fHistTPCprob", "TPC Likelihood to be an electron; Species; p [GeV/c]; TPC Likelihood [a.u.]", kNdimProbEl, nBins, binMin, binMax); + + const Int_t kNdimSuppression = 3; + nBins[2] = 200; binMin[2] = -1.; binMax[2] = 5.8; // log10 of TPC Likelihood(species)/Likelihood(elec) for species i neq electron + fQAList->CreateTHnSparse("fHistTPCsuppression", "TPC non-electron Suppression; Species; p [GeV/c]; Suppression [a.u.]", kNdimSuppression, nBins, binMin, binMax); + + const Int_t kNdimEle = 4; + nBins[0] = AliPID::kSPECIES - 1; binMin[0] = 1.; binMax[0] = AliPID::kSPECIES; + nBins[2] = 100; binMin[2] = -1.; binMax[2] = 5.8; + nBins[3] = 200; binMin[3] = 0.; binMax[3] = 1.; + fQAList->CreateTHnSparse("fHistTPCel", "TPC electron Histogram; Species; p [GeV/c]; Electron Enhancement:Electron Likelihood", kNdimEle, nBins, binMin, binMax); qaList->AddLast(fQAList->GetList()); } -//___________________________________________________________________ -void AliHFEpidTPC::SetBetheBlochParameters(Double_t *pars){ - // - // Set non-default Bethe-Bloch Parameters - // - fESDpid->GetTPCResponse().SetBetheBlochParameters(pars[0], pars[1], pars[2], pars[3], pars[4]); -} diff --git a/PWG3/hfe/AliHFEpidTPC.h b/PWG3/hfe/AliHFEpidTPC.h index d0c3307b085..6fe69397c13 100644 --- a/PWG3/hfe/AliHFEpidTPC.h +++ b/PWG3/hfe/AliHFEpidTPC.h @@ -54,20 +54,24 @@ class AliHFEpidTPC : public AliHFEpidBase{ Bool_t HasAsymmetricSigmaCut() const { return TestBit(kAsymmetricSigmaCut);} Bool_t HasParticleRejection() const { return TestBit(kRejection); } void SetTPCnSigma(Short_t nSigma) { fNsigmaTPC = nSigma; }; - void SetBetheBlochParameters(Double_t *pars); inline void SetAsymmetricTPCsigmaCut(Float_t pmin, Float_t pmax, Float_t sigmaMin, Float_t sigmaMax); inline void SetRejectParticle(Int_t species, Float_t pmin, Float_t sigmaMin, Float_t pmax, Float_t sigmaMax); + void SetUpperSigmaCut(TF1 * const model) { fUpperSigmaCut = model; } + void SetLowerSigmaCut(TF1 * const model) { fLowerSigmaCut = model; } + protected: void Copy(TObject &o) const; void AddQAhistograms(TList *qaList); - void FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack); + void FillTPChistograms(const AliESDtrack *track, const AliMCParticle *mctrack, Bool_t stepSelected = kFALSE); Int_t MakePIDaod(AliAODTrack *aodTrack, AliAODMCParticle *mcTrack); Int_t MakePIDesd(AliESDtrack *esdTrack, AliMCParticle *mcTrack); Int_t Reject(AliESDtrack *track); Double_t Likelihood(const AliESDtrack *track, Int_t species, Float_t rsig = 2.); Double_t Suppression(const AliESDtrack *track, Int_t species); + Bool_t CutSigmaModel(AliESDtrack *track); + private: enum{ kAsymmetricSigmaCut = BIT(20), @@ -76,13 +80,14 @@ class AliHFEpidTPC : public AliHFEpidBase{ Double_t fLineCrossingSigma[AliPID::kSPECIES]; // with of the exclusion point Int_t fLineCrossingType; // 0 for no line crossing, otherwise AliPID of the particle crossing the electron dEdx band UChar_t fLineCrossingsEnabled; // Bitmap showing which line crossing is set + TF1 *fUpperSigmaCut; // Upper Sigma Cut + TF1 *fLowerSigmaCut; // Lower Sigma Cut Float_t fPAsigCut[2]; // Momentum region where to perform asymmetric sigma cut Float_t fNAsigmaTPC[2]; // Asymmetric TPC Sigma band Short_t fNsigmaTPC; // TPC sigma band Float_t fRejection[4*AliPID::kSPECIES]; // All informations for Particle Rejection, order pmin, sigmin, pmax, sigmax UChar_t fRejectionEnabled; // Bitmap for enabled particle rejection AliPID *fPID; //! PID Object - AliESDpid *fESDpid; //! TPC PID object AliHFEcollection *fQAList; //! QA histograms ClassDef(AliHFEpidTPC, 1) // TPC Electron ID class diff --git a/PWG3/hfe/AliHFEpidTRD.cxx b/PWG3/hfe/AliHFEpidTRD.cxx index e2b0ae73ca9..663b5a94589 100644 --- a/PWG3/hfe/AliHFEpidTRD.cxx +++ b/PWG3/hfe/AliHFEpidTRD.cxx @@ -39,6 +39,18 @@ ClassImp(AliHFEpidTRD) const Double_t AliHFEpidTRD::fgkVerySmall = 1e-12; +//___________________________________________________________________ +AliHFEpidTRD::AliHFEpidTRD() : + AliHFEpidBase() + , fPIDMethod(kNN) + , fContainer(0x0) +{ + // + // default constructor + // + memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams); +} + //___________________________________________________________________ AliHFEpidTRD::AliHFEpidTRD(const char* name) : AliHFEpidBase(name) diff --git a/PWG3/hfe/AliHFEpidTRD.h b/PWG3/hfe/AliHFEpidTRD.h index 68afe68915e..60296b3481b 100644 --- a/PWG3/hfe/AliHFEpidTRD.h +++ b/PWG3/hfe/AliHFEpidTRD.h @@ -49,6 +49,7 @@ class AliHFEpidTRD : public AliHFEpidBase{ kHistTRDSigV2 = 4, kHistOverallSpecies = 5 }; + AliHFEpidTRD(); AliHFEpidTRD(const Char_t *name); AliHFEpidTRD(const AliHFEpidTRD &ref); AliHFEpidTRD& operator=(const AliHFEpidTRD &ref); diff --git a/PWG3/hfe/AliHFEpostAnalysis.cxx b/PWG3/hfe/AliHFEpostAnalysis.cxx index 4892dc6ff43..1e30dafa3de 100644 --- a/PWG3/hfe/AliHFEpostAnalysis.cxx +++ b/PWG3/hfe/AliHFEpostAnalysis.cxx @@ -337,16 +337,19 @@ TH1 *AliHFEpostAnalysis::CreateHistoPIDperformance(Int_t mode, Int_t charge){ // // Make Histograms for PID performance plots // + fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1); + fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1); + TH1 *hNom = NULL, *hDenom = NULL; char hname[256], htitle[256], cname[256]; Color_t mycolor = kBlack; - if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(charge, charge); + if(charge) fPIDperformance->GetAxis(3)->SetRange(charge, charge); // Normalisation by all candidates - no restriction in axis 4 - only for mode == 1 - if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(2,2); + if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(2,3); hDenom = fPIDperformance->Projection(0); hDenom->Sumw2(); hDenom->SetName("hDenom"); - if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetLast() + 1); + if(mode == 1) fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins() + 1); // Nominator need a restriction in the 4th axis switch(mode){ case 0: // Electron purity @@ -385,8 +388,8 @@ TH1 *AliHFEpostAnalysis::CreateHistoPIDperformance(Int_t mode, Int_t charge){ hNom->Sumw2(); hNom->SetName("hNom"); // Reset axis - fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetLast() + 1); - if(charge) fSignalToBackgroundMC->GetAxis(3)->SetRange(0, fSignalToBackgroundMC->GetAxis(3)->GetLast() + 1); + fPIDperformance->GetAxis(4)->SetRange(0, fPIDperformance->GetAxis(4)->GetNbins()+1); + if(charge) fPIDperformance->GetAxis(3)->SetRange(0, fPIDperformance->GetAxis(3)->GetNbins() + 1); // Create Efficiency histogram TH1 *hEff = dynamic_cast(hNom->Clone()); diff --git a/PWG3/hfe/AliHFEpriVtx.cxx b/PWG3/hfe/AliHFEpriVtx.cxx index be2ddd5d3ac..d416cb1d820 100644 --- a/PWG3/hfe/AliHFEpriVtx.cxx +++ b/PWG3/hfe/AliHFEpriVtx.cxx @@ -27,7 +27,7 @@ #include "AliESDEvent.h" #include -#include +#include #include #include @@ -41,13 +41,17 @@ ClassImp(AliHFEpriVtx) //_______________________________________________________________________________________________ AliHFEpriVtx::AliHFEpriVtx(): fESD1(0x0) - ,fStack(0x0) + ,fMCEvent(0x0) ,fNtrackswoPid(0) ,fHNtrackswoPid(0x0) ,fNESDprimVtxContributor(0x0) ,fNESDprimVtxIndices(0x0) ,fDiffDCAvsPt(0x0) ,fDiffDCAvsNt(0x0) + ,fNsectrk2prim(0) + ,fPVxRe(-999.) + ,fPVyRe(-999.) + ,fPVzRe(-999.) { // // Default constructor @@ -61,13 +65,17 @@ AliHFEpriVtx::AliHFEpriVtx(): AliHFEpriVtx::AliHFEpriVtx(const AliHFEpriVtx &p): TObject(p) ,fESD1(0x0) - ,fStack(0x0) + ,fMCEvent(0x0) ,fNtrackswoPid(p.fNtrackswoPid) ,fHNtrackswoPid(0x0) ,fNESDprimVtxContributor(0x0) ,fNESDprimVtxIndices(0x0) ,fDiffDCAvsPt(0x0) ,fDiffDCAvsNt(0x0) + ,fNsectrk2prim(p.fNsectrk2prim) + ,fPVxRe(p.fPVxRe) + ,fPVyRe(p.fPVyRe) + ,fPVzRe(p.fPVzRe) { // // Copy constructor @@ -193,8 +201,10 @@ Int_t AliHFEpriVtx::GetMCPID(AliESDtrack *track) // get MC pid // - Int_t label = TMath::Abs(track->GetLabel()); - TParticle* mcpart = fStack->Particle(label); + AliMCParticle *mctrack = NULL; + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) return 0; + TParticle *mcpart = mctrack->Particle(); + if ( !mcpart ) return 0; Int_t pdgCode = mcpart->GetPdgCode(); @@ -226,8 +236,15 @@ void AliHFEpriVtx::CountPriVxtElecContributor(AliESDtrack *ESDelectron, Int_t so // get track id of our selected electron Int_t elecTrkID = ESDelectron->GetID(); - Int_t label = TMath::Abs(ESDelectron->GetLabel()); - TParticle* mcpart = fStack->Particle(label); + AliMCParticle *mctrack = NULL; + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(ESDelectron->GetLabel()))))) return; + TParticle *mcpart = mctrack->Particle(); + + + if(!mcpart){ + AliDebug(1, "no mc particle, return\n"); + return; + } AliKFParticle::SetField(fESD1->GetMagneticField()); AliKFParticle kfElectron(*ESDelectron,11); @@ -284,7 +301,7 @@ void AliHFEpriVtx::FillNprimVtxContributor() const } //_______________________________________________________________________________________________ -Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack *ESDelectron) +Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack * const ESDelectron) { // // return recalculated DCA after removing input track from the primary vertex @@ -319,6 +336,80 @@ Double_t AliHFEpriVtx::GetDistanceFromRecalVertexXY(AliESDtrack *ESDelectron) } } } - return -1; + return -1; + +} + +void AliHFEpriVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk) +{ + // + // recalculate primary vertex after removing the input track + // + + const AliESDVertex *primvtx = fESD1->GetPrimaryVertex(); + + AliKFVertex kfESDprimary; + Int_t n = primvtx->GetNIndices(); + fNsectrk2prim = 0; + fPVxRe = -999.; + fPVyRe = -999.; + fPVyRe = -999.; + + if (n>0 && primvtx->GetStatus()){ + kfESDprimary = AliKFVertex(*primvtx); + UShort_t *priIndex = primvtx->GetIndices(); + for (Int_t j=0; jGetID(); + + AliKFParticle::SetField(fESD1->GetMagneticField()); + AliKFParticle kfElectron(*ESDelectron,11); + + const AliESDVertex *primvtx = fESD1->GetPrimaryVertex(); + + AliKFVertex kfESDprimary; + Int_t n = primvtx->GetNIndices(); + fPVxRe = -999.; + fPVyRe = -999.; + fPVyRe = -999.; + + if (n>0 && primvtx->GetStatus()){ + kfESDprimary = AliKFVertex(*primvtx); + UShort_t *priIndex = primvtx->GetIndices(); + for (Int_t i=0;i #include +#include #include #include #include @@ -34,7 +35,7 @@ #include #include #include -#include +#include #include #include "AliHFEpairs.h" #include "AliHFEsecVtxs.h" @@ -47,7 +48,7 @@ AliHFEsecVtx::AliHFEsecVtx(): fFilter(0x0) ,fESD1(0x0) ,fAOD1(0x0) - ,fStack(0x0) + ,fMCEvent(0x0) ,fUseMCPID(kFALSE) ,fkSourceLabel() ,fNparents(0) @@ -56,17 +57,25 @@ AliHFEsecVtx::AliHFEsecVtx(): ,fDcaCut() ,fNoOfHFEpairs(0) ,fNoOfHFEsecvtxs(0) + ,fArethereSecVtx(0) ,fHFEpairs(0x0) ,fHFEsecvtxs(0x0) ,fMCArray(0x0) - ,fPVx(0) - ,fPVy(0) + ,fPVx(-999) + ,fPVy(-999) + ,fPVx2(999) + ,fPVy2(-999) ,fCosPhi(-1) ,fSignedLxy(-1) + ,fSignedLxy2(-1) ,fKFchi2(-1) ,fInvmass(-1) ,fInvmassSigma(-1) ,fKFip(0) + ,fKFip2(0) + ,fNsectrk2prim(0) + ,fVtxchi2Tightcut(3.) + ,fVtxchi2Loosecut(5.) ,fPairQA(0x0) ,fSecvtxQA(0x0) ,fSecVtxList(0x0) @@ -84,7 +93,7 @@ AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p): ,fFilter(0x0) ,fESD1(0x0) ,fAOD1(0x0) - ,fStack(0x0) + ,fMCEvent(0x0) ,fUseMCPID(p.fUseMCPID) ,fkSourceLabel() ,fNparents(p.fNparents) @@ -93,17 +102,25 @@ AliHFEsecVtx::AliHFEsecVtx(const AliHFEsecVtx &p): ,fDcaCut() ,fNoOfHFEpairs(p.fNoOfHFEpairs) ,fNoOfHFEsecvtxs(p.fNoOfHFEsecvtxs) + ,fArethereSecVtx(p.fArethereSecVtx) ,fHFEpairs(0x0) ,fHFEsecvtxs(0x0) ,fMCArray(0x0) ,fPVx(p.fPVx) ,fPVy(p.fPVy) + ,fPVx2(p.fPVx2) + ,fPVy2(p.fPVy2) ,fCosPhi(p.fCosPhi) ,fSignedLxy(p.fSignedLxy) + ,fSignedLxy2(p.fSignedLxy2) ,fKFchi2(p.fKFchi2) ,fInvmass(p.fInvmass) ,fInvmassSigma(p.fInvmassSigma) ,fKFip(p.fKFip) + ,fKFip2(p.fKFip2) + ,fNsectrk2prim(p.fNsectrk2prim) + ,fVtxchi2Tightcut(p.fVtxchi2Tightcut) + ,fVtxchi2Loosecut(p.fVtxchi2Loosecut) ,fPairQA(0x0) ,fSecvtxQA(0x0) ,fSecVtxList(0x0) @@ -185,6 +202,9 @@ void AliHFEsecVtx::Init() } void AliHFEsecVtx::Process(AliVTrack *signalTrack){ + // + // Run Process + // if(signalTrack->Pt() < 1.0) return; AliESDtrack *track = dynamic_cast(signalTrack); InitHFEpairs(); @@ -261,13 +281,13 @@ void AliHFEsecVtx::GetPrimaryCondition() AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex())); if( primVtxCopy.GetNDF() <1 ) return; fPVx = primVtxCopy.GetX(); - fPVx = primVtxCopy.GetY(); + fPVy = primVtxCopy.GetY(); } else if(fAOD1) { AliKFVertex primVtxCopy(*(fAOD1->GetPrimaryVertex())); if( primVtxCopy.GetNDF() <1 ) return; fPVx = primVtxCopy.GetX(); - fPVx = primVtxCopy.GetY(); + fPVy = primVtxCopy.GetY(); } } @@ -282,11 +302,15 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde Float_t dca1[2]={-999.,-999.}, dca2[2]={-999.,-999.}; Float_t cov1[3]={-999.,-999.,-999.}, cov2[3]={-999.,-999.,-999.}; + Double_t dca1aod[2]={-999.,-999.}, dca2aod[2]={-999.,-999.}; + Double_t cov1aod[3]={-999.,-999.,-999.}, cov2aod[3]={-999.,-999.,-999.}; + if (IsAODanalysis()){ + const AliAODVertex *primVtx = fAOD1->GetPrimaryVertex(); AliESDtrack esdTrk1(track1); AliESDtrack esdTrk2(track2); - esdTrk1.PropagateToDCA(fAOD1->GetPrimaryVertex(),0,10000,(Double_t*)dca1,(Double_t*)cov1); - esdTrk2.PropagateToDCA(fAOD1->GetPrimaryVertex(),0,10000,(Double_t*)dca2,(Double_t*)cov2); + esdTrk1.PropagateToDCA(primVtx,0.,10000.,dca1aod,cov1aod); + esdTrk2.PropagateToDCA(primVtx,0.,10000.,dca2aod,cov2aod); } else { ((AliESDtrack*)track1)->GetImpactParameters(dca1,cov1); @@ -294,9 +318,9 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde } // apply pt dependent dca cut on hadrons - for(int ibin=0; ibin<6; ibin++){ + /*for(int ibin=0; ibin<6; ibin++){ if((track2->Pt()>fPtRng[ibin] && track2->Pt()GetMagneticField()); else AliKFParticle::SetField(fESD1->GetMagneticField()); - AliKFParticle kfTrack1(*track1, pdg1); - AliKFParticle kfTrack2(*track2, pdg2); - AliKFParticle kfSecondary(kfTrack1,kfTrack2); + AliKFParticle kfTrack[2]; + kfTrack[0] = AliKFParticle(*track1, pdg1); + kfTrack[1] = AliKFParticle(*track2, pdg2); + + AliKFParticle kfSecondary(kfTrack[0],kfTrack[1]); //secondary vertex point from kf particle Double_t kfx = kfSecondary.GetX(); @@ -325,6 +351,22 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde Double_t kfpy = kfSecondary.GetPy(); //Double_t kfpz = kfSecondary.GetPz(); + +/* //directly use of ESD vertex + const AliESDVertex *pvertex = fESD1->GetPrimaryVertex(); + Double_t xyzVtx[3]; + pvertex->GetXYZ(xyzVtx); + + Double_t dx = kfx-xyzVtx[0]; + Double_t dy = kfy-xyzVtx[1];*/ + + AliKFVertex primVtxCopy(*(fESD1->GetPrimaryVertex())); + if( primVtxCopy.GetNDF() <1 ) return; + fPVx = primVtxCopy.GetX(); + fPVy = primVtxCopy.GetY(); + + // printf("esdx= %lf kfx= %lf esdy= %lf kfy= %lf\n",xyzVtx[0],fPVx,xyzVtx[1],fPVy); + Double_t dx = kfx-fPVx; Double_t dy = kfy-fPVy; @@ -339,9 +381,13 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde if(kfSecondary.GetNDF()>0) kfchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF())); // opening angle between two particles in XY plane - Double_t phi = kfTrack1.GetAngleXY(kfTrack2); + Double_t phi = kfTrack[0].GetAngleXY(kfTrack[1]); Double_t cosphi = TMath::Cos(phi); + // DCA from primary to e-h KF particle (impact parameter of KF particle) + Double_t vtx[2]={fPVx, fPVy}; + Double_t kfip = kfSecondary.GetDistanceFromVertexXY(vtx); + // projection of kf vertex vector to the kf momentum direction Double_t signedLxy=-999.; if((dx*kfpx+dy*kfpy)>0) signedLxy = TMath::Sqrt(dx*dx+dy*dy); @@ -350,9 +396,24 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde //Double_t psqr = kfpx*kfpx+kfpy*kfpy; //if(psqr>0) signedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr); - // DCA from primary to e-h KF particle (impact parameter of KF particle) - Double_t vtx[2]={fPVx, fPVy}; - Double_t kfip = kfSecondary.GetDistanceFromVertexXY(vtx); + //recalculating primary vertex after removing secvtx tracks -------------------------- + Int_t trkid[2]; + trkid[0] = track1->GetID(); + trkid[1] = track2->GetID(); + + RecalcPrimvtx(2, trkid, kfTrack); + Double_t dx2 = kfx-fPVx2; + Double_t dy2 = kfy-fPVy2; + + // IP of sec particle recalculated based on recalculated primary vertex + Double_t vtx2[2]={fPVx2, fPVy2}; + Double_t kfip2 = kfSecondary.GetDistanceFromVertexXY(vtx2); + // signed Lxy recalculated based on recalculated primary vertex + Double_t signedLxy2=-999.; + if((dx2*kfpx+dy2*kfpy)>0) signedLxy2 = TMath::Sqrt(dx2*dx2+dy2*dy2); + if((dx2*kfpx+dy2*kfpy)<0) signedLxy2 = -1*TMath::Sqrt(dx2*dx2+dy2*dy2); + //------------------------------------------------------------------------------------ + Int_t paircode = -1; if (HasMCData()) paircode = GetPairCode(track1,track2); @@ -364,7 +425,9 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde hfepair.SetOpenangle(phi); hfepair.SetCosOpenangle(cosphi); hfepair.SetSignedLxy(signedLxy); + hfepair.SetSignedLxy2(signedLxy2); hfepair.SetKFIP(kfip); + hfepair.SetKFIP2(kfip2); hfepair.SetPairCode(paircode); AddHFEpairToArray(&hfepair); fNoOfHFEpairs++; @@ -374,17 +437,18 @@ void AliHFEsecVtx::PairAnalysis(AliVTrack* track1, AliVTrack* track2, Int_t inde dataE[0]=invmass; dataE[1]=kfchi2; dataE[2]=phi; - dataE[3]=signedLxy; - dataE[4]=kfip; + dataE[3]=signedLxy2; + dataE[4]=kfip2; dataE[5]=paircode; - /* - dataE[6]=TMath::Abs(dca1[0]); - dataE[7]=TMath::Abs(dca2[0]); //if(cov1[0]>0) dataE[6]=Double_t(dca1[0]/cov1[0]); //if(cov2[0]>0) dataE[7]=Double_t(dca2[0]/cov2[0]); - dataE[8]=track1->Pt(); - dataE[9]=track2->Pt(); - */ + //dataE[6]=track1->Pt(); + //dataE[7]=track2->Pt(); + //dataE[6]=dca1[0]; //mjtmp + //dataE[7]=dca2[0]; //mjtmp + //dataE[8]=TMath::Abs(dca1[0]); + //dataE[9]=TMath::Abs(dca2[0]); + fPairQA->Fill(dataE); } @@ -408,9 +472,14 @@ void AliHFEsecVtx::FindSECVTXCandid(AliVTrack *track) // AliVTrack *htrack[20]; - Int_t htracklabel[20]; - Double_t vtxchi2cut=3.; // testing cut - Double_t dataE[6]={-999.,-999.,-999.,-999.,-1.,0}; + //Int_t htracklabel[20]; + //Int_t paircode[20]; + //Double_t vtxchi2[20]; + //Double_t dataE[7]={-999.,-999.,-999.,-999.,-1.,0,0}; + + fVtxchi2Tightcut=3.; // tight cut for pair + fVtxchi2Loosecut=5.; // loose cut for secvtx + if (HFEpairs()->GetEntriesFast()>20){ AliDebug(3, "number of paired hadron is over maximum(20)"); return; @@ -421,68 +490,280 @@ void AliHFEsecVtx::FindSECVTXCandid(AliVTrack *track) if (IsAODanalysis()){ for (int ip=0; ipGetEntriesFast(); ip++){ pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip)); - htracklabel[ip] = pair->GetTrkLabel(); + //htracklabel[ip] = pair->GetTrkLabel(); htrack[ip] = fAOD1->GetTrack(pair->GetTrkLabel()); + //if(pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode[ip]=1; + //else paircode[ip]=0; + //vtxchi2[ip] = pair->GetKFChi2(); } } else{ for (int ip=0; ipGetEntriesFast(); ip++){ pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ip)); - htracklabel[ip] = pair->GetTrkLabel(); + //htracklabel[ip] = pair->GetTrkLabel(); htrack[ip] = fESD1->GetTrack(pair->GetTrkLabel()); + //if(pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode[ip]=1; + //else paircode[ip]=0; + //vtxchi2[ip] = pair->GetKFChi2(); } } - // in case there is only one paired track with the electron, put pair characteristics into secvtx container - // for the moment, I only apply pair vertex chi2 cut - if (HFEpairs()->GetEntriesFast() == 1){ - if (pair->GetKFChi2()GetTrkLabel()); - hfesecvtx.SetTrkLabel2(-999); - hfesecvtx.SetInvmass(pair->GetInvmass()); - hfesecvtx.SetKFChi2(pair->GetKFChi2()); - hfesecvtx.SetSignedLxy(pair->GetSignedLxy()); - hfesecvtx.SetKFIP(pair->GetKFIP()); - AddHFEsecvtxToArray(&hfesecvtx); - fNoOfHFEsecvtxs++; - - dataE[0]=pair->GetInvmass(); - dataE[1]=pair->GetKFChi2(); - dataE[2]=pair->GetSignedLxy(); - dataE[3]=pair->GetKFIP(); - if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel())); - dataE[5]=2; - fSecvtxQA->Fill(dataE); + + Int_t nPairs = HFEpairs()->GetEntriesFast(); + + + // 1 electron candidate + 1 track + if (nPairs == 1){ + if (pair->GetKFChi2() < fVtxchi2Tightcut) { // you can also put single track cut -> here you apply very tight cut for the pair + Fill2TrkSECVTX(track, pair); } return; } + //-------------------------------------------------------------- + + // 1 electron candidate + 2 tracks + if (nPairs == 2){ + CalcSECVTXProperty(track, htrack[0], htrack[1]); // calculate secondary vertex property + + if (fKFchi2 < fVtxchi2Loosecut) { // -> here you apply rather loose cut + Fill3TrkSECVTX(track, 0, 1); + } + else{ // if doesn't pass the sec vtx chi2 cut + for(int jp=0; jp<2; jp++){ + pair = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jp)); + if (pair->GetKFChi2() < fVtxchi2Tightcut){ + Fill2TrkSECVTX(track, pair); + } + } + } + return; + } + //-------------------------------------------------------------- + + // 1 electron candidate + 3 tracks + if (nPairs == 3){ + CalcSECVTXProperty(track, htrack[0], htrack[1], htrack[2]); // calculate secondary vertex property - // in case there are multiple paired track with the electron, calculate secvtx characteristics - // put the secvtx characteristics into container if it passes cuts - for (int i=0; iGetEntriesFast()-1; i++){ - for (int j=i+1; jGetEntriesFast(); j++){ - CalcSECVTXProperty(track, htrack[i], htrack[j]); - if (fKFchi2GetLabel())); - dataE[5]=3; - fSecvtxQA->Fill(dataE); + if (fKFchi2 < fVtxchi2Loosecut) { + Fill4TrkSECVTX(track, 0, 1, 2); + } + else { + fArethereSecVtx=0; + for (int i=0; iUncheckedAt(jp)); + if (pair->GetKFChi2() < fVtxchi2Tightcut){ + Fill2TrkSECVTX(track, pair); + } + } + } + } + return; + } + //-------------------------------------------------------------- + + // 1 electron candidate + more than 3 tracks + if (nPairs > 3){ + fArethereSecVtx=0; + for (int ih1=0; ih1UncheckedAt(jp)); + if (pair->GetKFChi2() < fVtxchi2Tightcut){ + Fill2TrkSECVTX(track, pair); + } + } + } + return; + } + //-------------------------------------------------------------- + +} + +//_______________________________________________________________________________________________ +void AliHFEsecVtx::Fill4TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair, Int_t kpair) +{ + // + // fill 3 tracks' secondary vertex properties + // + + Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.}; + + Int_t paircode1 = 0, paircode2 = 0, paircode3 = 0; + Int_t htracklabel1 = 0, htracklabel2= 0; + + if (HasMCData()){ + AliHFEpairs *pair1=0x0; + AliHFEpairs *pair2=0x0; + AliHFEpairs *pair3=0x0; + pair1 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ipair)); + pair2 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jpair)); + pair3 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(kpair)); + + htracklabel1 = pair1->GetTrkLabel(); + htracklabel2 = pair2->GetTrkLabel(); + + if (pair1->GetPairCode()==2 || pair1->GetPairCode()==3) paircode1=1; + else paircode1=0; + if (pair2->GetPairCode()==2 || pair2->GetPairCode()==3) paircode2=1; + else paircode2=0; + if (pair3->GetPairCode()==2 || pair3->GetPairCode()==3) paircode3=1; + else paircode3=0; } + + AliHFEsecVtxs hfesecvtx; + hfesecvtx.SetTrkLabel1(htracklabel1); // mj: not much meaningful for the moment + hfesecvtx.SetTrkLabel2(htracklabel2); // mj: not much meaningful for the moment + if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel()))); + hfesecvtx.SetKFChi2(fKFchi2); + hfesecvtx.SetInvmass(fInvmass); + hfesecvtx.SetSignedLxy(fSignedLxy); + hfesecvtx.SetSignedLxy2(fSignedLxy2); + hfesecvtx.SetKFIP(fKFip); + hfesecvtx.SetKFIP2(fKFip2); + AddHFEsecvtxToArray(&hfesecvtx); + fNoOfHFEsecvtxs++; + + dataE[0]=fInvmass; + dataE[1]=fKFchi2; + dataE[2]=fSignedLxy; + dataE[3]=fKFip; + if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel())); + dataE[5]=4; //# of associated tracks + if(paircode1 & paircode2 & paircode3) dataE[6]=1; + else if(!paircode1 & !paircode2 & !paircode3) dataE[6]=0; + else dataE[6]=3; + dataE[7]=fSignedLxy2; + dataE[8]=track->Pt(); + fSecvtxQA->Fill(dataE); +} + +//_______________________________________________________________________________________________ +void AliHFEsecVtx::Fill3TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair) +{ + // + // fill 3 tracks' secondary vertex properties + // + + Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.}; + + Int_t paircode1 = 0, paircode2 = 0; + Int_t htracklabel1 = 0, htracklabel2 = 0; + + if (HasMCData()){ + AliHFEpairs *pair1=0x0; + AliHFEpairs *pair2=0x0; + pair1 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(ipair)); + pair2 = (AliHFEpairs*) (HFEpairs()->UncheckedAt(jpair)); + + htracklabel1 = pair1->GetTrkLabel(); + htracklabel2 = pair2->GetTrkLabel(); + + if (pair1->GetPairCode()==2 || pair1->GetPairCode()==3) paircode1=1; + else paircode1=0; + if (pair2->GetPairCode()==2 || pair2->GetPairCode()==3) paircode2=1; + else paircode2=0; + } + + // fill secondary vertex container + AliHFEsecVtxs hfesecvtx; + hfesecvtx.SetTrkLabel1(htracklabel1); + hfesecvtx.SetTrkLabel2(htracklabel2); + if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel()))); + hfesecvtx.SetKFChi2(fKFchi2); + hfesecvtx.SetInvmass(fInvmass); + hfesecvtx.SetSignedLxy(fSignedLxy); + hfesecvtx.SetSignedLxy2(fSignedLxy2); + hfesecvtx.SetKFIP(fKFip); + hfesecvtx.SetKFIP2(fKFip2); + AddHFEsecvtxToArray(&hfesecvtx); + fNoOfHFEsecvtxs++; + + // fill debugging THnSparse + dataE[0]=fInvmass; + dataE[1]=fKFchi2; + dataE[2]=fSignedLxy; + dataE[3]=fKFip; + if(HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel())); + dataE[5]=3; + if(paircode1 & paircode2) dataE[6]=1; + else if(!paircode1 & !paircode2) dataE[6]=0; + else dataE[6]=3; + dataE[7]=fSignedLxy2; + dataE[8]=track->Pt(); + fSecvtxQA->Fill(dataE); + +} + +//_______________________________________________________________________________________________ +void AliHFEsecVtx::Fill2TrkSECVTX(AliVTrack* track, AliHFEpairs *pair) +{ + // + // fill 2 tracks' secondary vertex properties + // + + Double_t dataE[9]={-999.,-999.,-999.,-999.,-1.,0,0,-999.,-999.}; + + Int_t paircode; + if (pair->GetPairCode()==2 || pair->GetPairCode()==3) paircode=1; + else paircode=0; + + // fill secondary vertex container + AliHFEsecVtxs hfesecvtx; + hfesecvtx.SetTrkLabel1(pair->GetTrkLabel()); + hfesecvtx.SetTrkLabel2(-999); + if(HasMCData()) hfesecvtx.SetMCCode(GetElectronSource(TMath::Abs(track->GetLabel()))); + hfesecvtx.SetInvmass(pair->GetInvmass()); + hfesecvtx.SetKFChi2(pair->GetKFChi2()); + hfesecvtx.SetSignedLxy(pair->GetSignedLxy()); + hfesecvtx.SetSignedLxy2(pair->GetSignedLxy2()); + hfesecvtx.SetKFIP(pair->GetKFIP()); + hfesecvtx.SetKFIP2(pair->GetKFIP2()); + AddHFEsecvtxToArray(&hfesecvtx); + fNoOfHFEsecvtxs++; + + // fill debugging THnSparse + dataE[0]=pair->GetInvmass(); + dataE[1]=pair->GetKFChi2(); + dataE[2]=pair->GetSignedLxy(); + dataE[3]=pair->GetKFIP(); + if (HasMCData()) dataE[4]=GetElectronSource(TMath::Abs(track->GetLabel())); + dataE[5]=2; //# of associated tracks + dataE[6]=paircode; + dataE[7]=pair->GetSignedLxy2(); + dataE[8]=track->Pt(); + fSecvtxQA->Fill(dataE); + } //_______________________________________________________________________________________________ @@ -505,11 +786,13 @@ void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliV // create KF particle of pair if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField()); else AliKFParticle::SetField(fESD1->GetMagneticField()); - AliKFParticle kfTrack1(*track1, pdg1); - AliKFParticle kfTrack2(*track2, pdg2); - AliKFParticle kfTrack3(*track3, pdg3); + AliKFParticle kfTrack[3]; + kfTrack[0] = AliKFParticle(*track1, pdg1); + kfTrack[1] = AliKFParticle(*track2, pdg2); + kfTrack[2] = AliKFParticle(*track3, pdg3); - AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3); + AliKFParticle kfSecondary(kfTrack[0],kfTrack[1],kfTrack[2]); + //AliKFParticle kfSecondary(kfTrack1,kfTrack2,kfTrack3); //secondary vertex point from kf particle Double_t kfx = kfSecondary.GetX(); @@ -540,6 +823,137 @@ void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliV //[the other way to think about] - projection of kf vertex vector to the kf momentum direction //Double_t psqr = kfpx*kfpx+kfpy*kfpy; //if(psqr>0) fSignedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr); + + + //recalculating primary vertex after removing secvtx tracks -------------------------- + Int_t trkid[3]; + trkid[0] = track1->GetID(); + trkid[1] = track2->GetID(); + trkid[2] = track3->GetID(); + + RecalcPrimvtx(3, trkid, kfTrack); + Double_t dx2 = kfx-fPVx2; + Double_t dy2 = kfy-fPVy2; + + // IP of sec particle recalculated based on recalculated primary vertex + Double_t vtx2[2]={fPVx2, fPVy2}; + fKFip2 = kfSecondary.GetDistanceFromVertexXY(vtx2); + // signed Lxy recalculated based on recalculated primary vertex + if((dx2*kfpx+dy2*kfpy)>0) fSignedLxy2= TMath::Sqrt(dx2*dx2+dy2*dy2); + if((dx2*kfpx+dy2*kfpy)<0) fSignedLxy2= -1*TMath::Sqrt(dx2*dx2+dy2*dy2); + //------------------------------------------------------------------------------------ + +} + +//_______________________________________________________________________________________________ +void AliHFEsecVtx::CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3, AliVTrack* track4) +{ + // + // calculate secondary vertex properties + // + + // get KF particle input pid + Int_t pdg1 = GetPDG(track1); + Int_t pdg2 = GetPDG(track2); + Int_t pdg3 = GetPDG(track3); + Int_t pdg4 = GetPDG(track4); + + if(pdg1==-1 || pdg2==-1 || pdg3==-1 || pdg4==-1) { + //printf("out if considered pid range \n"); + return; + } + + // create KF particle of pair + if(IsAODanalysis()) AliKFParticle::SetField(fAOD1->GetMagneticField()); + else AliKFParticle::SetField(fESD1->GetMagneticField()); + + AliKFParticle kfTrack[4]; + kfTrack[0] = AliKFParticle(*track1, pdg1); + kfTrack[1] = AliKFParticle(*track2, pdg2); + kfTrack[2] = AliKFParticle(*track3, pdg3); + kfTrack[3] = AliKFParticle(*track4, pdg4); + + AliKFParticle kfSecondary(kfTrack[0],kfTrack[1],kfTrack[2],kfTrack[3]); + + //secondary vertex point from kf particle + Double_t kfx = kfSecondary.GetX(); + Double_t kfy = kfSecondary.GetY(); + //Double_t kfz = kfSecondary.GetZ(); + + //momentum at the decay point from kf particle + Double_t kfpx = kfSecondary.GetPx(); + Double_t kfpy = kfSecondary.GetPy(); + //Double_t kfpz = kfSecondary.GetPz(); + + Double_t dx = kfx-fPVx; + Double_t dy = kfy-fPVy; + + // discriminating variables ---------------------------------------------------------- + + if(kfSecondary.GetNDF()>0) fKFchi2 = TMath::Sqrt(TMath::Abs(kfSecondary.GetChi2()/kfSecondary.GetNDF())); + + // invariant mass of the KF particle + kfSecondary.GetMass(fInvmass,fInvmassSigma); + + // DCA from primary to e-h KF particle (impact parameter of KF particle) + Double_t vtx[2]={fPVx, fPVy}; + fKFip = kfSecondary.GetDistanceFromVertexXY(vtx); + + if((dx*kfpx+dy*kfpy)>0) fSignedLxy= TMath::Sqrt(dx*dx+dy*dy); + if((dx*kfpx+dy*kfpy)<0) fSignedLxy= -1*TMath::Sqrt(dx*dx+dy*dy); + //[the other way to think about] - projection of kf vertex vector to the kf momentum direction + //Double_t psqr = kfpx*kfpx+kfpy*kfpy; + //if(psqr>0) fSignedLxy=(dx*kfpx+dy*kfpy)/TMath::Sqrt(psqr); + + //recalculating primary vertex after removing secvtx tracks -------------------------- + Int_t trkid[4]; + trkid[0] = track1->GetID(); + trkid[1] = track2->GetID(); + trkid[2] = track3->GetID(); + trkid[3] = track4->GetID(); + + RecalcPrimvtx(4, trkid, kfTrack); + Double_t dx2 = kfx-fPVx2; + Double_t dy2 = kfy-fPVy2; + + // IP of sec particle recalculated based on recalculated primary vertex + Double_t vtx2[2]={fPVx2, fPVy2}; + fKFip2 = kfSecondary.GetDistanceFromVertexXY(vtx2); + // signed Lxy recalculated based on recalculated primary vertex + if((dx2*kfpx+dy2*kfpy)>0) fSignedLxy2= TMath::Sqrt(dx2*dx2+dy2*dy2); + if((dx2*kfpx+dy2*kfpy)<0) fSignedLxy2= -1*TMath::Sqrt(dx2*dx2+dy2*dy2); + //------------------------------------------------------------------------------------ + +} + +//_______________________________________________________________________________________________ +void AliHFEsecVtx::RecalcPrimvtx(Int_t nkftrk, Int_t * const trkid, AliKFParticle * const kftrk){ + + const AliESDVertex *primvtx = fESD1->GetPrimaryVertex(); + + AliKFVertex kfESDprimary; + Int_t n = primvtx->GetNIndices(); + fNsectrk2prim = 0; + fPVx2 = -999.; + fPVy2 = -999.; + + if (n>0 && primvtx->GetStatus()){ + kfESDprimary = AliKFVertex(*primvtx); + UShort_t *priIndex = primvtx->GetIndices(); + for(Int_t j=0; jGetLabel()); - TParticle* mcpart = fStack->Particle(label); + AliMCParticle *mctrack = NULL; + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) return 0; + TParticle *mcpart = mctrack->Particle(); + if ( !mcpart ) return 0; Int_t pdgCode = mcpart->GetPdgCode(); @@ -580,8 +996,15 @@ Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2) // if (trk1->GetLabel()<0 || trk2->GetLabel()<0) return 0; - TParticle* part1 = fStack->Particle(trk1->GetLabel()); - TParticle* part2 = fStack->Particle(trk2->GetLabel()); + + AliMCParticle *mctrack = NULL; + AliMCParticle *mctrack1 = NULL; + AliMCParticle *mctrack2 = NULL; + if(!(mctrack1 = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(trk1->GetLabel()))))) return 0; + if(!(mctrack2 = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(trk2->GetLabel()))))) return 0; + TParticle *part1 = mctrack1->Particle(); + TParticle *part2 = mctrack2->Particle(); + TParticle* part2cp = part2; if (!(part1) || !(part2)) return 0; @@ -598,7 +1021,9 @@ Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2) if (label2 < 0) break; if (label1 == label2){ //check if two tracks are originated from same mother - TParticle* commonmom = fStack->Particle(label2); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(label2))))) return 0; + TParticle* commonmom = mctrack->Particle(); + srcpdg = abs(commonmom->GetPdgCode()); //check ancester to see if it is originally from beauty @@ -606,7 +1031,9 @@ Int_t AliHFEsecVtx::GetPairOriginESD(AliESDtrack* trk1, AliESDtrack* trk2) Int_t ancesterlabel = commonmom->GetFirstMother(); if (ancesterlabel < 0) return srcpdg; // if there is no more commonancester, return commonmom's pdg - TParticle* commonancester = fStack->Particle(ancesterlabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(ancesterlabel))))) return 0; + TParticle* commonancester = mctrack->Particle(); + Int_t ancesterpdg = abs(commonancester->GetPdgCode()); for (Int_t l=0; lParticle(label2); //if their mother is different, go to earlier generation of 2nd particle + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(label2))))) return 0; + part2 = mctrack->Particle(); //if their mother is different, go to earlier generation of 2nd particle + if (!(part2)) break; } - part1 = fStack->Particle(label1); //if their mother is different, go to earlier generation of 1st particle + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(label1))))) return 0; + part1 = mctrack->Particle(); //if their mother is different, go to earlier generation of 1st particle part2 = part2cp; if (!(part1)) return 0; } @@ -748,7 +1178,16 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack) return -1; } - TParticle* mcpart = fStack->Particle(iTrack); + AliMCParticle *mctrack = NULL; + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(iTrack))))) return -1; + TParticle *mcpart = mctrack->Particle(); + + if(!mcpart){ + AliDebug(1, "no mc particle, return\n"); + return -1; + } + + if ( abs(mcpart->GetPdgCode()) != 11 ) return kMisID; // if ( abs(mcpart->GetPdgCode()) != 11 ) return -1; // check if it is electron ! @@ -761,7 +1200,9 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack) Int_t origin = -1; Bool_t isFinalOpenCharm = kFALSE; - TParticle *partMother = fStack->Particle(iLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(iLabel))))) return -1; + TParticle *partMother = mctrack->Particle(); + Int_t maPdgcode = partMother->GetPdgCode(); // if the mother is charmed hadron @@ -788,7 +1229,9 @@ Int_t AliHFEsecVtx::GetElectronSource(Int_t iTrack) } // if there is an ancester - TParticle* grandMa = fStack->Particle(jLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1; + TParticle *grandMa = mctrack->Particle(); + Int_t grandMaPDG = grandMa->GetPdgCode(); for (Int_t j=0; jParticle(jLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1; + TParticle *grandMa = mctrack->Particle(); + Int_t grandMaPDG = grandMa->GetPdgCode(); for (Int_t j=0; jParticle(jLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1; + TParticle *grandMa = mctrack->Particle(); + Int_t grandMaPDG = grandMa->GetPdgCode(); for (Int_t j=0; jParticle(jLabel); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(jLabel))))) return -1; + TParticle *grandMa = mctrack->Particle(); + Int_t grandMaPDG = grandMa->GetPdgCode(); for (Int_t j=0; jGetLabel()); Int_t pdgCode; + AliMCParticle *mctrack = NULL; if (IsAODanalysis()) { AliAODMCParticle *mcpart = (AliAODMCParticle*)fMCArray->At(label); @@ -967,7 +1417,9 @@ Int_t AliHFEsecVtx::GetMCPDG(AliVTrack *track) pdgCode = mcpart->GetPdgCode(); } else { - TParticle* mcpart = fStack->Particle(label); + if(!(mctrack = dynamic_cast(fMCEvent->GetTrack(TMath::Abs(label))))) return 0; + TParticle *mcpart = mctrack->Particle(); + if ( !mcpart ) return 0; pdgCode = mcpart->GetPdgCode(); } @@ -1125,16 +1577,16 @@ void AliHFEsecVtx::MakeContainer(){ // const Int_t nDimPair=6; - Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 11}; - //Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 11, 1000, 1000, 60, 60}; + Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 13}; + //Int_t nBinPair[nDimPair] = {200, 500, 314, 2000, 2000, 13, 60, 60, 2000, 2000}; const Double_t kInvmassmin = 0., kInvmassmax = 20.; const Double_t kKFChi2min = 0, kKFChi2max= 50; const Double_t kOpenanglemin = 0, kOpenanglemax = 3.14; const Double_t kSignedLxymin = -10, kSignedLxymax= 10; const Double_t kKFIPmin = -10, kKFIPmax= 10; - const Double_t kPairCodemin = -1, kPairCodemax= 10; - //const Double_t kDCAsigmin = 0, kDCAsigmax= 5; + const Double_t kPairCodemin = -1, kPairCodemax= 12; //const Double_t kPtmin = 0, kPtmax= 30; + //const Double_t kDCAsigmin = -5, kDCAsigmax= 5; Double_t* binEdgesPair[nDimPair]; for(Int_t ivar = 0; ivar < nDimPair; ivar++) @@ -1146,23 +1598,25 @@ void AliHFEsecVtx::MakeContainer(){ for(Int_t i=0; i<=nBinPair[3]; i++) binEdgesPair[3][i]=(Double_t)kSignedLxymin + (kSignedLxymax - kSignedLxymin)/nBinPair[3]*(Double_t)i; for(Int_t i=0; i<=nBinPair[4]; i++) binEdgesPair[4][i]=(Double_t)kKFIPmin + (kKFIPmax - kKFIPmin)/nBinPair[4]*(Double_t)i; for(Int_t i=0; i<=nBinPair[5]; i++) binEdgesPair[5][i]=(Double_t)kPairCodemin + (kPairCodemax - kPairCodemin)/nBinPair[5]*(Double_t)i; - /*for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kDCAsigmin + (kDCAsigmax - kDCAsigmin)/nBinPair[6]*(Double_t)i; - for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i]; - for(Int_t i=0; i<=nBinPair[8]; i++) binEdgesPair[8][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinPair[8]*(Double_t)i; - for(Int_t i=0; i<=nBinPair[9]; i++) binEdgesPair[9][i]=binEdgesPair[8][i];*/ + //for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinPair[6]*(Double_t)i; + //for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i]; + //for(Int_t i=0; i<=nBinPair[6]; i++) binEdgesPair[6][i]=(Double_t)kDCAsigmin + (kDCAsigmax - kDCAsigmin)/nBinPair[6]*(Double_t)i; + //for(Int_t i=0; i<=nBinPair[7]; i++) binEdgesPair[7][i]=binEdgesPair[6][i]; - fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code", nDimPair, nBinPair); - //fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; dca sig trk1; dca sig trk2; pt trk1; pt trk2 ", nDimPair, nBinPair); + fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; dca1; dca2", nDimPair, nBinPair); + //fPairQA = new THnSparseF("pairQA", "QA for Pair; invmass[GeV/c^2]; KF chi2; opening angle; signed Lxy; KF ip; pair code; pt1; pt2; dca1; dca2", nDimPair, nBinPair); for(Int_t idim = 0; idim < nDimPair; idim++){ fPairQA->SetBinEdges(idim, binEdgesPair[idim]); } fSecVtxList->AddAt(fPairQA,0); - const Int_t nDimSecvtx=6; + const Int_t nDimSecvtx=9; Double_t* binEdgesSecvtx[nDimSecvtx]; - Int_t nBinSecvtx[nDimSecvtx] = {200, 500, 2000, 2000, 11, 3}; - const Double_t kNtrksmin = 0, kNtrksmax= 3; + Int_t nBinSecvtx[nDimSecvtx] = {200, 500, 2000, 2000, 13, 10, 4, 2000, 500}; + const Double_t kNtrksmin = 0, kNtrksmax= 10; + const Double_t kTrueBmin = 0, kTrueBmax= 4; + const Double_t kPtmin = 0, kPtmax= 50; for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++) binEdgesSecvtx[ivar] = new Double_t[nBinSecvtx[ivar] + 1]; @@ -1172,6 +1626,9 @@ void AliHFEsecVtx::MakeContainer(){ for(Int_t i=0; i<=nBinSecvtx[3]; i++) binEdgesSecvtx[3][i]=binEdgesPair[4][i]; for(Int_t i=0; i<=nBinSecvtx[4]; i++) binEdgesSecvtx[4][i]=binEdgesPair[5][i]; for(Int_t i=0; i<=nBinSecvtx[5]; i++) binEdgesSecvtx[5][i]=(Double_t)kNtrksmin + (kNtrksmax - kNtrksmin)/nBinSecvtx[5]*(Double_t)i; + for(Int_t i=0; i<=nBinSecvtx[6]; i++) binEdgesSecvtx[6][i]=(Double_t)kTrueBmin + (kTrueBmax - kTrueBmin)/nBinSecvtx[6]*(Double_t)i; + for(Int_t i=0; i<=nBinSecvtx[7]; i++) binEdgesSecvtx[7][i]=binEdgesPair[3][i]; + for(Int_t i=0; i<=nBinSecvtx[8]; i++) binEdgesSecvtx[8][i]=(Double_t)kPtmin + (kPtmax - kPtmin)/nBinSecvtx[8]*(Double_t)i; fSecvtxQA = new THnSparseF("secvtxQA", "QA for Secvtx; invmass[GeV/c^2]; KF chi2; signed Lxy; KF ip; pair code; n tracks ", nDimSecvtx, nBinSecvtx); for(Int_t idim = 0; idim < nDimSecvtx; idim++){ @@ -1179,6 +1636,7 @@ void AliHFEsecVtx::MakeContainer(){ } fSecVtxList->AddAt(fSecvtxQA,1); + for(Int_t ivar = 0; ivar < nDimPair; ivar++) delete binEdgesPair[ivar]; for(Int_t ivar = 0; ivar < nDimSecvtx; ivar++) diff --git a/PWG3/hfe/AliHFEsecVtx.h b/PWG3/hfe/AliHFEsecVtx.h index f316fdce873..45dde233d2f 100644 --- a/PWG3/hfe/AliHFEsecVtx.h +++ b/PWG3/hfe/AliHFEsecVtx.h @@ -37,10 +37,11 @@ class AliAODEvent; class AliVTrack; class AliESDtrack; class AliAODTrack; -class AliStack; +class AliMCEvent; class AliHFEtrackFilter; class AliHFEpairs; class AliHFEsecVtxs; +class AliKFParticle; //________________________________________________________________ class AliHFEsecVtx : public TObject { @@ -64,7 +65,7 @@ class AliHFEsecVtx : public TObject { void SetESDAnalysis() { SetBit(kAODanalysis, kFALSE); }; void SetEvent(AliESDEvent* const ESD){fESD1=ESD;}; // set ESD pointer void SetEventAOD(AliAODEvent* const AOD){fAOD1=AOD;}; // set ESD pointer - void SetStack(AliStack* const stack){fStack=stack;}; // set stack pointer + void SetMCEvent(AliMCEvent* const mcEvent){fMCEvent=mcEvent;}; // set stack pointer void SetMCArray(TClonesArray* const mcarry){fMCArray=mcarry;} // set mcarray pointer void SetUseMCPID(Bool_t usemcpid){fUseMCPID=usemcpid;}; @@ -78,6 +79,7 @@ class AliHFEsecVtx : public TObject { Int_t GetPDG(AliVTrack *track); // return pdg void GetESDPID(AliESDtrack *track, Int_t &recpid, Double_t &recprob); //return esd pid likelihood void GetPrimaryCondition(); + void RecalcPrimvtx(Int_t nkftrk, Int_t * const, AliKFParticle * const); //recalculate primary vertex TClonesArray *HFEpairs(); TClonesArray *HFEsecvtxs(); @@ -101,20 +103,24 @@ class AliHFEsecVtx : public TObject { void Init(); void FindSECVTXCandid(AliVTrack *track); void CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3); // calculated distinctive variables + void CalcSECVTXProperty(AliVTrack* track1, AliVTrack* track2, AliVTrack* track3, AliVTrack* track4); // calculated distinctive variables + void Fill4TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair, Int_t kpair); + void Fill3TrkSECVTX(AliVTrack* track, Int_t ipair, Int_t jpair); + void Fill2TrkSECVTX(AliVTrack* track, AliHFEpairs *pair); private: enum{ kHasMCData = BIT(15), // bitset for mc data usage kAODanalysis = BIT(16) // bitset for aod analysis }; - enum {kAll, kDirectCharm, kDirectBeauty, kBeautyCharm, kGamma, kPi0, kElse, kBeautyGamma, kBeautyPi0, kBeautyElse}; // electron origin + enum {kAll, kDirectCharm, kDirectBeauty, kBeautyCharm, kGamma, kPi0, kElse, kBeautyGamma, kBeautyPi0, kBeautyElse, kMisID}; // electron origin enum {kCharm=4, kBeauty=5}; // quark flavor AliHFEtrackFilter *fFilter; // filter Tracks to combine the signal track with AliESDEvent* fESD1; // ESD pointer AliAODEvent* fAOD1; // AOD pointer - AliStack* fStack; // stack pointer + AliMCEvent* fMCEvent; // MCEvent pointer Bool_t fUseMCPID; // if use MC pid @@ -127,6 +133,7 @@ class AliHFEsecVtx : public TObject { Int_t fNoOfHFEpairs; // number of e-h pairs Int_t fNoOfHFEsecvtxs; // number of secondary vertexes + Int_t fArethereSecVtx; // checker TClonesArray *fHFEpairs; //! Array of pair TClonesArray *fHFEsecvtxs; //! Array of secondary vertexes @@ -134,12 +141,21 @@ class AliHFEsecVtx : public TObject { Double_t fPVx; // primary vertex copy x Double_t fPVy; // primary vertex copy y + Double_t fPVx2; // recalculated primary vertex x + Double_t fPVy2; // recalculated primary vertex y Double_t fCosPhi; // cos of opening angle of two pair vertex Double_t fSignedLxy; // signed Lxy of secondary vertex + Double_t fSignedLxy2; // signed Lxy of secondary vertex based on recalculated primary vertex Double_t fKFchi2; // chi2 of secondary vertex Double_t fInvmass; // invariant mass of secondary vertex Double_t fInvmassSigma; // invariant mass sigma of secondary vertex Double_t fKFip; // impact parameter of secondary vertex track + Double_t fKFip2; // impact parameter of secondary vertex track based on recalculated primary vertex + + Int_t fNsectrk2prim; // # of secvtx tracks contributing to primvtx calculation + + Double_t fVtxchi2Tightcut; // pair vertex chi2 cut + Double_t fVtxchi2Loosecut; // secvtx vertex chi2 cut THnSparseF *fPairQA; // qa histos for pair analysis THnSparseF *fSecvtxQA; // qa histos for secvtx diff --git a/PWG3/hfe/AliHFEsecVtxs.cxx b/PWG3/hfe/AliHFEsecVtxs.cxx index 8ec88b8a3e6..66a5a8ad0d8 100644 --- a/PWG3/hfe/AliHFEsecVtxs.cxx +++ b/PWG3/hfe/AliHFEsecVtxs.cxx @@ -30,10 +30,13 @@ ClassImp(AliHFEsecVtxs) AliHFEsecVtxs::AliHFEsecVtxs(): fTrkLabel1(0) ,fTrkLabel2(0) + ,fMCCode(0) ,fInvmass(0) ,fKFChi2(0) ,fSignedLxy(0) + ,fSignedLxy2(0) ,fKFIP(0) + ,fKFIP2(0) { // // Default constructor @@ -45,10 +48,13 @@ AliHFEsecVtxs::AliHFEsecVtxs(const AliHFEsecVtxs &p): TObject(p) ,fTrkLabel1(p.fTrkLabel1) ,fTrkLabel2(p.fTrkLabel2) + ,fMCCode(p.fMCCode) ,fInvmass(p.fInvmass) ,fKFChi2(p.fKFChi2) ,fSignedLxy(p.fSignedLxy) + ,fSignedLxy2(p.fSignedLxy2) ,fKFIP(p.fKFIP) + ,fKFIP2(p.fKFIP2) { // // Copy constructor diff --git a/PWG3/hfe/AliHFEsecVtxs.h b/PWG3/hfe/AliHFEsecVtxs.h index 24a94495239..9815b669bcb 100644 --- a/PWG3/hfe/AliHFEsecVtxs.h +++ b/PWG3/hfe/AliHFEsecVtxs.h @@ -36,29 +36,38 @@ class AliHFEsecVtxs : public TObject { Int_t GetTrkLabel1() const {return fTrkLabel1;} Int_t GetTrkLabel2() const {return fTrkLabel2;} + Int_t GetMCCode() const {return fMCCode;} Double_t GetInvmass() const {return fInvmass;} Double_t GetKFChi2() const {return fKFChi2;} Double_t GetSignedLxy() const {return fSignedLxy;} + Double_t GetSignedLxy2() const {return fSignedLxy2;} Double_t GetKFIP() const {return fKFIP;} + Double_t GetKFIP2() const {return fKFIP2;} void SetTrkLabel1(Int_t label) {fTrkLabel1 = label;} void SetTrkLabel2(Int_t label) {fTrkLabel2 = label;} void SetInvmass(Double_t invmass) {fInvmass = invmass;} void SetKFChi2(Double_t kfchi2) {fKFChi2 = kfchi2;} void SetSignedLxy(Double_t signedlxy) {fSignedLxy = signedlxy;} + void SetSignedLxy2(Double_t signedlxy2) {fSignedLxy2 = signedlxy2;} void SetKFIP(Double_t kfip) {fKFIP = kfip;} + void SetKFIP2(Double_t kfip2) {fKFIP2 = kfip2;} + void SetMCCode(Int_t mccode) {fMCCode = mccode;} protected: Int_t fTrkLabel1; // track 1 label associated to secvtx Int_t fTrkLabel2; // track 2 label associated to secvtx + Int_t fMCCode; // track mc code Double_t fInvmass; // secvtx invariant mass Double_t fKFChi2; // secvtx chi2 Double_t fSignedLxy; // secvtx signed Lxy - Double_t fKFIP; // secvtx impact parameter + Double_t fSignedLxy2; // recalculated secvtx signed Lxy + Double_t fKFIP; // secvtx impact parameter + Double_t fKFIP2; // recalculated secvtx impact parameter private: - ClassDef(AliHFEsecVtxs,0); + ClassDef(AliHFEsecVtxs,1); }; #endif diff --git a/PWG3/hfe/AliHFEtools.cxx b/PWG3/hfe/AliHFEtools.cxx index 1d5e5c289ea..91af78ad4fd 100644 --- a/PWG3/hfe/AliHFEtools.cxx +++ b/PWG3/hfe/AliHFEtools.cxx @@ -28,12 +28,17 @@ #include "TAxis.h" #include "AliAODMCParticle.h" +#include "AliESDpid.h" #include "AliLog.h" +#include "AliTOFPIDResponse.h" #include "AliHFEtools.h" ClassImp(AliHFEtools) +AliESDpid *AliHFEtools::fgDefaultPID = NULL; +Int_t AliHFEtools::fgLogLevel = 1; + //__________________________________________ AliHFEtools::AliHFEtools(): TObject() @@ -148,3 +153,50 @@ Float_t AliHFEtools::GetRapidity(AliAODMCParticle *part){ return rapidity; } +//__________________________________________ +AliESDpid* AliHFEtools::GetDefaultPID(Bool_t isMC){ + // + // Get the default PID as singleton instance + // + if(!fgDefaultPID){ + fgDefaultPID = new AliESDpid; + Double_t tres = isMC ? 80. : 130.; + fgDefaultPID->GetTOFResponse().SetTimeResolution(tres); + + // TPC Bethe Bloch parameters + Double_t alephParameters[5]; + if(isMC){ + // simulation + alephParameters[0] = 2.15898e+00/50.; + alephParameters[1] = 1.75295e+01; + alephParameters[2] = 3.40030e-09; + alephParameters[3] = 1.96178e+00; + alephParameters[4] = 3.91720e+00; + } else { + alephParameters[0] = 0.0283086/0.97; + //alephParameters[0] = 0.0283086; + alephParameters[1] = 2.63394e+01; + alephParameters[2] = 5.04114e-11; + alephParameters[3] = 2.12543e+00; + alephParameters[4] = 4.88663e+00; + } + fgDefaultPID->GetTPCResponse().SetBetheBlochParameters(alephParameters[0],alephParameters[1],alephParameters[2], alephParameters[3],alephParameters[4]); + + } + if(fgLogLevel){ + printf("Error - You are using the default PID: You should use the PID coming from the tender"); + printf("Error - Arrrrrrrrr..."); + printf("Error - Please rethink your program logic. Using default PID is really dangerous"); + printf("Error - TOF PID is adapted to Monte Carlo"); + } + return fgDefaultPID; +} + +//__________________________________________ +void AliHFEtools::DestroyDefaultPID(){ + // + // Destroy default PID object if existing + // + if(fgDefaultPID) delete fgDefaultPID; + fgDefaultPID = NULL; +} diff --git a/PWG3/hfe/AliHFEtools.h b/PWG3/hfe/AliHFEtools.h index 3aa47883077..6c4527ac8aa 100644 --- a/PWG3/hfe/AliHFEtools.h +++ b/PWG3/hfe/AliHFEtools.h @@ -24,6 +24,7 @@ class TParticle; class AliAODMCParticle; +class AliESDpid; class AliHFEtools : public TObject{ public: @@ -35,6 +36,13 @@ class AliHFEtools : public TObject{ Bool_t BinLogAxis(TObject *o, Int_t dim); static Float_t GetRapidity(TParticle *part); static Float_t GetRapidity(AliAODMCParticle *part); // return rapidity + static AliESDpid *GetDefaultPID(Bool_t isMC = kTRUE); + static void DestroyDefaultPID(); + static void SetLogLevel(Int_t loglevel) { fgLogLevel = loglevel ;} + + private: + static AliESDpid *fgDefaultPID; // Default PID object + static Int_t fgLogLevel; // Log Level ClassDef(AliHFEtools, 0) }; diff --git a/PWG3/hfe/AliHFEtrackFilter.cxx b/PWG3/hfe/AliHFEtrackFilter.cxx index 2fe5bbcff18..e7c37707e33 100644 --- a/PWG3/hfe/AliHFEtrackFilter.cxx +++ b/PWG3/hfe/AliHFEtrackFilter.cxx @@ -383,8 +383,8 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepRecKineITSTPC(){ // AliHFEcutStep *fCutStep = new AliHFEcutStep("RecKineITSTPC"); - AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts("QualityRec","REC Track Quality Cuts"); - trackQuality->SetMinNClusterTPC(50); + AliCFTrackQualityCuts *trackQuality = new AliCFTrackQualityCuts((Char_t *)"QualityRec", (Char_t *)"REC Track Quality Cuts"); + trackQuality->SetMinNClusterTPC(80); trackQuality->SetMaxChi2PerClusterTPC(3.5); trackQuality->SetStatus(AliESDtrack::kTPCrefit | AliESDtrack::kITSrefit); trackQuality->SetMaxCovDiagonalElements(2., 2., 0.5, 0.5, 2); @@ -394,9 +394,9 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepRecKineITSTPC(){ hfecuts->SetClusterRatioTPC(0.6); fCutStep->AddCut(hfecuts); - AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts("RecKine", "REC Kine Cuts"); - kineCuts->SetPtRange(0.1, 10); - kineCuts->SetEtaRange(-0.9, 0.9); + AliCFTrackKineCuts *kineCuts = new AliCFTrackKineCuts((Char_t *)"RecKine", (Char_t *)"REC Kine Cuts"); + kineCuts->SetPtRange(0.1, 20); + kineCuts->SetEtaRange(-0.8, 0.8); fCutStep->AddCut(kineCuts); AddCutStep(fCutStep); @@ -411,9 +411,9 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepPrimary(){ // AliHFEcutStep *fCutStep = new AliHFEcutStep("Primary"); - AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts("PrimaryCuts", "REC Primary Cuts"); - primaryCut->SetMaxDCAToVertexXY(2.); - primaryCut->SetMaxDCAToVertexZ(10.); + AliCFTrackIsPrimaryCuts *primaryCut = new AliCFTrackIsPrimaryCuts((Char_t *)"PrimaryCuts", (Char_t *)"REC Primary Cuts"); + primaryCut->SetMaxDCAToVertexXY(0.5); + primaryCut->SetMaxDCAToVertexZ(5.); primaryCut->SetAcceptKinkDaughters(kFALSE); fCutStep->AddCut(primaryCut); @@ -429,7 +429,7 @@ AliHFEcutStep *AliHFEtrackFilter::MakeCutStepHFEITS(){ // AliHFEcutStep *fCutStep = new AliHFEcutStep("HFEITS"); - AliHFEextraCuts *hfecuts = new AliHFEextraCuts("HFEPixelsCuts","Extra cuts from the HFE group"); + AliHFEextraCuts *hfecuts = new AliHFEextraCuts((Char_t *)"HFEPixelsCuts",(Char_t *)"Extra cuts from the HFE group"); hfecuts->SetRequireITSpixel(AliHFEextraCuts::kFirst); //hfecuts->SetCheckITSstatus(kTRUE); fCutStep->AddCut(hfecuts); @@ -461,17 +461,18 @@ AliHFEcutStep *AliHFEtrackFilter::MakeMCSignalCuts(){ // Cut step is already included in the filter // fMCsignal = new AliHFEcutStep("MCSignal"); - AliCFParticleGenCuts *genCuts = new AliCFParticleGenCuts("fCutsGenMC", "Particle Generation Cuts"); + AliCFParticleGenCuts *genCuts = new AliCFParticleGenCuts((Char_t *)"fCutsGenMC", (Char_t *)"Particle Generation Cuts"); genCuts->SetRequireIsCharged(); genCuts->SetRequireIsPrimary(); - genCuts->SetProdVtxRangeX(-2, 2); - genCuts->SetProdVtxRangeY(-2, 2); + genCuts->SetProdVtxRange2D(); + genCuts->SetProdVtxRangeX(0, 1); + genCuts->SetProdVtxRangeY(0, 1); genCuts->SetRequirePdgCode(11, kTRUE); fMCsignal->AddCut(genCuts); - AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts("fCutsKineMC","MC Kine Cuts"); - kineMCcuts->SetPtRange(0.1, 10.); - kineMCcuts->SetEtaRange(-0.9, 0.9); + AliCFTrackKineCuts *kineMCcuts = new AliCFTrackKineCuts((Char_t *)"fCutsKineMC",(Char_t *)"MC Kine Cuts"); + kineMCcuts->SetPtRange(0.1, 20.); + kineMCcuts->SetEtaRange(-0.8, 0.8); fMCsignal->AddCut(kineMCcuts); return fMCsignal; diff --git a/PWG3/libPWG3hfe.pkg b/PWG3/libPWG3hfe.pkg index 845f4aa5dc2..211a6820da1 100644 --- a/PWG3/libPWG3hfe.pkg +++ b/PWG3/libPWG3hfe.pkg @@ -9,8 +9,11 @@ SRCS=hfe/AliHFEtools.cxx \ hfe/AliHFEsecVtx.cxx \ hfe/AliHFEpriVtx.cxx \ hfe/AliHFEelecbackground.cxx \ + hfe/AliHFEspectrum.cxx \ + hfe/AliHFEV0info.cxx \ hfe/AliHFEV0pid.cxx \ hfe/AliHFEpidQA.cxx \ + hfe/AliHFEtrdPIDqa.cxx \ hfe/AliHFEpid.cxx \ hfe/AliHFEpidBase.cxx \ hfe/AliHFEpidITS.cxx \ @@ -30,7 +33,8 @@ SRCS=hfe/AliHFEtools.cxx \ hfe/AliAnalysisTaskHFEpidQA.cxx \ hfe/AliHFEefficiency.cxx \ hfe/AliAnalysisTaskHFE.cxx \ - hfe/AliHFEV0pidMC.cxx + hfe/AliHFEV0pidMC.cxx \ + hfe/AliHFEV0cuts.cxx HDRS= $(SRCS:.cxx=.h) DHDR= PWG3hfeLinkDef.h