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. *
15 *************************************************************************************/
17 /*************************************************************************************
19 * Class for the Selection of Non-Heavy-Flavour-Electrons trought *
20 * the invariant mass method. The selection can be done from two *
21 * different algorithms, which can be choosed calling the function *
22 * "SetAlgorithm(TString Algorithm)". *
24 * Authors: R.Bailhache, C.A.Schmidt *
26 *************************************************************************************/
29 #include "THnSparse.h"
31 #include "TLorentzVector.h"
32 #include "TParticle.h"
34 #include "TDatabasePDG.h"
36 #include "AliVEvent.h"
37 #include "AliMCEvent.h"
38 #include "AliESDEvent.h"
39 #include "AliMCParticle.h"
40 #include "AliAODMCParticle.h"
41 #include "AliAODEvent.h"
42 #include "AliAODVertex.h"
43 #include "AliAODTrack.h"
44 #include "AliVTrack.h"
45 #include "AliESDtrack.h"
46 #include "AliESDtrackCuts.h"
47 #include "AliPIDResponse.h"
50 #include "AliKFParticle.h"
51 #include "AliKFVertex.h"
53 #include "AliHFEcuts.h"
54 #include "AliHFEpid.h"
55 #include "AliHFEpidQAmanager.h"
56 #include "AliHFEtools.h"
58 #include "AliHFENonPhotonicElectron.h"
60 ClassImp(AliHFENonPhotonicElectron)
61 //________________________________________________________________________
62 AliHFENonPhotonicElectron::AliHFENonPhotonicElectron(const char *name, const Char_t *title)
66 ,fAODArrayMCInfo (NULL)
67 ,fHFEBackgroundCuts (NULL)
72 ,fChi2OverNDFCut (3.0)
74 // ,fMaxOpeningTheta (0.02)
75 // ,fMaxOpeningPhi (0.1)
76 ,fMaxOpening3D (TMath::Pi())
78 ,fSetMassConstraint (kFALSE)
79 ,fSelectCategory1tracks(kTRUE)
80 ,fSelectCategory2tracks(kFALSE)
83 ,fCounterPoolBackground (0)
93 // ,fUSignAngle (NULL)
94 // ,fLSignAngle (NULL)
99 fPIDBackground = new AliHFEpid("hfePidBackground");
100 fPIDBackgroundQA = new AliHFEpidQAmanager;
103 //________________________________________________________________________
104 AliHFENonPhotonicElectron::AliHFENonPhotonicElectron()
108 ,fAODArrayMCInfo (NULL)
109 ,fHFEBackgroundCuts (NULL)
110 ,fPIDBackground (0x0)
111 ,fPIDBackgroundQA (0)
113 ,fAlgorithmMA (kTRUE)
114 ,fChi2OverNDFCut (3.0)
116 // ,fMaxOpeningTheta (0.02)
117 // ,fMaxOpeningPhi (0.1)
118 ,fMaxOpening3D (TMath::TwoPi())
120 ,fSetMassConstraint (kFALSE)
121 ,fSelectCategory1tracks(kTRUE)
122 ,fSelectCategory2tracks(kFALSE)
125 ,fCounterPoolBackground (0)
135 // ,fUSignAngle (NULL)
136 // ,fLSignAngle (NULL)
141 fPIDBackground = new AliHFEpid("hfePidBackground");
142 fPIDBackgroundQA = new AliHFEpidQAmanager;
145 //________________________________________________________________________
146 AliHFENonPhotonicElectron::AliHFENonPhotonicElectron(const AliHFENonPhotonicElectron &ref)
150 ,fAODArrayMCInfo (NULL)
151 ,fHFEBackgroundCuts (ref.fHFEBackgroundCuts)
152 ,fPIDBackground (ref.fPIDBackground)
153 ,fPIDBackgroundQA (ref.fPIDBackgroundQA)
154 ,fkPIDRespons (ref.fkPIDRespons)
155 ,fAlgorithmMA (ref.fAlgorithmMA)
156 ,fChi2OverNDFCut (ref.fChi2OverNDFCut)
157 ,fMaxDCA (ref.fMaxDCA)
158 // ,fMaxOpeningTheta (ref.fMaxOpeningTheta)
159 // ,fMaxOpeningPhi (ref.fMaxOpeningPhi)
160 ,fMaxOpening3D (ref.fMaxOpening3D)
161 ,fMaxInvMass (ref.fMaxInvMass)
162 ,fSetMassConstraint (ref.fSetMassConstraint)
163 ,fSelectCategory1tracks(ref.fSelectCategory1tracks)
164 ,fSelectCategory2tracks(ref.fSelectCategory2tracks)
165 ,fITSmeanShift(ref.fITSmeanShift)
167 ,fCounterPoolBackground (0)
169 ,fListOutput (ref.fListOutput)
170 ,fAssElectron (ref.fAssElectron)
171 ,fIncElectron (ref.fIncElectron)
174 ,fUSmatches(ref.fUSmatches)
175 ,fLSmatches(ref.fLSmatches)
176 ,fHnsigmaITS(ref.fHnsigmaITS)
177 // ,fUSignAngle (ref.fUSignAngle)
178 // ,fLSignAngle (ref.fLSignAngle)
186 //____________________________________________________________
187 AliHFENonPhotonicElectron &AliHFENonPhotonicElectron::operator=(const AliHFENonPhotonicElectron &ref){
189 // Assignment operator
191 if(this == &ref) ref.Copy(*this);
195 //_________________________________________
196 AliHFENonPhotonicElectron::~AliHFENonPhotonicElectron()
201 if(fArraytrack) delete fArraytrack;
202 //if(fHFEBackgroundCuts) delete fHFEBackgroundCuts;
203 if(fPIDBackground) delete fPIDBackground;
204 if(fPIDBackgroundQA) delete fPIDBackgroundQA;
207 //_____________________________________________________________________________________________
208 void AliHFENonPhotonicElectron::Init()
214 //printf("Analysis Mode for AliHFENonPhotonicElectron: %s Analysis\n", fIsAOD ? "AOD" : "ESD");
216 if(!fListOutput) fListOutput = new TList;
217 fListOutput->SetName("HFENonPhotonicElectron");
218 fListOutput->SetOwner();
220 if(!fHFEBackgroundCuts) fHFEBackgroundCuts = new AliHFEcuts();
221 if(fIsAOD) fHFEBackgroundCuts->SetAOD();
222 fHFEBackgroundCuts->Initialize();
223 if(fHFEBackgroundCuts->IsQAOn()) {
224 fListOutput->Add(fHFEBackgroundCuts->GetQAhistograms());
228 if(!fPIDBackground) fPIDBackground = new AliHFEpid("default pid");
229 if(fMCEvent || fAODArrayMCInfo) fPIDBackground->SetHasMCData(kTRUE); // does nothing since the fMCEvent are set afterwards at the moment
230 if(!fPIDBackground->GetNumberOfPIDdetectors())
232 //fPIDBackground->AddDetector("TOF", 0);
233 fPIDBackground->AddDetector("TPC", 0);
235 AliInfo("PID Background QA switched on");
236 fPIDBackgroundQA->Initialize(fPIDBackground);
237 fListOutput->Add(fPIDBackgroundQA->MakeList("HFENP_PID_Background"));
238 fPIDBackground->SortDetectors();
241 //Double_t binLimPt[25] = {0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1., 1.1, 1.2, 1.3, 1.4, 1.5, 1.75, 2., 2.25, 2.5, 3., 3.5, 4., 5., 6.};
242 Double_t binLimPt[36] = {0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1., 1.1, 1.2, 1.3, 1.4, 1.5, 1.75, 2., 2.25, 2.5, 2.75, 3., 3.5, 4., 4.5, 5., 5.5, 6., 7., 8., 10., 12., 14., 16., 18., 20.};
243 const Int_t kBinsEtaInclusive = 8;
244 Double_t binLimEtaInclusive[kBinsEtaInclusive+1] = {-0.8, -0.6, -0.4, -0.2, 0., 0.2, 0.4, 0.6, 0.8};
245 const Int_t kBinsEtaAssociated = 30;
246 Double_t binLimEtaAssociat[kBinsEtaAssociated+1] = {-1.5, -1.4, -1.3, -1.2, -1.1, -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0., 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5};
248 //Int_t nBinsP = 400;
249 //Double_t minP = 0.0;
250 //Double_t maxP = 20.0;
251 //Double_t binLimP[nBinsP+1];
252 //for(Int_t i=0; i<=nBinsP; i++) binLimP[i]=(Double_t)minP + (maxP-minP)/nBinsP*(Double_t)i ;
256 Double_t maxC = 11.0;
257 Double_t binLimC[nBinsC+1];
258 for(Int_t i=0; i<=nBinsC; i++) binLimC[i]=(Double_t)minC + (maxC-minC)/nBinsC*(Double_t)i ;
260 Int_t nBinsSource = 10;
261 Double_t minSource = 0.;
262 Double_t maxSource = 10.;
263 Double_t binLimSource[nBinsSource+1];
264 for(Int_t i=0; i<=nBinsSource; i++) binLimSource[i]=(Double_t)minSource + (maxSource-minSource)/nBinsSource*(Double_t)i ;
266 Int_t nBinsInvMass = 100;
267 Double_t minInvMass = 0.;
268 Double_t maxInvMass = 1.;
269 Double_t binLimInvMass[nBinsInvMass+1];
270 for(Int_t i=0; i<=nBinsInvMass; i++) binLimInvMass[i]=(Double_t)minInvMass + (maxInvMass-minInvMass)/nBinsInvMass*(Double_t)i ;
272 Int_t nBinsPhi = 180;
273 Double_t minPhi = 0.0;
274 Double_t maxPhi = TMath::Pi();
275 Double_t binLimPhi[nBinsPhi+1];
276 for(Int_t i=0; i<=nBinsPhi; i++)
278 binLimPhi[i]=(Double_t)minPhi + (maxPhi-minPhi)/nBinsPhi*(Double_t)i ;
279 AliDebug(2,Form("bin phi is %f for %d",binLimPhi[i],i));
282 Int_t nBinsAngle = 180;
283 Double_t minAngle = 0.0;
284 Double_t maxAngle = TMath::Pi();
285 Double_t binLimAngle[nBinsAngle+1];
286 for(Int_t i=0; i<=nBinsAngle; i++)
288 binLimAngle[i]=(Double_t)minAngle + (maxAngle-minAngle)/nBinsAngle*(Double_t)i ;
289 AliDebug(2,Form("bin phi is %f for %d",binLimAngle[i],i));
292 // Constrain histograms
293 const Int_t nDimSingle=4;
294 const Int_t nDimPair=9;
295 Int_t nBinPair[nDimPair] = {nBinsPhi,nBinsC,nBinsPt,nBinsInvMass,nBinsSource,nBinsAngle,nBinsPt,kBinsEtaInclusive,kBinsEtaAssociated};
297 // Associated Electron
298 Int_t nBinAssElectron[nDimSingle] = {nBinsC,nBinsPt,nBinsSource,kBinsEtaAssociated};
299 fAssElectron = new THnSparseF("fAssElectron","fAssElectron",nDimSingle,nBinAssElectron);
300 fAssElectron->SetBinEdges(0,binLimC);
301 fAssElectron->SetBinEdges(1,binLimPt);
302 fAssElectron->SetBinEdges(2,binLimSource);
303 fAssElectron->SetBinEdges(3,binLimEtaAssociat);
304 fAssElectron->Sumw2();
305 AliDebug(2,"AliHFENonPhotonicElectron: fAssElectron");
307 // Inclusive Electron
308 Int_t nBinIncElectron[nDimSingle] = {nBinsC,nBinsPt,nBinsSource,kBinsEtaInclusive};
309 fIncElectron = new THnSparseF("fIncElectron","fIncElectron",nDimSingle,nBinIncElectron);
310 fIncElectron->SetBinEdges(0,binLimC);
311 fIncElectron->SetBinEdges(1,binLimPt);
312 fIncElectron->SetBinEdges(2,binLimSource);
313 fIncElectron->SetBinEdges(3,binLimEtaInclusive);
314 fIncElectron->Sumw2();
315 AliDebug(2,"AliHFENonPhotonicElectron: fIncElectron");
317 // ee invariant mass Unlike Sign
318 fUSign = new THnSparseF("fUSign","fUSign",nDimPair,nBinPair);
319 fUSign->SetBinEdges(0,binLimPhi);
320 fUSign->SetBinEdges(1,binLimC);
321 fUSign->SetBinEdges(2,binLimPt);
322 fUSign->SetBinEdges(3,binLimInvMass);
323 fUSign->SetBinEdges(4,binLimSource);
324 fUSign->SetBinEdges(5,binLimAngle);
325 fUSign->SetBinEdges(6,binLimPt);
326 fUSign->SetBinEdges(7,binLimEtaInclusive);
327 fUSign->SetBinEdges(8,binLimEtaAssociat);
329 AliDebug(2,"AliHFENonPhotonicElectron: fUSign");
331 // ee invariant mass Like Sign
332 fLSign = new THnSparseF("fLSign","fLSign",nDimPair,nBinPair);
333 fLSign->SetBinEdges(0,binLimPhi);
334 fLSign->SetBinEdges(1,binLimC);
335 fLSign->SetBinEdges(2,binLimPt);
336 fLSign->SetBinEdges(3,binLimInvMass);
337 fLSign->SetBinEdges(4,binLimSource);
338 fLSign->SetBinEdges(5,binLimAngle);
339 fLSign->SetBinEdges(6,binLimPt);
340 fLSign->SetBinEdges(7,binLimEtaInclusive);
341 fLSign->SetBinEdges(8,binLimEtaAssociat);
343 AliDebug(2,"AliHFENonPhotonicElectron: fLSign");
345 // Histograms counting the number of like sign / unlike sign matches per inclusive track
346 const Int_t nBinsMatches = 50;
347 Double_t binLimMatches[nBinsMatches+1];
348 for(int ib = 0; ib <= nBinsMatches; ib++) binLimMatches[ib] = ib;
349 const Int_t nDimMatches = 3; // centrality, pt_inc, number of matches
350 const Int_t nBinsMatchHist[nDimMatches] = {nBinsC, nBinsPt, nBinsMatches};
351 fUSmatches = new THnSparseF("fUSmatches", "fUSmatches", nDimMatches, nBinsMatchHist);
352 fUSmatches->SetBinEdges(0,binLimC);
353 fUSmatches->SetBinEdges(1,binLimPt);
354 fUSmatches->SetBinEdges(2,binLimMatches);
356 fLSmatches = new THnSparseF("fLSmatches", "fLSmatches", nDimMatches, nBinsMatchHist);
357 fLSmatches->SetBinEdges(0,binLimC);
358 fLSmatches->SetBinEdges(1,binLimPt);
359 fLSmatches->SetBinEdges(2,binLimMatches);
362 // ee angle Unlike Sign
363 const Int_t nDimUSignAngle=3;
364 Int_t nBinUSignAngle[nDimUSignAngle] = {nBinsAngle,nBinsC,nBinsSource};
365 fUSignAngle = new THnSparseF("fUSignAngle","fUSignAngle",nDimUSignAngle,nBinUSignAngle);
366 fUSignAngle->SetBinEdges(0,binLimAngle);
367 fUSignAngle->SetBinEdges(1,binLimC);
368 fUSignAngle->SetBinEdges(2,binLimSource);
369 fUSignAngle->Sumw2();
370 AliDebug(2,"AliHFENonPhotonicElectron: fUSignAngle");
372 // ee angle Like Sign
373 const Int_t nDimLSignAngle=3;
374 Int_t nBinLSignAngle[nDimLSignAngle] = {nBinsAngle,nBinsC,nBinsSource};
375 fLSignAngle = new THnSparseF("fLSignAngle","fLSignAngle",nDimLSignAngle,nBinLSignAngle);
376 fLSignAngle->SetBinEdges(0,binLimAngle);
377 fLSignAngle->SetBinEdges(1,binLimC);
378 fLSignAngle->SetBinEdges(2,binLimSource);
379 fLSignAngle->Sumw2();
380 AliDebug(2,"AliHFENonPhotonicElectron: fLSignAngle");
383 // control histogram for ITS PID
384 fHnsigmaITS = new TH2F("fHnsigmaITS", "Number of sigmas in the ITS", 30, 0., 0.3, 1200, -10., 10.);
386 fListOutput->Add(fAssElectron);
387 fListOutput->Add(fIncElectron);
388 fListOutput->Add(fUSign);
389 fListOutput->Add(fLSign);
390 fListOutput->Add(fUSmatches);
391 fListOutput->Add(fLSmatches);
392 fListOutput->Add(fHnsigmaITS);
393 // fListOutput->Add(fUSignAngle);
394 // fListOutput->Add(fLSignAngle);
398 //_____________________________________________________________________________________________
399 void AliHFENonPhotonicElectron::InitRun(const AliVEvent *inputEvent,const AliPIDResponse *pidResponse)
407 AliDebug(1, "Using default PID Response");
408 Bool_t hasmc = kFALSE;
409 if(fMCEvent || fAODArrayMCInfo) hasmc=kTRUE;
410 pidResponse = AliHFEtools::GetDefaultPID(hasmc, inputEvent->IsA() == AliESDEvent::Class());
413 if(!fPIDBackground) return;
414 fPIDBackground->SetPIDResponse(pidResponse);
416 if(!fPIDBackground->IsInitialized())
418 // Initialize PID with the given run number
419 fPIDBackground->InitializePID(inputEvent->GetRunNumber());
424 //_____________________________________________________________________________________________
425 Int_t AliHFENonPhotonicElectron::FillPoolAssociatedTracks(AliVEvent *inputEvent, Int_t binct)
428 // Fill the pool of associated tracks
429 // Return the number of associated tracks
434 fHFEBackgroundCuts->SetRecEvent(inputEvent);
435 Int_t nbtracks = inputEvent->GetNumberOfTracks();
438 fArraytrack->~TArrayI();
439 new(fArraytrack) TArrayI(nbtracks);
441 fArraytrack = new TArrayI(nbtracks);
444 fCounterPoolBackground = 0;
446 Bool_t isSelected(kFALSE);
447 Bool_t isAOD = (dynamic_cast<AliAODEvent *>(inputEvent) != NULL);
448 AliDebug(2, Form("isAOD: %s", isAOD ? "yes" : "no"));
449 for(Int_t k = 0; k < nbtracks; k++) {
450 AliVTrack *track = (AliVTrack *) inputEvent->GetTrack(k);
455 if(fSelectCategory1tracks && FilterCategory1Track(track, isAOD, binct)) isSelected = kTRUE;
456 else if(fSelectCategory2tracks && FilterCategory2Track(track, isAOD)) isSelected = kTRUE;
459 AliDebug(2,Form("fCounterPoolBackground %d, track %d",fCounterPoolBackground,k));
460 fArraytrack->AddAt(k,fCounterPoolBackground);
461 fCounterPoolBackground++;
465 //printf(Form("Associated Pool: Tracks %d, fCounterPoolBackground %d \n", nbtracks, fCounterPoolBackground));
467 return fCounterPoolBackground;
471 //_____________________________________________________________________________________________
472 Int_t AliHFENonPhotonicElectron::CountPoolAssociated(AliVEvent *inputEvent, Int_t binct)
475 // Count the pool of assiocated tracks
479 if(fnumberfound > 0) //!count only events with an inclusive electron
481 Double_t valueAssElectron[4] = { binct, -1, -1}; //Centrality Pt Source
483 Int_t indexmother2 = -1;
484 AliVTrack *track2 = 0x0;
486 for(Int_t ii = 0; ii < fCounterPoolBackground; ii++){
487 iTrack2 = fArraytrack->At(ii);
488 AliDebug(2,Form("track %d",iTrack2));
489 track2 = (AliVTrack *)inputEvent->GetTrack(iTrack2);
492 //printf("ERROR: Could not receive track %d", iTrack2);
497 if(fMCEvent || fAODArrayMCInfo) valueAssElectron[2] = FindMother(TMath::Abs(track2->GetLabel()), indexmother2) ;
499 fkPIDRespons = fPIDBackground->GetPIDResponse();
501 valueAssElectron[1] = track2->Pt() ;
502 valueAssElectron[3] = track2->Eta() ;
504 fAssElectron->Fill( valueAssElectron) ;
506 //printf(Form("Associated Pool: fCounterPoolBackground %d \n", fCounterPoolBackground));
511 //_____________________________________________________________________________________________
512 Int_t AliHFENonPhotonicElectron::LookAtNonHFE(Int_t iTrack1, AliVTrack *track1, AliVEvent *vEvent, Double_t weight, Int_t binct, Double_t deltaphi, Int_t source, Int_t indexmother)
518 /***********************************************************************************
520 * iTrack1: index of the tagged electrons in AliVEvent *
521 * track1: tagged electron *
523 * weight: weight in pt if not realistic *
524 * binct: centrality bin *
525 * deltaphi: phi-phi event plane for v2 *
526 * source: MC sources *
527 * indexmother: MC index mother *
530 * return -1 if nothing *
531 * return 2 if opposite charge within the mass range *
532 * return 4 if like charge within the mass range *
533 * return 6 if opposite & like charge within the mass range *
535 ***********************************************************************************/
537 AliAODEvent *aodeventu = dynamic_cast<AliAODEvent*>(vEvent);
538 Int_t taggedphotonic = -1;
540 AliDebug(2,Form("fCounterPoolBackground %d in LookAtNonHFE!!!",fCounterPoolBackground));
541 if(!fArraytrack) return taggedphotonic;
542 AliDebug(2,Form("process track %d",iTrack1));
543 AliDebug(1,Form("Inclusive source is %d\n", source));
545 fkPIDRespons = fPIDBackground->GetPIDResponse();
547 //Set Fill-Arrays for THnSparse
548 Double_t valueIncElectron[4] = { binct, track1->Pt(), source, track1->Eta()}; //Centrality Pt Source P
549 Double_t valueSign[9] = { deltaphi, binct, track1->Pt(), -1, source, -1, -1, track1->Eta(), -1}; //DeltaPhi Centrality Pt InvariantMass Source Angle Pt
550 //Double_t valueAngle[3] = { -1, binct, source}; //Angle Centrality Source
552 Int_t pdg1 = CheckPdg(TMath::Abs(track1->GetLabel()));
553 AliKFParticle::SetField(vEvent->GetMagneticField());
554 AliKFVertex primV(*(vEvent->GetPrimaryVertex()));
556 AliVTrack *track2(NULL);
558 Int_t indexmother2 = -1;
561 Float_t fCharge2 = 0;
563 // count number of matches with opposite/same sign track in the given mass range
564 Int_t countsMatchLikesign(0),
565 countsMatchUnlikesign(0);
569 Double_t invmass(-1);
571 Float_t fCharge1 = track1->Charge(); //Charge from track1
573 Bool_t kUSignPhotonic = kFALSE;
574 Bool_t kLSignPhotonic = kFALSE;
576 //! FILL Inclusive Electron
577 fIncElectron->Fill(valueIncElectron,weight);
579 //printf(Form("Inclusive Pool: TrackNr. %d, fnumberfound %d \n", iTrack1, fnumberfound));
581 for(Int_t idex = 0; idex < fCounterPoolBackground; idex++){
582 iTrack2 = fArraytrack->At(idex);
583 AliDebug(2,Form("track %d",iTrack2));
584 track2 = (AliVTrack *)vEvent->GetTrack(iTrack2);
587 //printf("ERROR: Could not receive track %d", iTrack2);
591 fCharge2 = track2->Charge(); //Charge from track2
594 //valueAngle[2] = source;
595 valueSign[4] = source;
596 valueSign[6] = track2->Pt();
597 valueSign[8] = track2->Eta();
599 // track cuts and PID already done
601 // Checking if it is the same Track!
602 if(iTrack2==iTrack1) continue;
603 AliDebug(2,"Different");
606 if(fMCEvent || fAODArrayMCInfo){
607 AliDebug(2, "Checking for source");
608 source2 = FindMother(TMath::Abs(track2->GetLabel()), indexmother2);
609 AliDebug(2, Form("source is %d", source2));
610 pdg2 = CheckPdg(TMath::Abs(track2->GetLabel()));
612 if(source == kElectronfromconversion){
613 AliDebug(2, Form("Electron from conversion (source %d), paired with source %d", source, source2));
614 AliDebug(2, Form("Index of the mothers: incl %d, associated %d", indexmother, indexmother2));
615 AliDebug(2, Form("PDGs: incl %d, associated %d", pdg1, pdg2));
619 if((indexmother2 == indexmother) && (source == source2) && ((pdg1*pdg2)<0.0)){
620 AliDebug(1, "Real pair");
622 case kElectronfromconversion:
623 valueSign[4] = kElectronfromconversionboth;
625 case kElectronfrompi0:
626 valueSign[4] = kElectronfrompi0both;
628 case kElectronfrometa:
629 valueSign[4] = kElectronfrometaboth;
637 // Use TLorentzVector
638 if(!MakePairDCA(track1, track2, vEvent, (aodeventu != NULL), invmass, angle)) continue;
641 if(!MakePairKF(track1, track2, primV, invmass, angle)) continue;
644 valueSign[3] = invmass;
645 valueSign[5] = angle;
647 //if((fCharge1*fCharge2)>0.0) fLSignAngle->Fill(&valueAngle[0],weight);
648 //else fUSignAngle->Fill(&valueAngle[0],weight);
650 if(angle > fMaxOpening3D) continue; //! Cut on Opening Angle
651 if(invmass > fMaxInvMass) continue; //! Cut on Invariant Mass
653 if((fCharge1*fCharge2)>0.0){
654 if(invmass < 1.0) fLSign->Fill( valueSign, weight);
655 // count like-sign background matched pairs per inclusive based on mass cut
656 if(invmass < 0.14) countsMatchLikesign++;
657 AliDebug(1, "Selected Like sign");
659 if(invmass < 1.0)fUSign->Fill( valueSign, weight);
660 // count unlike-sign matched pairs per inclusive based on mass cut
661 if(invmass < 0.14) countsMatchUnlikesign++;
662 AliDebug(1, "Selected Unike sign");
665 if((fCharge1*fCharge2)>0.0) kLSignPhotonic=kTRUE;
666 else kUSignPhotonic=kTRUE;
670 Double_t valCountsLS[3] = {binct, track1->Pt(), countsMatchLikesign},
671 valCountsUS[3] = {binct, track1->Pt(), countsMatchUnlikesign};
672 fUSmatches->Fill(valCountsUS);
673 fLSmatches->Fill(valCountsLS);
675 if( kUSignPhotonic && kLSignPhotonic) taggedphotonic = 6;
676 if(!kUSignPhotonic && kLSignPhotonic) taggedphotonic = 4;
677 if( kUSignPhotonic && !kLSignPhotonic) taggedphotonic = 2;
679 return taggedphotonic;
682 //_________________________________________________________________________
683 Int_t AliHFENonPhotonicElectron::FindMother(Int_t tr, Int_t &indexmother) const {
685 // Find the mother if MC
688 if(!fMCEvent && !fAODArrayMCInfo) return 0;
690 Int_t pdg = CheckPdg(tr);
691 if(TMath::Abs(pdg)!= 11)
697 indexmother = IsMotherGamma(tr);
698 if(indexmother > 0) return kElectronfromconversion;
699 indexmother = IsMotherPi0(tr);
700 if(indexmother > 0) return kElectronfrompi0;
701 indexmother = IsMotherC(tr);
702 if(indexmother > 0) return kElectronfromC;
703 indexmother = IsMotherB(tr);
704 if(indexmother > 0) return kElectronfromB;
705 indexmother = IsMotherEta(tr);
706 if(indexmother > 0) return kElectronfrometa;
708 return kElectronfromother;
711 //________________________________________________________________________________________________
712 Int_t AliHFENonPhotonicElectron::CheckPdg(Int_t tr) const {
715 // Return the pdg of the particle
719 if(tr < 0) return pdgcode;
721 AliMCParticle *mctrackesd = NULL; AliAODMCParticle *mctrackaod = NULL;
723 AliVParticle *mctrack = fMCEvent->GetTrack(tr);
725 if((mctrackesd = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))) pdgcode = mctrackesd->PdgCode();
726 else if((mctrackaod = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))) pdgcode = mctrackaod->GetPdgCode();
728 } else if(fAODArrayMCInfo) {
729 if(tr < fAODArrayMCInfo->GetEntriesFast()){
730 mctrackaod = (AliAODMCParticle *) fAODArrayMCInfo->At(tr);
731 if(mctrackaod) return pdgcode = mctrackaod->GetPdgCode();
738 //_______________________________________________________________________________________________
739 Int_t AliHFENonPhotonicElectron::GetMotherPDG(Int_t tr, Int_t &motherIndex) const {
741 // Returns the mother PDG of the track (return value) and the index of the
744 if(tr < 0) return -1;
747 AliMCParticle *mctrackesd(NULL); AliAODMCParticle *mctrackaod(NULL);
751 AliDebug(2, "Using MC Event");
752 AliVParticle *mctrack = fMCEvent->GetTrack(tr);
754 if((mctrackesd = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))){
756 TParticle *particle = mctrackesd->Particle();
760 motherIndex = particle->GetFirstMother();
761 if(motherIndex >= 0){
762 AliMCParticle *mothertrack = NULL;
763 if((mothertrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(motherIndex))))){
764 TParticle * mother = mothertrack->Particle();
765 pdg = mother->GetPdgCode();
769 } else if((mctrackaod = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))){
772 motherIndex = mctrackaod->GetMother();
773 if(motherIndex >= 0){
774 AliAODMCParticle *mothertrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(motherIndex));
775 if(mothertrack) pdg = mothertrack->GetPdgCode();
779 } else if(fAODArrayMCInfo) {
780 AliDebug(2, "Using AOD list");
781 if(tr < fAODArrayMCInfo->GetEntriesFast()){
782 mctrackaod = (AliAODMCParticle *) fAODArrayMCInfo->At(tr);
786 motherIndex = mctrackaod->GetMother();
787 if(motherIndex >= 0 && motherIndex < fAODArrayMCInfo->GetEntriesFast()){
788 AliAODMCParticle *mothertrack = dynamic_cast<AliAODMCParticle *>(fAODArrayMCInfo->At(TMath::Abs(motherIndex)));
789 if(mothertrack) pdg = mothertrack->GetPdgCode();
797 //_______________________________________________________________________________________________
798 Int_t AliHFENonPhotonicElectron::IsMotherGamma(Int_t tr) const {
801 // Return the lab of gamma mother or -1 if not gamma
804 Int_t imother(-1), pdg(-1);
805 pdg = GetMotherPDG(tr, imother);
809 if(TMath::Abs(pdg) == 22){
810 AliDebug(2, "Gamma Mother selected");
813 if(TMath::Abs(pdg) == 11){
814 AliDebug(2, "Mother is electron - look further in hierarchy");
815 return IsMotherGamma(imother);
817 AliDebug(2, "Nothing selected");
820 AliDebug(2, "Not mother");
824 //________________________________________________________________________________________________
825 Int_t AliHFENonPhotonicElectron::IsMotherPi0(Int_t tr) const {
828 // Return the lab of pi0 mother or -1 if not pi0
831 Int_t imother(-1), pdg(-1);
832 pdg = GetMotherPDG(tr, imother);
836 if(TMath::Abs(pdg) == 111){
837 AliDebug(2, "Pi0 Mother selected");
840 if(TMath::Abs(pdg) == 11){
841 AliDebug(2, "Mother is electron - look further in hierarchy");
842 return IsMotherPi0(imother);
844 AliDebug(2, "Nothing selected");
847 AliDebug(2, "Not mother");
850 //________________________________________________________________________________________________
851 Int_t AliHFENonPhotonicElectron::IsMotherC(Int_t tr) const {
854 // Return the lab of signal mother or -1 if not from C
857 Int_t imother(-1), pdg(-1);
858 pdg = GetMotherPDG(tr, imother);
862 if((TMath::Abs(pdg)==411) || (TMath::Abs(pdg)==421) || (TMath::Abs(pdg)==431) || (TMath::Abs(pdg)==4122) || (TMath::Abs(pdg)==4132) || (TMath::Abs(pdg)==4232) || (TMath::Abs(pdg)==43320)){
863 AliDebug(2, "Charm Mother selected");
866 if(TMath::Abs(pdg) == 11){
867 AliDebug(2, "Mother is electron - look further in hierarchy");
868 return IsMotherC(imother);
870 AliDebug(2, "Nothing selected");
873 AliDebug(2, "Not mother");
877 //_______________________________________________________________________________________________
878 Int_t AliHFENonPhotonicElectron::IsMotherB(Int_t tr) const {
881 // Return the lab of signal mother or -1 if not B
884 Int_t imother(-1), pdg(-1);
885 pdg = GetMotherPDG(tr, imother);
889 if((TMath::Abs(pdg)==511) || (TMath::Abs(pdg)==521) || (TMath::Abs(pdg)==531) || (TMath::Abs(pdg)==5122) || (TMath::Abs(pdg)==5132) || (TMath::Abs(pdg)==5232) || (TMath::Abs(pdg)==53320)){
890 AliDebug(2, "Bottom Mother selected");
893 if(TMath::Abs(pdg) == 11){
894 return IsMotherB(imother);
895 AliDebug(2, "Mother is electron - look further in hierarchy");
897 AliDebug(2, "Nothing selected");
900 AliDebug(2, "Not mother");
904 //_______________________________________________________________________________________________
905 Int_t AliHFENonPhotonicElectron::IsMotherEta(Int_t tr) const {
908 // Return the lab of eta mother or -1 if not eta
911 Int_t imother(-1), pdg(-1);
912 pdg = GetMotherPDG(tr, imother);
916 if(TMath::Abs(pdg) == 221){
917 AliDebug(2, "Eta mother selected");
920 if(TMath::Abs(pdg) == 11){
921 AliDebug(2, "Mother is electron - look further in hierarchy");
922 return IsMotherEta(imother);
924 AliDebug(2, "Nothing selected");
927 AliDebug(2, "Not mother");
931 //_______________________________________________________________________________________________
932 Bool_t AliHFENonPhotonicElectron::MakePairDCA(const AliVTrack *inclusive, const AliVTrack *associated, AliVEvent *vEvent, Bool_t isAOD, Double_t &invMass, Double_t &angle) const {
934 // Make Pairs of electrons using TLorentzVector
936 Double_t eMass = TDatabasePDG::Instance()->GetParticle(11)->Mass(); //Electron mass in GeV
937 Double_t bfield = vEvent->GetMagneticField();
939 AliESDtrack *esdtrack1, *esdtrack2;
941 // call copy constructor for AODs
942 esdtrack1 = new AliESDtrack(inclusive);
943 esdtrack2 = new AliESDtrack(associated);
945 // call copy constructor for ESDs
946 esdtrack1 = new AliESDtrack(*(static_cast<const AliESDtrack *>(inclusive)));
947 esdtrack2 = new AliESDtrack(*(static_cast<const AliESDtrack *>(associated)));
949 if((!esdtrack1) || (!esdtrack2)){
955 Double_t xt1 = 0; //radial position track 1 at the DCA point
956 Double_t xt2 = 0; //radial position track 2 at the DCA point
957 Double_t dca = esdtrack2->GetDCA(esdtrack1,bfield,xt2,xt1); //DCA track1-track2
959 // Apply DCA cut already in the function
965 //Momenta of the track extrapolated to DCA track-track
966 Double_t p1[3] = {0,0,0};
967 Double_t p2[3] = {0,0,0};
968 Bool_t kHasdcaT1 = esdtrack1->GetPxPyPzAt(xt1,bfield,p1); //Track1
969 Bool_t kHasdcaT2 = esdtrack2->GetPxPyPzAt(xt2,bfield,p2); //Track2
970 if(!kHasdcaT1 || !kHasdcaT2) AliWarning("It could be a problem in the extrapolation");
972 TLorentzVector electron1, electron2, mother;
973 electron1.SetXYZM(p1[0], p1[1], p1[2], eMass);
974 electron2.SetXYZM(p2[0], p2[1], p2[2], eMass);
976 mother = electron1 + electron2;
977 invMass = mother.M();
978 angle = TVector2::Phi_0_2pi(electron1.Angle(electron2.Vect()));
985 //_______________________________________________________________________________________________
986 Bool_t AliHFENonPhotonicElectron::MakePairKF(const AliVTrack *inclusive, const AliVTrack *associated, AliKFVertex &primV, Double_t &invMass, Double_t &angle) const {
988 // Make pairs of electrons using the AliKF package
991 //printf("AOD HFE non photonic\n");
993 Int_t fPDGtrack1 = 11;
994 if(inclusive->Charge()>0) fPDGtrack1 = -11;
995 Int_t fPDGtrack2 = 11;
996 if(associated->Charge()>0) fPDGtrack2 = -11;
998 AliKFParticle ktrack1(*inclusive, fPDGtrack1);
999 AliKFParticle ktrack2(*associated, fPDGtrack2);
1000 AliKFParticle recoGamma(ktrack1,ktrack2);
1002 if(recoGamma.GetNDF()<1) return kFALSE; //! Cut on Reconstruction
1004 Double_t chi2OverNDF = recoGamma.GetChi2()/recoGamma.GetNDF();
1005 if(TMath::Sqrt(TMath::Abs(chi2OverNDF))>fChi2OverNDFCut) return kFALSE;
1007 if(fSetMassConstraint){
1011 recoGamma.SetProductionVertex(primV);
1012 recoGamma.SetMassConstraint(0,0.0001);
1016 recoGamma.GetMass(invMass,width);
1017 angle = ktrack1.GetAngle(ktrack2);
1021 //_______________________________________________________________________________________________
1022 Bool_t AliHFENonPhotonicElectron::FilterCategory1Track(const AliVTrack * const track, Bool_t isAOD, Int_t binct){
1024 // Selection of good associated tracks for the pool
1025 // selection is done using strong cuts
1026 // Tracking in the TPC and the ITS is a minimal requirement
1028 Bool_t survivedbackground = kTRUE;
1030 if(!fHFEBackgroundCuts->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, (TObject *) track)) survivedbackground = kFALSE;
1031 AliDebug(3, Form("First cut: %s\n", survivedbackground == kTRUE ? "yes" : "no"));
1032 if(!fHFEBackgroundCuts->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, (TObject *) track)) survivedbackground = kFALSE;
1033 AliDebug(3, Form("Second cut: %s\n", survivedbackground == kTRUE ? "yes" : "no"));
1035 if(survivedbackground){
1037 AliHFEpidObject hfetrack2;
1039 if(!isAOD) hfetrack2.SetAnalysisType(AliHFEpidObject::kESDanalysis);
1040 else hfetrack2.SetAnalysisType(AliHFEpidObject::kAODanalysis);
1042 hfetrack2.SetRecTrack(track);
1044 hfetrack2.SetCentrality((Int_t)binct);
1045 AliDebug(3,Form("centrality %d and %d",binct,hfetrack2.GetCentrality()));
1046 hfetrack2.SetPbPb();
1049 if(fPIDBackground->IsSelected(&hfetrack2,0x0,"recTrackCont",fPIDBackgroundQA)){
1050 survivedbackground = kTRUE;
1051 } else survivedbackground = kFALSE;
1053 AliDebug(3, Form("PID: %s\n", survivedbackground == kTRUE ? "yes" : "no"));
1054 return survivedbackground;
1057 //_______________________________________________________________________________________________
1058 Bool_t AliHFENonPhotonicElectron::FilterCategory2Track(const AliVTrack * const track, Bool_t isAOD){
1060 // Selection of category 2 tracks: These tracks are exclusively low pt tracks below
1061 // 300 MeV/c which have at least 2 hits in the 4 outer ITS layers and are identified as
1062 // electron candidates by the ITS
1064 if(TMath::Abs(track->Pt()) > 0.3) return kFALSE;
1065 Int_t nclustersITS(0), nclustersOuter(0);
1067 const AliAODTrack *aodtrack = static_cast<const AliAODTrack *>(track);
1068 if(!(aodtrack->TestFilterBit(AliAODTrack::kTrkGlobalNoDCA) || aodtrack->TestFilterBit(AliAODTrack::kTrkITSsa))) return kFALSE;
1069 nclustersITS = aodtrack->GetITSNcls();
1070 for(int ily = 2; ily < 5; ily++)
1071 if(aodtrack->HasPointOnITSLayer(ily)) nclustersOuter++;
1073 const AliESDtrack *esdtrack = static_cast<const AliESDtrack *>(track);
1074 if(esdtrack->GetStatus() & AliESDtrack::kITSpureSA) return kFALSE;
1075 nclustersITS = esdtrack->GetITSclusters(NULL);
1076 for(int ily = 2; ily < 5; ily++)
1077 if(esdtrack->HasPointOnITSLayer(ily)) nclustersOuter++;
1079 if(nclustersITS < 4) return kFALSE;
1080 if(nclustersOuter < 3) return kFALSE;
1083 Double_t nsigmaITS = fPIDBackground->GetPIDResponse()->NumberOfSigmasITS(track, AliPID::kElectron);
1084 fHnsigmaITS->Fill(track->Pt(), nsigmaITS);
1085 if(TMath::Abs(nsigmaITS - fITSmeanShift) > 3.) return kFALSE;
1086 // if global track, we apply also TPC PID