1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 // Filling an AliCFContainer with the quantities pt, eta and phi
18 // for tracks which survivied the particle cuts (MC resp. ESD tracks)
19 // Track selection is done using the AliHFE package
22 // Raphaelle Bailhache <R.Bailhache@gsi.de>
23 // Markus Fasel <M.Fasel@gsi.de>
24 // Matus Kalisky <matus.kalisky@cern.ch>
25 // MinJung Kweon <minjung@physi.uni-heidelberg.de>
30 #include <TDirectory.h>
36 #include <TIterator.h>
40 #include <TObjArray.h>
41 #include <TParticle.h>
46 #include "AliAODInputHandler.h"
47 #include "AliAODMCParticle.h"
48 #include "AliAODTrack.h"
49 #include "AliCFContainer.h"
50 #include "AliCFManager.h"
51 #include "AliESDEvent.h"
52 #include "AliESDInputHandler.h"
53 #include "AliESDtrack.h"
55 #include "AliAnalysisManager.h"
56 #include "AliMCEvent.h"
57 #include "AliMCEventHandler.h"
58 #include "AliMCParticle.h"
61 #include "AliVVertex.h"
63 #include "AliHFEpid.h"
64 #include "AliHFEcollection.h"
65 #include "AliHFEcuts.h"
66 #include "AliHFEmcQA.h"
67 #include "AliHFEpairs.h"
68 #include "AliHFEpostAnalysis.h"
69 #include "AliHFEsecVtxs.h"
70 #include "AliHFEsecVtx.h"
71 #include "AliHFEelecbackground.h"
72 #include "AliHFEtools.h"
73 #include "AliAnalysisTaskHFE.h"
75 //____________________________________________________________
76 AliAnalysisTaskHFE::AliAnalysisTaskHFE():
77 AliAnalysisTaskSE("PID efficiency Analysis")
84 , fPIDperformance(NULL)
85 , fSignalToBackgroundMC(NULL)
89 , fElecBackGround(NULL)
92 , fNElectronTracksEvent(NULL)
97 , fHistELECBACKGROUND(NULL)
103 DefineOutput(1, TH1I::Class());
104 DefineOutput(2, TList::Class());
105 DefineOutput(3, TList::Class());
106 // DefineOutput(4, TList::Class());
109 fPID = new AliHFEpid;
112 //____________________________________________________________
113 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const char * name):
114 AliAnalysisTaskSE(name)
121 , fPIDperformance(NULL)
122 , fSignalToBackgroundMC(NULL)
126 , fElecBackGround(NULL)
129 , fNElectronTracksEvent(NULL)
134 , fHistELECBACKGROUND(NULL)
138 // Default constructor
140 DefineOutput(1, TH1I::Class());
141 DefineOutput(2, TList::Class());
142 DefineOutput(3, TList::Class());
143 // DefineOutput(4, TList::Class());
146 fPID = new AliHFEpid;
149 //____________________________________________________________
150 AliAnalysisTaskHFE::AliAnalysisTaskHFE(const AliAnalysisTaskHFE &ref):
151 AliAnalysisTaskSE(ref)
152 , fQAlevel(ref.fQAlevel)
153 , fPIDdetectors(ref.fPIDdetectors)
154 , fPIDstrategy(ref.fPIDstrategy)
155 , fPlugins(ref.fPlugins)
157 , fCorrelation(ref.fCorrelation)
158 , fPIDperformance(ref.fPIDperformance)
159 , fSignalToBackgroundMC(ref.fSignalToBackgroundMC)
162 , fSecVtx(ref.fSecVtx)
163 , fElecBackGround(ref.fElecBackGround)
165 , fNEvents(ref.fNEvents)
166 , fNElectronTracksEvent(ref.fNElectronTracksEvent)
168 , fOutput(ref.fOutput)
169 , fHistMCQA(ref.fHistMCQA)
170 , fHistSECVTX(ref.fHistSECVTX)
171 , fHistELECBACKGROUND(ref.fHistELECBACKGROUND)
172 // , fQAcoll(ref.fQAcoll)
179 //____________________________________________________________
180 AliAnalysisTaskHFE &AliAnalysisTaskHFE::operator=(const AliAnalysisTaskHFE &ref){
182 // Assignment operator
184 if(this == &ref) return *this;
185 AliAnalysisTask::operator=(ref);
186 fQAlevel = ref.fQAlevel;
187 fPIDdetectors = ref.fPIDdetectors;
188 fPIDstrategy = ref.fPIDstrategy;
189 fPlugins = ref.fPlugins;
191 fCorrelation = ref.fCorrelation;
192 fPIDperformance = ref.fPIDperformance;
193 fSignalToBackgroundMC = ref.fSignalToBackgroundMC;
196 fSecVtx = ref.fSecVtx;
197 fElecBackGround = ref.fElecBackGround;
199 fNEvents = ref.fNEvents;
200 fNElectronTracksEvent = ref.fNElectronTracksEvent;
202 fOutput = ref.fOutput;
203 fHistMCQA = ref.fHistMCQA;
204 fHistSECVTX = ref.fHistSECVTX;
205 fHistELECBACKGROUND = ref.fHistELECBACKGROUND;
207 // fQAcoll = ref.fQAcoll;
211 //____________________________________________________________
212 AliAnalysisTaskHFE::~AliAnalysisTaskHFE(){
216 if(fPID) delete fPID;
230 fHistSECVTX->Clear();
233 if(fHistELECBACKGROUND){
234 fHistELECBACKGROUND->Clear();
235 delete fHistELECBACKGROUND;
237 if(fSecVtx) delete fSecVtx;
238 if(fElecBackGround) delete fElecBackGround;
239 if(fMCQA) delete fMCQA;
240 if(fNEvents) delete fNEvents;
242 fCorrelation->Clear();
245 if(fPIDperformance) delete fPIDperformance;
246 if(fSignalToBackgroundMC) delete fSignalToBackgroundMC;
247 // if(fQAcoll) delete fQAcoll;
250 //____________________________________________________________
251 void AliAnalysisTaskHFE::UserCreateOutputObjects(){
253 // Creating output container and output objects
254 // Here we also Initialize the correction framework container and
259 // QA histograms are created if requested
260 // Called once per worker
262 AliDebug(3, "Creating Output Objects");
263 // Automatic determination of the analysis mode
264 AliVEventHandler *inputHandler = AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
265 if(!TString(inputHandler->IsA()->GetName()).CompareTo("AliAODInputHandler")){
269 if(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler())
272 printf("Analysis Mode: %s Analysis\n", IsAODanalysis() ? "AOD" : "ESD");
273 printf("MC Data available %s\n", HasMCData() ? "Yes" : "No");
275 // example how to use the AliHFEcollection
276 //fQAcoll = new AliHFEcollection("fQAcoll", "QA");
277 //fQAcoll->CreateTH1F("fNevents", "Number of Events in the Analysis", 2, 0, 2);
278 //fQAcoll->CreateProfile("fNtrdclusters", "Number of TRD clusters as function of momentum; p[GeV/c]", 20, 0, 20);
280 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
281 fNElectronTracksEvent = new TH1I("nElectronTracksEvent", "Number of Electron Candidates", 100, 0, 100);
282 // First Step: TRD alone
283 if(!fQA) fQA = new TList;
284 fQA->AddAt(new TProfile("conr", "Electron PID contamination", 20, 0, 20), 0);
285 fQA->AddAt(new TH1F("alpha_rec", "Alpha from reconstructed tracks with TRD hits", 36, -TMath::Pi(), TMath::Pi()), 1);
286 fQA->AddAt(new TH1F("alpha_sim", "Alpha from simulated electron tracks", 36, -TMath::Pi(), TMath::Pi()), 2);
287 fQA->AddAt(new TH1F("nElectron", "Number of electrons", 100, 0, 100), 3);
288 fQA->AddAt(new TProfile("pidquality", "TRD PID quality as function of momentum", 20, 0, 20), 4);
289 fQA->AddAt(new TProfile("ntrdclusters", "Number of TRD clusters as function of momentum", 20, 0, 20), 5);
290 fQA->AddAt(new TH1F("chi2TRD","#chi2 per TRD cluster", 20, 0, 20), 6);
291 fQA->AddAt(new TH1I("mccharge", "MC Charge", 200, -100, 100), 7);
293 if(!fOutput) fOutput = new TList;
294 // Initialize correction Framework and Cuts
295 fCFM = new AliCFManager;
296 MakeParticleContainer();
297 MakeEventContainer();
298 // Temporary fix: Initialize particle cuts with NULL
299 for(Int_t istep = 0; istep < fCFM->GetParticleContainer()->GetNStep(); istep++)
300 fCFM->SetParticleCutsList(istep, NULL);
302 AliWarning("Cuts not available. Default cuts will be used");
303 fCuts = new AliHFEcuts;
304 fCuts->CreateStandardCuts();
306 if(IsAODanalysis()) fCuts->SetAOD();
307 fCuts->Initialize(fCFM);
308 if(fCuts->IsInDebugMode()) fQA->Add(fCuts->GetQAhistograms());
310 // add output objects to the List
311 fOutput->AddAt(fCFM->GetParticleContainer(), 0);
312 fOutput->AddAt(fCFM->GetEventContainer(), 1);
313 fOutput->AddAt(fCorrelation, 2);
314 fOutput->AddAt(fPIDperformance, 3);
315 fOutput->AddAt(fSignalToBackgroundMC, 4);
316 fOutput->AddAt(fNElectronTracksEvent, 5);
320 AliInfo("PID QA switched on");
321 //fPID->SetDebugLevel(2);
323 fQA->Add(fPID->GetQAhistograms());
325 fPID->SetHasMCData(HasMCData());
326 if(!fPIDdetectors.Length() && ! fPIDstrategy) AddPIDdetector("TPC");
328 fPID->InitializePID(Form("Strategy%d", fPIDstrategy));
330 fPID->InitializePID(fPIDdetectors.Data()); // Only restrictions to TPC allowed
332 // mcQA----------------------------------
333 if (HasMCData() && IsQAOn(kMCqa)) {
335 if(!fMCQA) fMCQA = new AliHFEmcQA;
336 if(!fHistMCQA) fHistMCQA = new TList();
337 fHistMCQA->SetName("MCqa");
338 fMCQA->CreateHistograms(AliHFEmcQA::kCharm,0,"mcqa_"); // create histograms for charm
339 fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,0,"mcqa_"); // create histograms for beauty
340 fMCQA->CreateHistograms(AliHFEmcQA::kCharm,1,"mcqa_barrel_"); // create histograms for charm
341 fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,1,"mcqa_barrel_"); // create histograms for beauty
342 fMCQA->CreateHistograms(AliHFEmcQA::kCharm,2,"mcqa_unitY_"); // create histograms for charm
343 fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,2,"mcqa_unitY_"); // create histograms for beauty
344 fMCQA->CreateHistograms(AliHFEmcQA::kCharm,3,"mcqa_reccut_"); // create histograms for charm
345 fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,3,"mcqa_reccut_"); // create histograms for beauty
346 fMCQA->CreateHistograms(AliHFEmcQA::kCharm,4,"mcqa_recpidcut_"); // create histograms for charm
347 fMCQA->CreateHistograms(AliHFEmcQA::kBeauty,4,"mcqa_recpidcut_"); // create histograms for beauty
348 TIter next(gDirectory->GetList());
352 while ((obj = next.Next())) {
353 objname = obj->GetName();
354 TObjArray *toks = objname.Tokenize("_");
355 if (toks->GetEntriesFast()){
356 TObjString *fpart = (TObjString *)(toks->UncheckedAt(0));
357 if ((fpart->String()).CompareTo("mcqa") == 0) fHistMCQA->AddAt(obj, counter++);
363 // secvtx----------------------------------
364 if (GetPlugin(kSecVtx)) {
365 AliInfo("Secondary Vertex Analysis on");
366 fSecVtx = new AliHFEsecVtx;
367 fSecVtx->SetHasMCData(HasMCData());
369 if(!fHistSECVTX) fHistSECVTX = new TList();
370 fSecVtx->CreateHistograms(fHistSECVTX);
371 fOutput->Add(fHistSECVTX);
374 // background----------------------------------
375 if (GetPlugin(kIsElecBackGround)) {
376 AliInfo("Electron BackGround Analysis on");
377 if(!fElecBackGround){
378 AliWarning("ElecBackGround not available. Default elecbackground will be used");
379 fElecBackGround = new AliHFEelecbackground;
381 fElecBackGround->SetHasMCData(HasMCData());
383 if(!fHistELECBACKGROUND) fHistELECBACKGROUND = new TList();
384 fElecBackGround->CreateHistograms(fHistELECBACKGROUND);
385 fOutput->Add(fHistELECBACKGROUND);
389 //____________________________________________________________
390 void AliAnalysisTaskHFE::UserExec(Option_t *){
394 AliDebug(3, "Starting Single Event Analysis");
396 AliError("Reconstructed Event not available");
400 AliDebug(4, Form("MC Event: %p", fMCEvent));
402 AliError("No MC Event, but MC Data required");
407 AliError("HFE cuts not available");
411 if(HasMCData()) ProcessMC(); // Run the MC loop + MC QA in case MC Data are available
413 if(IsAODanalysis()) ProcessAOD();
416 PostData(1, fNEvents);
417 PostData(2, fOutput);
419 // PostData(4, fQAcoll->GetList());
422 //____________________________________________________________
423 void AliAnalysisTaskHFE::Terminate(Option_t *){
425 // Terminate not implemented at the moment
427 if(GetPlugin(kPostProcess)){
428 fOutput = dynamic_cast<TList *>(GetOutputData(2));
430 AliError("Results not available");
433 AliHFEpostAnalysis postanalysis;
434 postanalysis.SetResults(fOutput);
435 if(HasMCData())postanalysis.DrawMCSignal2Background();
436 postanalysis.DrawEfficiency();
437 postanalysis.DrawPIDperformance();
438 postanalysis.DrawCutEfficiency();
440 if (GetPlugin(kIsElecBackGround)) {
441 AliHFEelecbackground elecBackGround;
443 if(!(oe = (TList*)dynamic_cast<TList *>(fOutput->FindObject("HFEelecbackground")))){
446 elecBackGround.Load(oe);
447 elecBackGround.Plot();
448 elecBackGround.PostProcess();
453 //____________________________________________________________
454 void AliAnalysisTaskHFE::ProcessMC(){
456 // Runs the MC Loop (filling the container for the MC Cut Steps with the observables pt, eta and phi)
457 // In case MC QA is on also MC QA loop is done
459 AliDebug(3, "Processing MC Information");
460 Double_t nContrib = 0;
461 const AliVVertex *pVertex = fMCEvent->GetPrimaryVertex();
462 if(pVertex) nContrib = pVertex->GetNContributors();
463 if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepGenerated, fMCEvent)) return;
464 fCFM->GetEventContainer()->Fill(&nContrib,AliHFEcuts::kEventStepGenerated);
465 Int_t nElectrons = 0;
467 if (HasMCData() && IsQAOn(kMCqa)) {
468 AliDebug(2, "Running MC QA");
470 if(fMCEvent->Stack()){
471 fMCQA->SetStack(fMCEvent->Stack());
472 fMCQA->SetGenEventHeader(fMCEvent->GenEventHeader());
475 Int_t nMCTracks = fMCEvent->Stack()->GetNtrack();
477 // loop over all tracks for decayed electrons
478 for (Int_t igen = 0; igen < nMCTracks; igen++){
479 TParticle* mcpart = fMCEvent->Stack()->Particle(igen);
480 fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kCharm);
481 fMCQA->GetQuarkKine(mcpart, igen, AliHFEmcQA::kBeauty);
482 fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kCharm);
483 fMCQA->GetHadronKine(mcpart, AliHFEmcQA::kBeauty);
484 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 0); // no accept cut
485 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 0); // no accept cut
486 if (TMath::Abs(mcpart->Eta()) < 0.9) {
487 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
488 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 1); // accept |eta|<0.9
490 if (TMath::Abs(AliHFEtools::GetRapidity(mcpart)) < 0.5) {
491 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
492 fMCQA->GetDecayedKine(mcpart, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 2); // accept |y|<0.5
495 fMCQA->EndOfEventAna(AliHFEmcQA::kCharm);
496 fMCQA->EndOfEventAna(AliHFEmcQA::kBeauty);
499 } // end of MC QA loop
500 // -----------------------------------------------------------------
501 fCFM->SetMCEventInfo(fMCEvent);
502 // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
504 fCFM->SetMCEventInfo(fInputEvent);
507 AliVParticle *mctrack = NULL;
508 for(Int_t imc = 0; imc <fMCEvent->GetNumberOfTracks(); imc++){
509 if(!(mctrack = fMCEvent->GetTrack(imc))) continue;
510 if(ProcessMCtrack(mctrack)) nElectrons++;
513 // fCFM->CheckEventCuts(AliCFManager::kEvtRecCuts, fESD);
514 (dynamic_cast<TH1F *>(fQA->At(3)))->Fill(nElectrons);
517 //____________________________________________________________
518 void AliAnalysisTaskHFE::ProcessESD(){
520 // Run Analysis of reconstructed event in ESD Mode
521 // Loop over Tracks, filter according cut steps defined in AliHFEcuts
523 AliDebug(3, "Processing ESD Event");
524 Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
525 if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
526 fCFM->GetEventContainer()->Fill(&nContrib, AliHFEcuts::kEventStepReconstructed);
527 AliESDEvent *fESD = dynamic_cast<AliESDEvent *>(fInputEvent);
529 AliError("ESD Event required for ESD Analysis")
532 if (GetPlugin(kIsElecBackGround)) {
533 fElecBackGround->SetEvent(fESD);
535 if (GetPlugin(kSecVtx)) {
536 fSecVtx->SetEvent(fESD);
537 fSecVtx->GetPrimaryCondition();
541 if (GetPlugin(kSecVtx)) {
542 if(fMCEvent->Stack()) fSecVtx->SetStack(fMCEvent->Stack());
544 if (GetPlugin(kIsElecBackGround)) {
545 fElecBackGround->SetMCEvent(fMCEvent);
550 Double_t container[8];
551 memset(container, 0, sizeof(Double_t) * 8);
552 // container for the output THnSparse
553 Double_t dataE[5]; // [pT, eta, Phi, type, 'C' or 'B']
554 Int_t nElectronCandidates = 0;
555 AliESDtrack *track = NULL, *htrack = NULL;
556 AliMCParticle *mctrack = NULL;
557 TParticle* mctrack4QA = NULL;
559 // For double counted tracks
560 LabelContainer cont(fESD->GetNumberOfTracks());
561 Bool_t alreadyseen = kFALSE;
563 Bool_t signal = kTRUE;
565 fCFM->SetRecEventInfo(fESD);
566 // Electron background analysis
567 if (GetPlugin(kIsElecBackGround)) {
569 AliDebug(2, "Running BackGround Analysis");
571 fElecBackGround->Reset();
573 } // end of electron background analysis
577 for(Int_t itrack = 0; itrack < fESD->GetNumberOfTracks(); itrack++){
579 track = fESD->GetTrack(itrack);
581 container[0] = track->Pt();
582 container[1] = track->Eta();
583 container[2] = track->Phi();
584 container[3] = track->Charge();
586 dataE[0] = track->Pt();
587 dataE[1] = track->Eta();
588 dataE[2] = track->Phi();
589 dataE[3] = track->Charge();
595 // Fill step without any cut
598 // Check if it is electrons near the vertex
599 if(!(mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(track->GetLabel()))))) continue;
600 mctrack4QA = mctrack->Particle();//fMCEvent->Stack()->Particle(TMath::Abs(track->GetLabel()));
602 container[4] = mctrack->Pt();
603 container[5] = mctrack->Eta();
604 container[6] = mctrack->Phi();
605 container[7] = mctrack->Charge()/3.;
607 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, mctrack)) signal = kFALSE;
610 alreadyseen = cont.Find(TMath::Abs(track->GetLabel()));
611 cont.Append(TMath::Abs(track->GetLabel()));
613 fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut);
614 fCFM->GetParticleContainer()->Fill(&container[0], AliHFEcuts::kStepRecNoCut + 2*AliHFEcuts::kNcutStepsESDtrack);
616 fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepRecNoCut + AliHFEcuts::kNcutStepsESDtrack);
620 // RecKine: ITSTPC cuts
621 if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track, container, signal, alreadyseen)) continue;
623 // Check TRD criterions (outside the correction framework)
624 if(track->GetTRDncls()){
625 (dynamic_cast<TH1F *>(fQA->At(6)))->Fill(track->GetTRDchi2()/track->GetTRDncls());
626 (dynamic_cast<TH1F *>(fQA->At(1)))->Fill(track->GetAlpha()); // Check the acceptance without tight cuts
627 (dynamic_cast<TProfile *>(fQA->At(4)))->Fill(container[0], track->GetTRDpidQuality());
628 (dynamic_cast<TProfile *>(fQA->At(5)))->Fill(container[0], track->GetTRDncls());
629 //fQAcoll->Fill("fNtrdclusters", container[0], track->GetTRDncls());
634 if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track, container, signal, alreadyseen)) continue;
636 // HFEcuts: ITS layers cuts
637 if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track, container, signal, alreadyseen)) continue;
639 // HFEcuts: Nb of tracklets TRD0
640 if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTRD, track, container, signal, alreadyseen)) continue;
642 // dimensions 3&4&5 : pt,eta,phi (MC)
643 ((THnSparseF *)fCorrelation->At(0))->Fill(container);
646 if(HasMCData() && IsQAOn(kMCqa)) {
647 // mc qa for after the reconstruction cuts
648 AliDebug(2, "Running MC QA");
649 fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 3); // charm
650 fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 3); // beauty
653 // track accepted, do PID
654 AliHFEpidObject hfetrack;
655 hfetrack.fAnalysisType = AliHFEpidObject::kESDanalysis;
656 hfetrack.fRecTrack = track;
657 if(HasMCData()) hfetrack.fMCtrack = mctrack;
658 if(!fPID->IsSelected(&hfetrack)) continue;
659 nElectronCandidates++;
661 if (HasMCData() && IsQAOn(kMCqa)) {
662 // mc qa for after the reconstruction and pid cuts
663 AliDebug(2, "Running MC QA");
664 fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kCharm, AliHFEmcQA::kElectronPDG, 4); // charm
665 fMCQA->GetDecayedKine(mctrack4QA, AliHFEmcQA::kBeauty, AliHFEmcQA::kElectronPDG, 4); // beauty
670 fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
671 fCFM->GetParticleContainer()->Fill(&container[4], AliHFEcuts::kStepPID);
673 fCFM->GetParticleContainer()->Fill(&container[4], (AliHFEcuts::kStepPID + (AliHFEcuts::kNcutStepsESDtrack)));
675 // dimensions 3&4&5 : pt,eta,phi (MC)
676 ((THnSparseF *)fCorrelation->At(1))->Fill(container);
679 if(GetPlugin(kSecVtx) && fMCEvent->Stack()) {
680 AliDebug(2, "Running Secondary Vertex Analysis");
682 fSecVtx->InitHFEpairs();
683 fSecVtx->InitHFEsecvtxs();
684 AliESDtrack *htrack = 0x0;
685 for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
686 htrack = fESD->GetTrack(jtrack);
687 if ( itrack == jtrack ) continue; // since it is for tagging single electron, don't need additional condition
688 if (htrack->Pt()<1.0) continue;
689 if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC, htrack)) continue;
690 if (!fCFM->CheckParticleCuts(AliHFEcuts::kStepRecPrim, htrack)) continue;
691 fSecVtx->PairAnalysis(track, htrack, jtrack); // e-h pairing
693 /*for(int ip=0; ip<fSecVtx->HFEpairs()->GetEntriesFast(); ip++){
695 AliHFEpairs *pair = (AliHFEpairs*) (fSecVtx->HFEpairs()->UncheckedAt(ip));
696 if(!(pair->GetPairCode()>1. && pair->GetPairCode()<4.)) // apply various cuts
697 fSecVtx->HFEpairs()->RemoveAt(ip);
700 fSecVtx->HFEpairs()->Compress();
701 fSecVtx->RunSECVTX(track); // secondary vertexing with e,h1,h2,.. tracks
702 for(int ip=0; ip<fSecVtx->HFEsecvtxs()->GetEntriesFast(); ip++){
703 AliHFEsecVtxs *secvtx=0x0;
704 secvtx = (AliHFEsecVtxs*) (fSecVtx->HFEsecvtxs()->UncheckedAt(ip));
705 // here you apply cuts, then if it doesn't pass the cut, remove it from the fSecVtx->HFEsecvtxs()
707 fSecVtx->DeleteHFEpairs();
708 fSecVtx->DeleteHFEsecvtxs();
713 // Track selected: distinguish between true and fake
714 AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->Particle()->GetPdgCode()));
715 if((pid = TMath::Abs(mctrack->Particle()->GetPdgCode())) == 11){
716 Int_t type = IsSignalElectron(track);
717 AliDebug(1, Form("Type: %d\n", type));
719 dataE[5] = type; // beauty[1] or charm[2]
720 dataE[4] = 2; // signal electron
723 dataE[4] = 1; // not a signal electron
728 // Fill THnSparse with the information for Fake Electrons
732 // fill the performance THnSparse, if the mc origin could be defined
734 AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
735 fPIDperformance->Fill(dataE);
738 // Electron background analysis
739 if (GetPlugin(kIsElecBackGround)) {
741 AliDebug(2, "Running BackGround Analysis");
743 for(Int_t jtrack = 0; jtrack < fESD->GetNumberOfTracks(); jtrack++){
744 htrack = fESD->GetTrack(jtrack);
745 if ( itrack == jtrack ) continue;
746 fElecBackGround->PairAnalysis(track, htrack);
748 } // end of electron background analysis
752 //fQAcoll->Fill("fNevents", 1);
753 fNElectronTracksEvent->Fill(nElectronCandidates);
756 //____________________________________________________________
757 void AliAnalysisTaskHFE::ProcessAOD(){
759 // Run Analysis in AOD Mode
760 // Function is still in development
762 AliDebug(3, "Processing AOD Event");
763 Double_t nContrib = fInputEvent->GetPrimaryVertex()->GetNContributors();
764 if(!fCFM->CheckEventCuts(AliHFEcuts::kEventStepReconstructed, fInputEvent)) return;
765 fCFM->GetEventContainer()->Fill(&nContrib,AliHFEcuts::kEventStepReconstructed);
766 AliAODEvent *fAOD = dynamic_cast<AliAODEvent *>(fInputEvent);
768 AliError("AOD Event required for AOD Analysis")
772 AliAODTrack *track = NULL;
773 AliAODMCParticle *mctrack = NULL;
774 Double_t container[8]; memset(container, 0, sizeof(Double_t) * 8);
775 Double_t dataE[6]; // [pT, eta, Phi, Charge, type, 'C' or 'B']
776 Int_t nElectronCandidates = 0;
778 for(Int_t itrack = 0; itrack < fAOD->GetNumberOfTracks(); itrack++){
779 track = fAOD->GetTrack(itrack);
781 if(track->GetFlags() != 1<<4) continue; // Only process AOD tracks where the HFE is set
783 container[0] = track->Pt();
784 container[1] = track->Eta();
785 container[2] = track->Phi();
786 container[3] = track->Charge();
788 dataE[0] = track->Pt();
789 dataE[1] = track->Eta();
790 dataE[2] = track->Phi();
791 dataE[3] = track->Charge();
796 Int_t label = TMath::Abs(track->GetLabel());
798 mctrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(label));
799 container[4] = mctrack->Pt();
800 container[5] = mctrack->Eta();
801 container[6] = mctrack->Phi();
802 container[7] = mctrack->Charge();
805 // track accepted, do PID
806 AliHFEpidObject hfetrack;
807 hfetrack.fAnalysisType = AliHFEpidObject::kAODanalysis;
808 hfetrack.fRecTrack = track;
809 if(HasMCData()) hfetrack.fMCtrack = mctrack;
810 //if(!fPID->IsSelected(&hfetrack)) continue; // we will do PID here as soon as possible
811 // Particle identified - Fill CF Container
812 fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepPID + 2*AliHFEcuts::kNcutStepsESDtrack);
813 nElectronCandidates++;
815 // Track selected: distinguish between true and fake
816 AliDebug(1, Form("Candidate Selected, filling THnSparse, PID: %d\n", mctrack->GetPdgCode()));
817 if((pid = TMath::Abs(mctrack->GetPdgCode())) == 11){
818 Int_t type = IsSignalElectron(track);
819 AliDebug(1, Form("Type: %d\n", type));
821 dataE[5] = type; // beauty[1] or charm[2]
822 dataE[4] = 2; // signal electron
825 dataE[4] = 1; // not a signal electron
830 // Fill THnSparse with the information for Fake Electrons
834 // fill the performance THnSparse, if the mc origin could be defined
836 AliDebug(1, Form("Entries: [%.3f|%.3f|%.3f|%f|%f|%f]\n", dataE[0],dataE[1],dataE[2],dataE[3],dataE[4],dataE[5]));
837 fPIDperformance->Fill(dataE);
842 fNElectronTracksEvent->Fill(nElectronCandidates);
845 //____________________________________________________________
846 Bool_t AliAnalysisTaskHFE::ProcessMCtrack(AliVParticle *track){
848 // Filter the Monte Carlo Track
849 // Additionally Fill a THnSparse for Signal To Background Studies
850 // Works for AOD and MC analysis Type
852 Double_t container[4], signalContainer[6];
853 Double_t vertex[3]; // Production vertex cut to mask gammas which are NOT supposed to have hits in the first ITS layer(s)
855 AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(track);
856 container[0] = mctrack->Pt();
857 container[1] = mctrack->Eta();
858 container[2] = mctrack->Phi();
859 container[3] = mctrack->Charge()/3;
861 signalContainer[0] = mctrack->Pt();
862 signalContainer[1] = mctrack->Eta();
863 signalContainer[2] = mctrack->Phi();
864 signalContainer[3] = mctrack->Charge()/3;
866 vertex[0] = mctrack->Particle()->Vx();
867 vertex[1] = mctrack->Particle()->Vy();
869 AliAODMCParticle *aodmctrack = dynamic_cast<AliAODMCParticle *>(track);
870 container[0] = aodmctrack->Pt();
871 container[1] = aodmctrack->Eta();
872 container[2] = aodmctrack->Phi();
873 container[3] = aodmctrack->Charge()/3;
875 signalContainer[0] = aodmctrack->Pt();
876 signalContainer[1] = aodmctrack->Eta();
877 signalContainer[2] = aodmctrack->Phi();
878 signalContainer[3] = aodmctrack->Charge()/3;
880 aodmctrack->XvYvZv(vertex);
882 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCGenerated, track)) return kFALSE;
883 TH1 *test = dynamic_cast<TH1I*>(fQA->FindObject("mccharge"));
884 test->Fill(signalContainer[3]);
885 fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCGenerated);
886 if((signalContainer[4] = static_cast<Double_t >(IsSignalElectron(track))) > 1e-3) fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCsignal);
887 signalContainer[5] = 0;
888 // apply cut on the sqrt of the production vertex
889 Double_t radVertex = TMath::Sqrt(vertex[0]*vertex[0] + vertex[1] * vertex[1]);
891 // Within first ITS layer(2) -> Background we cannot reject by ITS cut, let it pass
892 signalContainer[5] = 1;
893 } else if (radVertex < 7.5){
894 signalContainer[5] = 2;
896 fSignalToBackgroundMC->Fill(signalContainer);
897 (dynamic_cast<TH1F *>(fQA->At(2)))->Fill(container[2] - TMath::Pi());
898 //if(IsESDanalysis()){
899 if(!fCFM->CheckParticleCuts(AliHFEcuts::kStepMCInAcceptance, track)) return kFALSE;
900 fCFM->GetParticleContainer()->Fill(container, AliHFEcuts::kStepMCInAcceptance);
905 //____________________________________________________________
906 void AliAnalysisTaskHFE::MakeEventContainer(){
908 // Create the event container for the correction framework and link it
910 const Int_t kNvar = 1; // number of variables on the grid: number of tracks per event
911 const Double_t kNTrackBound[2] = {-0.5, 200.5};
912 const Int_t kNBins = 201;
914 AliCFContainer *evCont = new AliCFContainer("eventContainer", "Container for events", AliHFEcuts::kNcutStepsEvent, kNvar, &kNBins);
916 Double_t *trackBins = AliHFEtools::MakeLinearBinning(kNBins, kNTrackBound[0], kNTrackBound[1]);
917 evCont->SetBinLimits(0,trackBins);
920 fCFM->SetEventContainer(evCont);
923 //____________________________________________________________
924 void AliAnalysisTaskHFE::MakeParticleContainer(){
926 // Create the particle container for the correction framework manager and
929 const Int_t kNvar = 4 ; //number of variables on the grid:pt,eta, phi, charge
930 const Double_t kPtbound[2] = {0.1, 10.};
931 const Double_t kEtabound[2] = {-0.8, 0.8};
932 const Double_t kPhibound[2] = {0., 2. * TMath::Pi()};
934 //arrays for the number of bins in each dimension
936 iBin[0] = 40; // bins in pt
937 iBin[1] = 8; // bins in eta
938 iBin[2] = 18; // bins in phi
939 iBin[3] = 2; // bins in charge
941 //arrays for lower bounds :
942 Double_t* binEdges[kNvar];
943 binEdges[0] = AliHFEtools::MakeLogarithmicBinning(iBin[0], kPtbound[0], kPtbound[1]);
944 binEdges[1] = AliHFEtools::MakeLinearBinning(iBin[1], kEtabound[0], kEtabound[1]);
945 binEdges[2] = AliHFEtools::MakeLinearBinning(iBin[2], kPhibound[0], kPhibound[1]);
946 binEdges[3] = AliHFEtools::MakeLinearBinning(iBin[3], -1.1, 1.1); // Numeric precision
948 //one "container" for MC
949 AliCFContainer* container = new AliCFContainer("trackContainer", "Container for tracks", (AliHFEcuts::kNcutStepsTrack + 2*AliHFEcuts::kNcutStepsESDtrack), kNvar, iBin);
951 //setting the bin limits
952 for(Int_t ivar = 0; ivar < kNvar; ivar++)
953 container -> SetBinLimits(ivar, binEdges[ivar]);
954 fCFM->SetParticleContainer(container);
956 //create correlation matrix for unfolding
957 Int_t thnDim[2*kNvar];
958 for (int k=0; k<kNvar; k++) {
959 //first half : reconstructed
962 thnDim[k+kNvar] = iBin[k];
965 if(!fCorrelation) fCorrelation = new TList();
966 fCorrelation->SetName("correlation");
968 THnSparseF *correlation0 = new THnSparseF("correlationstepbeforePID","THnSparse with correlations",2*kNvar,thnDim);
969 THnSparseF *correlation1 = new THnSparseF("correlationstepafterPID","THnSparse with correlations",2*kNvar,thnDim);
970 for (int k=0; k<kNvar; k++) {
971 correlation0->SetBinEdges(k,binEdges[k]);
972 correlation0->SetBinEdges(k+kNvar,binEdges[k]);
973 correlation1->SetBinEdges(k,binEdges[k]);
974 correlation1->SetBinEdges(k+kNvar,binEdges[k]);
976 correlation0->Sumw2();
977 correlation1->Sumw2();
979 fCorrelation->AddAt(correlation0,0);
980 fCorrelation->AddAt(correlation1,1);
982 // Add a histogram for Fake electrons
984 Int_t nBin[nDim] = {40, 8, 18, 2, 3, 3};
985 Double_t* binEdges2[nDim];
987 //values for bin lower bounds
988 for(Int_t ivar = 0; ivar < kNvar; ivar++)
989 binEdges2[ivar] = binEdges[ivar];
990 binEdges2[4] = AliHFEtools::MakeLinearBinning(nBin[4], 0, nBin[4]);
991 binEdges2[5] = AliHFEtools::MakeLinearBinning(nBin[5], 0, nBin[5]);
993 fPIDperformance = new THnSparseF("PIDperformance", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; type (0 - not el, 1 - other el, 2 - HF el; flavor (0 - no, 1 - charm, 2 - bottom)", nDim, nBin);
994 fPIDperformance->Sumw2();
995 fSignalToBackgroundMC = new THnSparseF("SignalToBackgroundMC", "PID performance; pT [GeV/c]; theta [rad]; phi [rad]; charge; flavor (0 - no, 1 - charm, 2 - bottom); ITS Cluster (0 - no, 1 - first (and maybe second), 2 - second)", nDim, nBin);
996 fSignalToBackgroundMC->Sumw2();
997 for(Int_t idim = 0; idim < nDim; idim++){
998 fPIDperformance->SetBinEdges(idim, binEdges2[idim]);
999 fSignalToBackgroundMC->SetBinEdges(idim, binEdges2[idim]);
1001 for(Int_t ivar = 0; ivar < kNvar; ivar++)
1002 delete binEdges[ivar];
1003 for(Int_t ivar = kNvar; ivar < nDim; ivar++)
1004 delete binEdges2[ivar];
1007 //____________________________________________________________
1008 void AliAnalysisTaskHFE::AddPIDdetector(TString detector){
1010 // Adding PID detector to the task
1012 if(!fPIDdetectors.Length())
1013 fPIDdetectors = detector;
1015 fPIDdetectors += ":" + detector;
1018 //____________________________________________________________
1019 void AliAnalysisTaskHFE::PrintStatus() const {
1021 // Print Analysis status
1023 printf("\n\tAnalysis Settings\n\t========================================\n\n");
1024 printf("\tSecondary Vertex finding: %s\n", GetPlugin(kSecVtx) ? "YES" : "NO");
1025 printf("\tPrimary Vertex resolution: %s\n", GetPlugin(kPriVtx) ? "YES" : "NO");
1027 printf("\tParticle Identification Detectors:\n");
1028 TObjArray *detectors = fPIDdetectors.Tokenize(":");
1029 for(Int_t idet = 0; idet < detectors->GetEntries(); idet++)
1030 printf("\t\t%s\n", (dynamic_cast<TObjString *>(detectors->At(idet)))->String().Data());
1033 printf("\t\tPID: %s\n", IsQAOn(kPIDqa) ? "YES" : "NO");
1034 printf("\t\tCUTS: %s\n", (fCuts != NULL && fCuts->IsInDebugMode()) ? "YES" : "NO");
1035 printf("\t\tMC: %s\n", IsQAOn(kMCqa) ? "YES" : "NO");
1039 //____________________________________________________________
1040 AliAnalysisTaskHFE::LabelContainer::LabelContainer(Int_t capacity):
1048 // Default constructor
1050 fContainer = new Int_t[capacity];
1051 fBegin = &fContainer[0];
1052 fEnd = &fContainer[capacity - 1];
1053 fLast = fCurrent = fBegin;
1056 //____________________________________________________________
1057 Bool_t AliAnalysisTaskHFE::LabelContainer::Append(Int_t label){
1059 // Add Label to the container
1061 if(fLast > fEnd) return kFALSE;
1066 //____________________________________________________________
1067 Bool_t AliAnalysisTaskHFE::LabelContainer::Find(Int_t label) const {
1069 // Find track in the list of labels
1071 for(Int_t *entry = fBegin; entry <= fLast; entry++)
1072 if(*entry == label) return kTRUE;
1076 //____________________________________________________________
1077 Int_t AliAnalysisTaskHFE::LabelContainer::Next(){
1081 if(fCurrent > fLast) return -1;
1085 //____________________________________________________________
1086 Int_t AliAnalysisTaskHFE::IsSignalElectron(AliVParticle *fTrack) const{
1088 // Checks whether the identified electron track is coming from heavy flavour
1089 // returns 0 in case of no signal, 1 in case of charm and 2 in case of Bottom
1096 TString objname = fTrack->IsA()->GetName();
1098 if(IsESDanalysis()){
1100 AliMCParticle *mctrack = NULL;
1101 if(!objname.CompareTo("AliESDtrack")){
1102 AliDebug(2, "Checking signal for ESD track");
1103 AliESDtrack *esdtrack = dynamic_cast<AliESDtrack *>(fTrack);
1104 mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(esdtrack->GetLabel())));
1106 else if(!objname.CompareTo("AliMCParticle")){
1107 AliDebug(2, "Checking signal for MC track");
1108 mctrack = dynamic_cast<AliMCParticle *>(fTrack);
1111 AliError("Input object not supported");
1114 if(!mctrack) return kNoSignal;
1115 TParticle *ecand = mctrack->Particle();
1116 if(TMath::Abs(ecand->GetPdgCode()) != 11) return kNoSignal; // electron candidate not true electron
1117 Int_t motherLabel = TMath::Abs(ecand->GetFirstMother());
1118 AliDebug(3, Form("mother label: %d\n", motherLabel));
1119 if(!motherLabel) return kNoSignal; // mother track unknown
1120 AliMCParticle *motherTrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(motherLabel));
1121 if(!motherTrack) return kNoSignal;
1122 TParticle *mparticle = motherTrack->Particle();
1123 pid = TMath::Abs(mparticle->GetPdgCode());
1125 // AOD Analysis - Different Data handling
1126 AliAODMCParticle *aodmc = NULL;
1127 if(!objname.CompareTo("AliAODTrack")){
1128 AliAODTrack *aodtrack = dynamic_cast<AliAODTrack *>(fTrack);
1129 Int_t aodlabel = TMath::Abs(aodtrack->GetLabel());
1130 if(aodlabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal;
1131 aodmc = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(aodlabel));
1132 } else if(!objname.CompareTo("AliAODMCParticle")){
1133 aodmc = dynamic_cast<AliAODMCParticle *>(fTrack);
1135 AliError("Input object not supported");
1138 if(!aodmc) return kNoSignal;
1139 Int_t motherLabel = TMath::Abs(aodmc->GetMother());
1140 AliDebug(3, Form("mother label: %d\n", motherLabel));
1141 if(!motherLabel || motherLabel >= fMCEvent->GetNumberOfTracks()) return kNoSignal;
1142 AliAODMCParticle *aodmother = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(motherLabel));
1143 pid = aodmother->GetPdgCode();
1145 // From here the two analysis modes go together
1146 AliDebug(3, Form("PDG code: %d\n", pid));
1148 // identify signal according to Pdg Code
1149 if((pid % 1000) / 100 == 4) return kCharm; // charmed meson, 3rd position in pdg code == 4
1150 if(pid / 1000 == 4) return kCharm; // charmed baryon, 4th position in pdg code == 4
1151 if((pid % 1000) / 100 == 5) return kBeauty; // beauty meson, 3rd position in pdg code == 5
1152 if(pid / 1000 == 5) return kBeauty; // beauty baryon, 4th position in pdg code == 5
1156 //__________________________________________
1157 void AliAnalysisTaskHFE::SwitchOnPlugin(Int_t plug){
1161 // - Primary vertex studies
1162 // - Secondary vertex Studies
1163 // - Post Processing
1166 case kPriVtx: SETBIT(fPlugins, plug); break;
1167 case kSecVtx: SETBIT(fPlugins, plug); break;
1168 case kIsElecBackGround: SETBIT(fPlugins, plug); break;
1169 case kPostProcess: SETBIT(fPlugins, plug); break;
1170 default: AliError("Unknown Plugin");
1174 //__________________________________________
1175 Bool_t AliAnalysisTaskHFE::ProcessCutStep(Int_t cutStep, AliVParticle *track, Double_t *container, Bool_t signal, Bool_t alreadyseen){
1177 // Check single track cuts for a given cut step
1178 // Fill the particle container
1180 if(!fCFM->CheckParticleCuts(cutStep, track)) return kFALSE;
1182 fCFM->GetParticleContainer()->Fill(container, cutStep + 2*AliHFEcuts::kNcutStepsESDtrack);
1183 fCFM->GetParticleContainer()->Fill(&container[4], cutStep);
1185 fCFM->GetParticleContainer()->Fill(&container[4], cutStep + AliHFEcuts::kNcutStepsESDtrack);
1191 //__________________________________________
1192 void AliAnalysisTaskHFE::SetTPCBetheBlochParameters(Double_t *pars){
1194 // Set Bethe-Bloch Parameters for TPC PID
1196 fPID->SetTPCBetheBlochParameters(pars);