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 **************************************************************************/
16 // Class for heavy-flavour electron v2 with EMCal triggered events
17 // Author: Denise Godoy
25 #include "THnSparse.h"
26 #include "TLorentzVector.h"
30 #include "AliAnalysisTask.h"
31 #include "AliAnalysisManager.h"
33 #include "AliESDEvent.h"
34 #include "AliESDHandler.h"
35 #include "AliAODEvent.h"
36 #include "AliAODHandler.h"
38 #include "AliAnalysisTaskElecV2.h"
39 #include "TGeoGlobalMagField.h"
41 #include "AliAnalysisTaskSE.h"
42 #include "TRefArray.h"
44 #include "AliESDInputHandler.h"
45 #include "AliESDpid.h"
46 #include "AliESDtrackCuts.h"
47 #include "AliPhysicsSelection.h"
48 #include "AliESDCaloCluster.h"
49 #include "AliAODCaloCluster.h"
50 #include "AliEMCALRecoUtils.h"
51 #include "AliEMCALGeometry.h"
52 #include "AliGeomManager.h"
54 #include "TGeoManager.h"
58 #include "AliEMCALTrack.h"
61 #include "AliKFParticle.h"
62 #include "AliKFVertex.h"
65 #include "AliPIDResponse.h"
66 #include "AliHFEcontainer.h"
67 #include "AliHFEcuts.h"
68 #include "AliHFEpid.h"
69 #include "AliHFEpidBase.h"
70 #include "AliHFEpidQAmanager.h"
71 #include "AliHFEtools.h"
72 #include "AliCFContainer.h"
73 #include "AliCFManager.h"
75 #include "AliEventplane.h"
76 #include "AliCentrality.h"
78 ClassImp(AliAnalysisTaskElecV2)
79 //________________________________________________________________________
80 AliAnalysisTaskElecV2::AliAnalysisTaskElecV2(const char *name)
81 : AliAnalysisTaskSE(name)
86 ,fIdentifiedAsOutInz(kFALSE)
87 ,fPassTheEventCut(kFALSE)
88 ,fRejectKinkMother(kFALSE)
93 ,fOpeningAngleCut(0.1)
107 ,fTrackPtBefTrkCuts(0)
108 ,fTrackPtAftTrkCuts(0)
121 fPID = new AliHFEpid("hfePid");
122 fTrackCuts = new AliESDtrackCuts();
124 // Define input and output slots here
125 // Input slot #0 works with a TChain
126 DefineInput(0, TChain::Class());
127 // Output slot #0 id reserved by the base class for AOD
128 // Output slot #1 writes into a TH1 container
129 // DefineOutput(1, TH1I::Class());
130 DefineOutput(1, TList::Class());
131 // DefineOutput(3, TTree::Class());
134 //________________________________________________________________________
135 AliAnalysisTaskElecV2::AliAnalysisTaskElecV2()
136 : AliAnalysisTaskSE("DefaultAnalysis_AliAnalysisElecHadCorrel")
141 ,fIdentifiedAsOutInz(kFALSE)
142 ,fPassTheEventCut(kFALSE)
143 ,fRejectKinkMother(kFALSE)
148 ,fOpeningAngleCut(0.1)
162 ,fTrackPtBefTrkCuts(0)
163 ,fTrackPtAftTrkCuts(0)
174 //Default constructor
175 fPID = new AliHFEpid("hfePid");
177 fTrackCuts = new AliESDtrackCuts();
180 // Define input and output slots here
181 // Input slot #0 works with a TChain
182 DefineInput(0, TChain::Class());
183 // Output slot #0 id reserved by the base class for AOD
184 // Output slot #1 writes into a TH1 container
185 // DefineOutput(1, TH1I::Class());
186 DefineOutput(1, TList::Class());
187 //DefineOutput(3, TTree::Class());
189 //_________________________________________
191 AliAnalysisTaskElecV2::~AliAnalysisTaskElecV2()
201 //_________________________________________
203 void AliAnalysisTaskElecV2::UserExec(Option_t*)
206 //Called for each event
208 // create pointer to event
209 fESD = dynamic_cast<AliESDEvent*>(InputEvent());
211 printf("ERROR: fESD not available\n");
216 AliError("HFE cuts not available");
220 if(!fPID->IsInitialized()){
221 // Initialize PID with the given run number
222 AliWarning("PID not initialised, get from Run no");
223 fPID->InitializePID(fESD->GetRunNumber());
227 Int_t fNOtrks = fESD->GetNumberOfTracks();
228 const AliESDVertex *pVtx = fESD->GetPrimaryVertex();
230 Double_t pVtxZ = -999;
231 pVtxZ = pVtx->GetZ();
233 if(TMath::Abs(pVtxZ)>10) return;
236 if(fNOtrks<2) return;
238 AliPIDResponse *pidResponse = fInputHandler->GetPIDResponse();
240 AliDebug(1, "Using default PID Response");
241 pidResponse = AliHFEtools::GetDefaultPID(kFALSE, fInputEvent->IsA() == AliAODEvent::Class());
244 fPID->SetPIDResponse(pidResponse);
246 fCFM->SetRecEventInfo(fESD);
249 AliCentrality *centrality = fESD->GetCentrality();
250 cent = centrality->GetCentralityPercentile("V0M");
257 Double_t evPlaneV0A = TVector2::Phi_0_2pi(fESD->GetEventplane()->GetEventplane("V0A",fESD,2));
258 if(evPlaneV0A > TMath::Pi()) evPlaneV0A = evPlaneV0A - TMath::Pi();
260 Double_t evPlaneV0C = TVector2::Phi_0_2pi(fESD->GetEventplane()->GetEventplane("V0C",fESD,2));
261 if(evPlaneV0C > TMath::Pi()) evPlaneV0C = evPlaneV0C - TMath::Pi();
263 AliEventplane* esdTPCep = fESD->GetEventplane();
264 TVector2 *standardQ = esdTPCep->GetQVector();
265 Double_t qx = -999., qy = -999.;
271 TVector2 qVectorfortrack;
272 qVectorfortrack.Set(qx,qy);
273 Float_t evPlaneTPC = TVector2::Phi_0_2pi(qVectorfortrack.Phi())/2.;
275 TVector2 *qsub1a = esdTPCep->GetQsub1();
276 TVector2 *qsub2a = esdTPCep->GetQsub2();
277 Double_t evPlaneResTPC = -999.;
280 evPlaneResTPC = TMath::Cos(2.*TVector2::Phi_0_2pi(qsub1a->Phi()/2.- qsub2a->Phi()/2.));
283 fTPCsubEPres->Fill(evPlaneResTPC,cent);
285 Double_t evPlaneRes[4]={GetCos2DeltaPhi(evPlaneV0A,evPlaneV0C),GetCos2DeltaPhi(evPlaneV0A,evPlaneTPC),GetCos2DeltaPhi(evPlaneV0C,evPlaneTPC),cent};
286 fEPres->Fill(evPlaneRes);
289 for (Int_t iTracks = 0; iTracks < fESD->GetNumberOfTracks(); iTracks++) {
290 AliESDtrack* track = fESD->GetTrack(iTracks);
292 printf("ERROR: Could not receive track %d\n", iTracks);
296 if(TMath::Abs(track->Eta())>0.7) continue;
298 fTrackPtBefTrkCuts->Fill(track->Pt());
299 // RecKine: ITSTPC cuts
300 if(!ProcessCutStep(AliHFEcuts::kStepRecKineITSTPC, track)) continue;
303 if(fRejectKinkMother) { // Quick and dirty fix to reject both kink mothers and daughters
304 if(track->GetKinkIndex(0) != 0) continue;
308 if(!ProcessCutStep(AliHFEcuts::kStepRecPrim, track)) continue;
310 // HFEcuts: ITS layers cuts
311 if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsITS, track)) continue;
313 // HFE cuts: TPC PID cleanup
314 if(!ProcessCutStep(AliHFEcuts::kStepHFEcutsTPC, track)) continue;
316 fTrackPtAftTrkCuts->Fill(track->Pt());
318 Double_t clsE = -999., p = -999., EovP=-999., pt = -999., dEdx=-999., fTPCnSigma=0, phi=-999.;
320 // Track extrapolation
325 Int_t clsId = track->GetEMCALcluster();
327 AliESDCaloCluster *cluster = fESD->GetCaloCluster(clsId);
328 if(cluster && cluster->IsEMCAL()){
335 dEdx = track->GetTPCsignal();
337 fTPCnSigma = fPID->GetPIDResponse() ? fPID->GetPIDResponse()->NumberOfSigmasTPC(track, AliPID::kElectron) : 1000;
338 fdEdxBef->Fill(p,dEdx);
339 fTPCnsigma->Fill(p,fTPCnSigma);
341 Double_t corr[7]={fTPCnSigma,cent,pt,EovP,GetDeltaPhi(phi,evPlaneTPC),GetDeltaPhi(phi,evPlaneV0A),GetDeltaPhi(phi,evPlaneV0C)};
344 if(fTPCnSigma >= 1.5 && fTPCnSigma <= 3)fTrkEovPBef->Fill(pt,EovP);
348 AliHFEpidObject hfetrack;
349 hfetrack.SetAnalysisType(AliHFEpidObject::kESDanalysis);
350 hfetrack.SetRecTrack(track);
352 if(!fPID->IsSelected(&hfetrack, NULL, "", fPIDqa)) pidpassed = 0;
354 Double_t corrV2[6]={cent,pt,EovP,GetCos2DeltaPhi(phi,evPlaneTPC),GetCos2DeltaPhi(phi,evPlaneV0A),GetCos2DeltaPhi(phi,evPlaneV0C)};
355 fChargPartV2->Fill(corrV2);
357 if(fTPCnSigma >= -0.5){
358 Double_t qX = standardQ->X() - esdTPCep->GetQContributionX(track);
359 Double_t qY = standardQ->Y() - esdTPCep->GetQContributionY(track);
360 TVector2 newQVectorfortrack;
361 newQVectorfortrack.Set(qX,qY);
362 Double_t corrV2TPC = -999.;
363 corrV2TPC = TVector2::Phi_0_2pi(newQVectorfortrack.Phi())/2;
365 Double_t correctedV2[5]={cent,pt,GetCos2DeltaPhi(phi,corrV2TPC),GetCos2DeltaPhi(phi,evPlaneV0A),GetCos2DeltaPhi(phi,evPlaneV0C)};
367 feTPCV2->Fill(correctedV2);
370 if(pidpassed==0) continue;
372 Double_t qX = standardQ->X() - esdTPCep->GetQContributionX(track);
373 Double_t qY = standardQ->Y() - esdTPCep->GetQContributionY(track);
374 TVector2 newQVectorfortrack;
375 newQVectorfortrack.Set(qX,qY);
376 Double_t corrV2TPC = -999.;
377 corrV2TPC = TVector2::Phi_0_2pi(newQVectorfortrack.Phi())/2;
379 Double_t correctedV2[5]={cent,pt,GetCos2DeltaPhi(phi,corrV2TPC),GetCos2DeltaPhi(phi,evPlaneV0A),GetCos2DeltaPhi(phi,evPlaneV0C)};
381 feV2->Fill(correctedV2);
383 fTrkEovPAft->Fill(pt,EovP);
384 fdEdxAft->Fill(p,dEdx);
386 Bool_t fFlagPhotonicElec = kFALSE;
387 SelectPhotonicElectron(iTracks,track,fFlagPhotonicElec);
389 if(fFlagPhotonicElec){
390 fphoteV2->Fill(correctedV2);
391 fPhotoElecPt->Fill(pt);
394 if(!fFlagPhotonicElec) fSemiInclElecPt->Fill(pt);
396 PostData(1, fOutputList);
398 //_________________________________________
399 void AliAnalysisTaskElecV2::UserCreateOutputObjects()
401 //--------Initialize PID
402 fPID->SetHasMCData(kFALSE);
403 if(!fPID->GetNumberOfPIDdetectors())
405 fPID->AddDetector("TPC", 0);
406 fPID->AddDetector("EMCAL", 1);
409 fPID->SortDetectors();
410 fPIDqa = new AliHFEpidQAmanager();
411 fPIDqa->Initialize(fPID);
413 //--------Initialize correction Framework and Cuts
414 fCFM = new AliCFManager;
415 const Int_t kNcutSteps = AliHFEcuts::kNcutStepsMCTrack + AliHFEcuts::kNcutStepsRecTrack + AliHFEcuts::kNcutStepsDETrack;
416 fCFM->SetNStepParticle(kNcutSteps);
417 for(Int_t istep = 0; istep < kNcutSteps; istep++)
418 fCFM->SetParticleCutsList(istep, NULL);
421 AliWarning("Cuts not available. Default cuts will be used");
422 fCuts = new AliHFEcuts;
423 fCuts->CreateStandardCuts();
425 fCuts->Initialize(fCFM);
427 //---------Output Tlist
428 fOutputList = new TList();
429 fOutputList->SetOwner();
430 fOutputList->Add(fPIDqa->MakeList("PIDQA"));
432 fNoEvents = new TH1F("fNoEvents","",1,0,1) ;
433 fOutputList->Add(fNoEvents);
435 fTrkpt = new TH1F("fTrkpt","track pt",100,0,50);
436 fOutputList->Add(fTrkpt);
438 fTrackPtBefTrkCuts = new TH1F("fTrackPtBefTrkCuts","track pt before track cuts",100,0,50);
439 fOutputList->Add(fTrackPtBefTrkCuts);
441 fTrackPtAftTrkCuts = new TH1F("fTrackPtAftTrkCuts","track pt after track cuts",100,0,50);
442 fOutputList->Add(fTrackPtAftTrkCuts);
444 fTPCnsigma = new TH2F("fTPCnsigma", "TPC - n sigma",100,0,50,200,-10,10);
445 fOutputList->Add(fTPCnsigma);
447 fTrkEovPBef = new TH2F("fTrkEovPBef","track E/p before HFE pid",100,0,50,100,0,2);
448 fOutputList->Add(fTrkEovPBef);
450 fTrkEovPAft = new TH2F("fTrkEovPAft","track E/p after HFE pid",100,0,50,100,0,2);
451 fOutputList->Add(fTrkEovPAft);
453 fdEdxBef = new TH2F("fdEdxBef","track dEdx vs p before HFE pid",100,0,50,150,0,150);
454 fOutputList->Add(fdEdxBef);
456 fdEdxAft = new TH2F("fdEdxAft","track dEdx vs p after HFE pid",100,0,50,150,0,150);
457 fOutputList->Add(fdEdxAft);
459 fInvmassLS = new TH1F("fInvmassLS", "Inv mass of LS (e,e); mass(GeV/c^2); counts;", 500,0,0.5);
460 fOutputList->Add(fInvmassLS);
462 fInvmassULS = new TH1F("fInvmassULS", "Inv mass of ULS (e,e); mass(GeV/c^2); counts;", 500,0,0.5);
463 fOutputList->Add(fInvmassULS);
465 fOpeningAngleLS = new TH1F("fOpeningAngleLS","Opening angle for LS pairs",100,0,1);
466 fOutputList->Add(fOpeningAngleLS);
468 fOpeningAngleULS = new TH1F("fOpeningAngleULS","Opening angle for ULS pairs",100,0,1);
469 fOutputList->Add(fOpeningAngleULS);
471 fPhotoElecPt = new TH1F("fPhotoElecPt", "photonic electron pt",100,0,50);
472 fOutputList->Add(fPhotoElecPt);
474 fSemiInclElecPt = new TH1F("fSemiInclElecPt", "Semi-inclusive electron pt",100,0,50);
475 fOutputList->Add(fSemiInclElecPt);
477 fCent = new TH1F("fCent","Centrality",100,0,100) ;
478 fOutputList->Add(fCent);
480 fTPCsubEPres = new TH2F("fTPCsubEPres","TPC subevent plane resolution",100,-1,1,90,0,90);
481 fOutputList->Add(fTPCsubEPres);
483 Int_t binsv1[4]={100,100,100,90}; // V0A-V0C, V0A-TPC, V0C-TPC, cent
484 Double_t xminv1[4]={-1,-1,-1,0};
485 Double_t xmaxv1[4]={1,1,1,90};
486 fEPres = new THnSparseD ("fEPres","EP resolution",4,binsv1,xminv1,xmaxv1);
487 fOutputList->Add(fEPres);
489 Int_t binsv2[7]={100,90,100,100,100,100,100}; // fTPCnSigma,cent, pt, EovP, TPCdeltaPhi, V0AdeltaPhi, V0CdeltaPhi
490 Double_t xminv2[7]={-3.5,0,0,0,0,0,0};
491 Double_t xmaxv2[7]={3.5,90,50,3,TMath::Pi(),TMath::Pi(),TMath::Pi()};
492 fCorr = new THnSparseD ("fCorr","Correlations",7,binsv2,xminv2,xmaxv2);
493 fOutputList->Add(fCorr);
495 Int_t binsv3[5]={90,100,100,100,100}; // cent, pt, TPCcos2DeltaPhi, V0Acos2DeltaPhi, V0Ccos2DeltaPhi
496 Double_t xminv3[5]={0,0,-1,-1,-1};
497 Double_t xmaxv3[5]={90,50,1,1,1};
498 feV2 = new THnSparseD ("feV2","inclusive electron v2",5,binsv3,xminv3,xmaxv3);
499 fOutputList->Add(feV2);
501 Int_t binsv4[5]={90,100,100,100,100}; // cent, pt, TPCdeltaPhi, V0AdeltaPhi, V0CdeltaPhi
502 Double_t xminv4[5]={0,0,-1,-1,-1};
503 Double_t xmaxv4[5]={90,50,1,1,1};
504 fphoteV2 = new THnSparseD ("fphoteV2","photonic electron v2",5,binsv4,xminv4,xmaxv4);
505 fOutputList->Add(fphoteV2);
507 Int_t binsv5[6]={90,100,100,100,100,100}; // cent, pt, EovP, TPCdeltaPhi, V0AdeltaPhi, V0CdeltaPhi
508 Double_t xminv5[6]={0,0,0,-1,-1,-1};
509 Double_t xmaxv5[6]={90,50,3,1,1,1};
510 fChargPartV2 = new THnSparseD ("fChargPartV2","Charged particle v2",6,binsv5,xminv5,xmaxv5);
511 fOutputList->Add(fChargPartV2);
513 Int_t binsv6[5]={90,100,100,100,100}; // cent, pt, TPCdeltaPhi, V0AdeltaPhi, V0CdeltaPhi
514 Double_t xminv6[5]={0,0,-1,-1,-1};
515 Double_t xmaxv6[5]={90,50,1,1,1};
516 feTPCV2 = new THnSparseD ("feTPCV2","inclusive electron v2 (TPC)",5,binsv6,xminv6,xmaxv6);
517 fOutputList->Add(feTPCV2);
519 PostData(1,fOutputList);
522 //________________________________________________________________________
523 void AliAnalysisTaskElecV2::Terminate(Option_t *)
525 // Info("Terminate");
526 AliAnalysisTaskSE::Terminate();
529 //________________________________________________________________________
530 Bool_t AliAnalysisTaskElecV2::ProcessCutStep(Int_t cutStep, AliVParticle *track)
532 // Check single track cuts for a given cut step
533 const Int_t kMCOffset = AliHFEcuts::kNcutStepsMCTrack;
534 if(!fCFM->CheckParticleCuts(cutStep + kMCOffset, track)) return kFALSE;
537 //_________________________________________
538 void AliAnalysisTaskElecV2::SelectPhotonicElectron(Int_t itrack, AliESDtrack *track, Bool_t &fFlagPhotonicElec)
540 //Identify non-heavy flavour electrons using Invariant mass method
542 fTrackCuts->SetAcceptKinkDaughters(kFALSE);
543 fTrackCuts->SetRequireTPCRefit(kTRUE);
544 fTrackCuts->SetEtaRange(-0.7,0.7);
545 fTrackCuts->SetRequireSigmaToVertex(kTRUE);
546 fTrackCuts->SetMaxChi2PerClusterTPC(3.5);
547 fTrackCuts->SetMinNClustersTPC(100);
549 const AliESDVertex *pVtx = fESD->GetPrimaryVertex();
551 Bool_t flagPhotonicElec = kFALSE;
553 for(Int_t jTracks = itrack+1; jTracks<fESD->GetNumberOfTracks(); jTracks++){
554 AliESDtrack* trackAsso = fESD->GetTrack(jTracks);
556 printf("ERROR: Could not receive track %d\n", jTracks);
560 Double_t dEdxAsso = -999., ptAsso=-999., openingAngle = -999.;
561 Double_t mass=999., width = -999;
562 Bool_t fFlagLS=kFALSE, fFlagULS=kFALSE;
564 dEdxAsso = trackAsso->GetTPCsignal();
565 ptAsso = trackAsso->Pt();
566 Int_t chargeAsso = trackAsso->Charge();
567 Int_t charge = track->Charge();
569 if(ptAsso <0.3) continue;
570 if(!fTrackCuts->AcceptTrack(trackAsso)) continue;
571 if(dEdxAsso <70 || dEdxAsso>100) continue; //11a pass1
573 Int_t fPDGe1 = 11; Int_t fPDGe2 = 11;
574 if(charge>0) fPDGe1 = -11;
575 if(chargeAsso>0) fPDGe2 = -11;
577 if(charge == chargeAsso) fFlagLS = kTRUE;
578 if(charge != chargeAsso) fFlagULS = kTRUE;
580 AliKFParticle ge1(*track, fPDGe1);
581 AliKFParticle ge2(*trackAsso, fPDGe2);
582 AliKFParticle recg(ge1, ge2);
584 if(recg.GetNDF()<1) continue;
585 Double_t chi2recg = recg.GetChi2()/recg.GetNDF();
586 if(TMath::Sqrt(TMath::Abs(chi2recg))>3.) continue;
588 AliKFVertex primV(*pVtx);
590 recg.SetProductionVertex(primV);
592 recg.SetMassConstraint(0,0.0001);
594 openingAngle = ge1.GetAngle(ge2);
595 if(fFlagLS) fOpeningAngleLS->Fill(openingAngle);
596 if(fFlagULS) fOpeningAngleULS->Fill(openingAngle);
598 if(openingAngle > fOpeningAngleCut) continue;
600 recg.GetMass(mass,width);
602 if(fFlagLS) fInvmassLS->Fill(mass);
603 if(fFlagULS) fInvmassULS->Fill(mass);
605 if(mass<fInvmassCut && fFlagULS && !flagPhotonicElec){
606 flagPhotonicElec = kTRUE;
610 fFlagPhotonicElec = flagPhotonicElec;
613 //_________________________________________
614 Double_t AliAnalysisTaskElecV2::GetCos2DeltaPhi(Double_t phiA,Double_t phiB) const
616 //Get cos[2(phi-psi_EP)] or cos[2(psi_subEP1 - psi_subEP2)]
617 Double_t dPhi = TVector2::Phi_0_2pi(phiA - phiB);
618 if(dPhi > TMath::Pi()) dPhi = dPhi - TMath::Pi();
619 Double_t cos2DeltaPhi = TMath::Cos(2*dPhi);
624 //_________________________________________
625 Double_t AliAnalysisTaskElecV2::GetDeltaPhi(Double_t phiA,Double_t phiB) const
628 Double_t dPhi = TVector2::Phi_0_2pi(phiA - phiB);
629 if(dPhi > TMath::Pi()) dPhi = dPhi - TMath::Pi();