3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* Sedat Altinpinar <Sedat.Altinpinar@cern.ch> *
9 //* Hege Erdal <hege.erdal@gmail.com> *
11 //* Permission to use, copy, modify and distribute this software and its *
12 //* documentation strictly for non-commercial purposes is hereby granted *
13 //* without fee, provided that the above copyright notice appears in all *
14 //* copies and that both the copyright notice and this permission notice *
15 //* appear in the supporting documentation. The authors make no claims *
16 //* about the suitability of this software for any purpose. It is *
17 //* provided "as is" without express or implied warranty. *
18 //**************************************************************************
20 /// @file AliDxHFEParticleSelectionEl.cxx
21 /// @author Sedat Altinpinar, Hege Erdal, Matthias Richter
23 /// @brief D0 selection for D0-HFE correlation
25 #include "AliDxHFEParticleSelectionEl.h"
26 #include "AliVParticle.h"
27 #include "AliVEvent.h"
29 #include "AliPIDResponse.h"
30 #include "AliHFEcontainer.h"
31 #include "AliHFEpid.h"
32 #include "AliHFEpidBase.h"
33 #include "AliHFEtools.h"
34 #include "AliHFEcuts.h"
35 #include "AliAODTrack.h"
36 #include "AliAnalysisDataSlot.h"
37 #include "AliAnalysisDataContainer.h"
38 #include "AliAnalysisManager.h"
39 #include "AliCFManager.h"
40 #include "THnSparse.h"
45 #include "TObjArray.h"
52 /// ROOT macro for the implementation of ROOT specific class methods
53 ClassImp(AliDxHFEParticleSelectionEl)
55 AliDxHFEParticleSelectionEl::AliDxHFEParticleSelectionEl(const char* opt)
56 : AliDxHFEParticleSelection("electron", opt)
59 , fElectronProperties(NULL)
73 AliDxHFEParticleSelectionEl::~AliDxHFEParticleSelectionEl()
76 if (fElectronProperties) {
77 delete fElectronProperties;
78 fElectronProperties=NULL;
92 // NOTE: external objects fPID and fCuts are not deleted here
98 const char* AliDxHFEParticleSelectionEl::fgkCutBinNames[]={
110 int AliDxHFEParticleSelectionEl::Init()
117 // Implicit call to InitControlObjects() before setting up CFM and fCuts
119 iResult=AliDxHFEParticleSelection::Init();
120 if (iResult<0) return iResult;
122 //--------Initialize correction Framework and Cuts-------------------------
123 // Consider moving this, either to separate function or
124 // add a set function for AliCFManager
125 // Do we need this? Can we just call AliHFEcuts::CheckParticleCuts
126 AliInfo("Setting up CFM");
127 fCFM = new AliCFManager;
128 // the setup of cut objects is done in AliHFEcuts::Initialize
129 // the ids used by this class must be the same, the code might be broken if
130 // the sequence in AliHFEcuts::Initialize is changed
131 const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack;
132 // reset pointers in the CF manager
133 fCFM->SetNStepParticle(kNcutSteps);
134 for(Int_t istep = 0; istep < kNcutSteps; istep++) {
135 fCFM->SetParticleCutsList(istep, NULL);
138 AliWarning("Cuts not available. Default cuts will be used");
139 fCuts = new AliHFEcuts;
140 fCuts->CreateStandardCuts();
142 // TODO: error handling?
143 fCuts->Initialize(fCFM);
149 THnSparse* AliDxHFEParticleSelectionEl::DefineTHnSparse()
152 // Defines the THnSparse. For now, only calls CreatControlTHnSparse
154 // here is the only place to change the dimension
155 const int thnSize = 3;
156 InitTHnSparseArray(thnSize);
157 const double Pi=TMath::Pi();
159 name.Form("%s info", GetName());
163 int thnBins [thnSize] = { 1000, 200, 500};
164 double thnMin [thnSize] = { 0, 0, -1.};
165 double thnMax [thnSize] = { 100, 2*Pi, 1.};
166 const char* thnNames[thnSize] = { "Pt","Phi","Eta"};
168 return CreateControlTHnSparse(name,thnSize,thnBins,thnMin,thnMax,thnNames);
171 int AliDxHFEParticleSelectionEl::InitControlObjects()
173 /// init control and monitoring objects
174 AliInfo("Electron THnSparse");
176 fElectronProperties=DefineTHnSparse();
177 AddControlObject(fElectronProperties);
179 double dEdxBins[6]={1000,0.,10.,200,0.,200.};
180 double nSigBins[6]={1000,0.,10.,200,-10.,10.};
182 fHistoList=new TList;
183 fHistoList->SetName("HFE Histograms");
184 fHistoList->SetOwner();
186 // Histogram storing which cuts have been applied to the tracks
187 fHistoList->Add(CreateControlHistogram("fWhichCut","effective cut for a rejected particle", kNCutLabels, fgkCutBinNames));
189 // dEdx plots, TPC signal vs momentum
190 fHistoList->Add(CreateControl2DHistogram("fdEdx", "dEdx before cuts", dEdxBins,"momentum (GeV/c)","dE/dx in TPC (a.u.)"));
191 fHistoList->Add(CreateControl2DHistogram("fdEdxCut", "dEdx after cuts",dEdxBins,"momentum (GeV/c)","dE/dx in TPC (a.u.)"));
192 fHistoList->Add(CreateControl2DHistogram("fdEdxPidTOF", "dEdx after TOF pid",dEdxBins,"momentum (GeV/c)","dE/dx in TPC (a.u.)"));
193 fHistoList->Add(CreateControl2DHistogram("fdEdxPid", "dEdx after pid",dEdxBins,"momentum (GeV/c)","dE/dx in TPC (a.u.)"));
195 // nSigmaTPC vs momentum
196 fHistoList->Add(CreateControl2DHistogram("fnSigTPC", "nSigTPC before cuts",nSigBins,"momentum (GeV/c)","nSigma in TPC (a.u.)"));
197 fHistoList->Add(CreateControl2DHistogram("fnSigTPCCut", "nSigmaTPC after cuts",nSigBins,"momentum (GeV/c)","nSigma in TPC (a.u.)"));
198 fHistoList->Add(CreateControl2DHistogram("fnSigTPCPidTOF", "nSigmaTPC after TOF PID", nSigBins,"momentum (GeV/c)","nSigma in TPC (a.u.)"));
199 fHistoList->Add(CreateControl2DHistogram("fnSigTPCPid", "nSigmaTPC after PID", nSigBins,"momentum (GeV/c)","nSigma in TPC (a.u.)"));
201 // nSigmaTOF vs momentum
202 fHistoList->Add(CreateControl2DHistogram("fnSigTOF", "nSigmaTOF before cuts",nSigBins,"momentum (GeV/c)","nSigma in TOF (a.u.)"));
203 fHistoList->Add(CreateControl2DHistogram("fnSigTOFCut", "nSigmaTOF after cuts",nSigBins,"momentum (GeV/c)","nSigma in TOF (a.u.)"));
204 fHistoList->Add(CreateControl2DHistogram("fnSigTOFPidTOF", "nSigmaTOF after TOF PID", nSigBins,"momentum (GeV/c)","nSigma in TOF (a.u.)"));
205 fHistoList->Add(CreateControl2DHistogram("fnSigTOFPid", "nSigmaTOF after PID", nSigBins,"momentum (GeV/c)","nSigma in TOF (a.u.)"));
207 AddControlObject(fHistoList);
209 return AliDxHFEParticleSelection::InitControlObjects();
212 int AliDxHFEParticleSelectionEl::HistogramParticleProperties(AliVParticle* p, int selectionCode)
214 /// histogram particle properties
215 if (!p) return -EINVAL;
216 //if (!fControlObjects) return 0;
217 if(selectionCode==0) return 0;
219 if(fElectronProperties && ParticleProperties()) {
220 FillParticleProperties(p, ParticleProperties(), GetDimTHnSparse());
221 fElectronProperties->Fill(ParticleProperties());
227 int AliDxHFEParticleSelectionEl::FillParticleProperties(AliVParticle* p, Double_t* data, int dimension) const
229 // fill the data array from the particle data
230 if (!data) return -EINVAL;
231 AliAODTrack *track=(AliAODTrack*)p;
232 if (!track) return -ENODATA;
234 if (dimension!=GetDimTHnSparse()) {
235 // TODO: think about filling only the available data and throwing a warning
238 data[i++]=track->Pt();
239 data[i++]=track->Phi();
240 data[i++]=track->Eta();
245 int AliDxHFEParticleSelectionEl::IsSelected(AliVParticle* pEl, const AliVEvent* pEvent)
247 /// select El candidates
248 // TODO: How to handle MC? would be too much duplicate code if copy entire IsSelected.
250 AliAODTrack *track=(AliAODTrack*)pEl;
251 fCFM->SetRecEventInfo(pEvent);
253 ((TH2D*)fHistoList->FindObject("fdEdx"))->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
254 ((TH2D*)fHistoList->FindObject("fnSigTPC"))->Fill(track->GetTPCmomentum(), fPIDResponse->NumberOfSigmasTPC(track,AliPID::kElectron));
255 ((TH2D*)fHistoList->FindObject("fnSigTOF"))->Fill(track->P(), fPIDResponse->NumberOfSigmasTOF(track,AliPID::kElectron));
257 //--------track cut selection-----------------------
259 // RecKine: ITSTPC cuts
260 if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track)){
261 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kRecKineITSTPC);
266 if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track)) {
267 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kRecPrim);
271 // HFEcuts: ITS layers cuts
272 if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track)) {
273 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kHFEcutsITS);
277 // HFE cuts: TOF PID and mismatch flag
278 if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTOF, track)) {
279 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kHFEcutsTOF);
283 // HFE cuts: TPC PID cleanup
284 if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTPC, track)){
285 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kHFEcutsTPC);
289 // HFEcuts: Nb of tracklets TRD0
290 //if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track)) continue;
291 ((TH2D*)fHistoList->FindObject("fdEdxCut"))->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
292 ((TH2D*)fHistoList->FindObject("fnSigTPCCut"))->Fill(track->GetTPCmomentum(), fPIDResponse->NumberOfSigmasTPC(track,AliPID::kElectron));
293 ((TH2D*)fHistoList->FindObject("fnSigTOFCut"))->Fill(track->P(), fPIDResponse->NumberOfSigmasTOF(track,AliPID::kElectron));
296 //--------PID selection-----------------------
297 AliHFEpidObject hfetrack;
298 hfetrack.SetAnalysisType(AliHFEpidObject::kAODanalysis);
299 hfetrack.SetRecTrack(track);
301 // TODO: configurable colliding system
302 //if(IsPbPb()) hfetrack.SetPbPb();
305 // TODO: Put this into a while-loop instead, looping over the number of pid objects in the cut-list?
306 // This needs a bit of thinking and finetuning (wrt histogramming)
307 if(fPIDTOF && fPIDTOF->IsSelected(&hfetrack)) {
308 ((TH2D*)fHistoList->FindObject("fdEdxPidTOF"))->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
309 ((TH2D*)fHistoList->FindObject("fnSigTPCPidTOF"))->Fill(track->GetTPCmomentum(), fPIDResponse->NumberOfSigmasTPC(track,AliPID::kElectron));
310 ((TH2D*)fHistoList->FindObject("fnSigTOFPidTOF"))->Fill(track->P(), fPIDResponse->NumberOfSigmasTOF(track,AliPID::kElectron));
313 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kPIDTOF);
317 //Combined tof & tpc pid
318 if(fPID && fPID->IsSelected(&hfetrack)) {
319 AliDebug(3,"Inside FilldPhi, electron is selected");
320 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kSelected);
321 ((TH2D*)fHistoList->FindObject("fdEdxPid"))->Fill(track->GetTPCmomentum(), track->GetTPCsignal());
322 ((TH2D*)fHistoList->FindObject("fnSigTPCPid"))->Fill(track->GetTPCmomentum(), fPIDResponse->NumberOfSigmasTPC(track,AliPID::kElectron));
323 ((TH2D*)fHistoList->FindObject("fnSigTOFPid"))->Fill(track->P(), fPIDResponse->NumberOfSigmasTOF(track,AliPID::kElectron));
327 ((TH1D*)fHistoList->FindObject("fWhichCut"))->Fill(kPID);
334 void AliDxHFEParticleSelectionEl::SetCuts(TObject* cuts, int level)
337 if (level==kCutHFE) {
338 fCuts=dynamic_cast<AliHFEcuts*>(cuts);
339 if (!fCuts && cuts) {
340 AliError(Form("Cut object is not of required type AliHFEcuts but %s", cuts->ClassName()));
345 if (level==kCutPID) {
346 fPID=dynamic_cast<AliHFEpid*>(cuts);
348 AliError(Form("cuts object is not of required type AliHFEpid but %s", cuts->ClassName()));
353 if (level==kCutPIDTOF) {
354 fPIDTOF=dynamic_cast<AliHFEpid*>(cuts);
355 if (!fPIDTOF && cuts) {
356 AliError(Form("cuts object is not of required type AliHFEpid but %s", cuts->ClassName()));
361 fCutPidList=dynamic_cast<TList*>(cuts);
362 if (!fCutPidList && cuts) {
363 AliError(Form("cuts object is not of required type TList but %s", cuts->ClassName()));
366 // TODO: Could be done more elegantly, at the moment requires that the cut and pid objects are in
367 // a specific order..
370 TIter next(fCutPidList);
371 while((obj = next())){
374 fCuts=dynamic_cast<AliHFEcuts*>(obj);
376 AliError(Form("Cut object is not of required type AliHFEcuts but %s", cuts->ClassName()));
379 fPID=dynamic_cast<AliHFEpid*>(obj);
381 AliError(Form("cuts object is not of required type AliHFEpid but %s", cuts->ClassName()));
384 fPIDTOF=dynamic_cast<AliHFEpid*>(obj);
386 AliError(Form("cuts object is not of required type AliHFEpid but %s", cuts->ClassName()));
395 //________________________________________________________________________
396 Bool_t AliDxHFEParticleSelectionEl::ProcessCutStep(Int_t cutStep, AliVParticle *track)
398 // Check single track cuts for a given cut step
399 const Int_t kMCOffset = AliHFEcuts::kNcutStepsMCTrack;
400 if(!fCFM->CheckParticleCuts(cutStep + kMCOffset, track)) return kFALSE;
401 //if(!fCuts->CheckParticleCuts(cutStep + kMCOffset, track)) return kFALSE;