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)
74 ,fChi2OverNDFCut (3.0)
76 // ,fMaxOpeningTheta (0.02)
77 // ,fMaxOpeningPhi (0.1)
78 ,fMaxOpening3D (TMath::Pi())
80 ,fSetMassConstraint (kFALSE)
81 ,fSelectCategory1tracks(kTRUE)
82 ,fSelectCategory2tracks(kFALSE)
85 ,fCounterPoolBackground (0)
95 // ,fUSignAngle (NULL)
96 // ,fLSignAngle (NULL)
101 fPIDBackground = new AliHFEpid("hfePidBackground");
102 fPIDBackgroundQA = new AliHFEpidQAmanager;
105 //________________________________________________________________________
106 AliHFENonPhotonicElectron::AliHFENonPhotonicElectron()
110 ,fAODArrayMCInfo (NULL)
111 ,fHFEBackgroundCuts (NULL)
112 ,fPIDBackground (0x0)
113 ,fPIDBackgroundQA (0)
117 ,fAlgorithmMA (kTRUE)
118 ,fChi2OverNDFCut (3.0)
120 // ,fMaxOpeningTheta (0.02)
121 // ,fMaxOpeningPhi (0.1)
122 ,fMaxOpening3D (TMath::TwoPi())
124 ,fSetMassConstraint (kFALSE)
125 ,fSelectCategory1tracks(kTRUE)
126 ,fSelectCategory2tracks(kFALSE)
129 ,fCounterPoolBackground (0)
139 // ,fUSignAngle (NULL)
140 // ,fLSignAngle (NULL)
145 fPIDBackground = new AliHFEpid("hfePidBackground");
146 fPIDBackgroundQA = new AliHFEpidQAmanager;
149 //________________________________________________________________________
150 AliHFENonPhotonicElectron::AliHFENonPhotonicElectron(const AliHFENonPhotonicElectron &ref)
154 ,fAODArrayMCInfo (NULL)
155 ,fHFEBackgroundCuts (ref.fHFEBackgroundCuts)
156 ,fPIDBackground (ref.fPIDBackground)
157 ,fPIDBackgroundQA (ref.fPIDBackgroundQA)
158 ,fkPIDRespons (ref.fkPIDRespons)
159 ,fPtBinning(ref.fPtBinning)
160 ,fEtaBinning(ref.fEtaBinning)
161 ,fAlgorithmMA (ref.fAlgorithmMA)
162 ,fChi2OverNDFCut (ref.fChi2OverNDFCut)
163 ,fMaxDCA (ref.fMaxDCA)
164 // ,fMaxOpeningTheta (ref.fMaxOpeningTheta)
165 // ,fMaxOpeningPhi (ref.fMaxOpeningPhi)
166 ,fMaxOpening3D (ref.fMaxOpening3D)
167 ,fMaxInvMass (ref.fMaxInvMass)
168 ,fSetMassConstraint (ref.fSetMassConstraint)
169 ,fSelectCategory1tracks(ref.fSelectCategory1tracks)
170 ,fSelectCategory2tracks(ref.fSelectCategory2tracks)
171 ,fITSmeanShift(ref.fITSmeanShift)
173 ,fCounterPoolBackground (0)
175 ,fListOutput (ref.fListOutput)
176 ,fAssElectron (ref.fAssElectron)
177 ,fIncElectron (ref.fIncElectron)
180 ,fUSmatches(ref.fUSmatches)
181 ,fLSmatches(ref.fLSmatches)
182 ,fHnsigmaITS(ref.fHnsigmaITS)
183 // ,fUSignAngle (ref.fUSignAngle)
184 // ,fLSignAngle (ref.fLSignAngle)
192 //____________________________________________________________
193 AliHFENonPhotonicElectron &AliHFENonPhotonicElectron::operator=(const AliHFENonPhotonicElectron &ref){
195 // Assignment operator
197 if(this == &ref) ref.Copy(*this);
201 //_________________________________________
202 AliHFENonPhotonicElectron::~AliHFENonPhotonicElectron()
207 if(fArraytrack) delete fArraytrack;
208 //if(fHFEBackgroundCuts) delete fHFEBackgroundCuts;
209 if(fPIDBackground) delete fPIDBackground;
210 if(fPIDBackgroundQA) delete fPIDBackgroundQA;
213 //_____________________________________________________________________________________________
214 void AliHFENonPhotonicElectron::Init()
220 //printf("Analysis Mode for AliHFENonPhotonicElectron: %s Analysis\n", fIsAOD ? "AOD" : "ESD");
222 if(!fListOutput) fListOutput = new TList;
223 fListOutput->SetName("HFENonPhotonicElectron");
224 fListOutput->SetOwner();
226 if(!fHFEBackgroundCuts) fHFEBackgroundCuts = new AliHFEcuts();
227 if(fIsAOD) fHFEBackgroundCuts->SetAOD();
228 fHFEBackgroundCuts->Initialize();
229 if(fHFEBackgroundCuts->IsQAOn()) {
230 fListOutput->Add(fHFEBackgroundCuts->GetQAhistograms());
234 if(!fPIDBackground) fPIDBackground = new AliHFEpid("default pid");
235 if(fMCEvent || fAODArrayMCInfo) fPIDBackground->SetHasMCData(kTRUE); // does nothing since the fMCEvent are set afterwards at the moment
236 if(!fPIDBackground->GetNumberOfPIDdetectors())
238 //fPIDBackground->AddDetector("TOF", 0);
239 fPIDBackground->AddDetector("TPC", 0);
241 AliInfo("PID Background QA switched on");
242 fPIDBackgroundQA->Initialize(fPIDBackground);
243 fListOutput->Add(fPIDBackgroundQA->MakeList("HFENP_PID_Background"));
244 fPIDBackground->SortDetectors();
246 const Int_t kBinsPtDefault = 35;
247 Double_t binLimPtDefault[kBinsPtDefault+1] = {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.};
248 const Int_t kBinsEtaInclusiveDefault = 8;
249 Double_t binLimEtaInclusiveDefault[kBinsEtaInclusiveDefault+1] = {-0.8, -0.6, -0.4, -0.2, 0., 0.2, 0.4, 0.6, 0.8};
250 const Int_t kBinsEtaAssociated = 30;
251 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};
253 if(!fPtBinning.GetSize()) fPtBinning.Set(kBinsPtDefault+1, binLimPtDefault);
254 if(!fEtaBinning.GetSize()) fEtaBinning.Set(kBinsEtaInclusiveDefault+1, binLimEtaInclusiveDefault);
256 //Int_t nBinsP = 400;
257 //Double_t minP = 0.0;
258 //Double_t maxP = 20.0;
259 //Double_t binLimP[nBinsP+1];
260 //for(Int_t i=0; i<=nBinsP; i++) binLimP[i]=(Double_t)minP + (maxP-minP)/nBinsP*(Double_t)i ;
264 Double_t maxC = 11.0;
265 Double_t binLimC[nBinsC+1];
266 for(Int_t i=0; i<=nBinsC; i++) binLimC[i]=(Double_t)minC + (maxC-minC)/nBinsC*(Double_t)i ;
268 Int_t nBinsSource = 10;
269 Double_t minSource = 0.;
270 Double_t maxSource = 10.;
271 Double_t binLimSource[nBinsSource+1];
272 for(Int_t i=0; i<=nBinsSource; i++) binLimSource[i]=(Double_t)minSource + (maxSource-minSource)/nBinsSource*(Double_t)i ;
274 Int_t nBinsInvMass = 100;
275 Double_t minInvMass = 0.;
276 Double_t maxInvMass = 1.;
277 Double_t binLimInvMass[nBinsInvMass+1];
278 for(Int_t i=0; i<=nBinsInvMass; i++) binLimInvMass[i]=(Double_t)minInvMass + (maxInvMass-minInvMass)/nBinsInvMass*(Double_t)i ;
280 Int_t nBinsPhi = 180;
281 Double_t minPhi = 0.0;
282 Double_t maxPhi = TMath::Pi();
283 Double_t binLimPhi[nBinsPhi+1];
284 for(Int_t i=0; i<=nBinsPhi; i++)
286 binLimPhi[i]=(Double_t)minPhi + (maxPhi-minPhi)/nBinsPhi*(Double_t)i ;
287 AliDebug(2,Form("bin phi is %f for %d",binLimPhi[i],i));
290 Int_t nBinsAngle = 180;
291 Double_t minAngle = 0.0;
292 Double_t maxAngle = TMath::Pi();
293 Double_t binLimAngle[nBinsAngle+1];
294 for(Int_t i=0; i<=nBinsAngle; i++)
296 binLimAngle[i]=(Double_t)minAngle + (maxAngle-minAngle)/nBinsAngle*(Double_t)i ;
297 AliDebug(2,Form("bin phi is %f for %d",binLimAngle[i],i));
300 // Constrain histograms
301 const Int_t nDimSingle=4;
302 const Int_t nDimPair=9;
303 Int_t nBinPair[nDimPair] = {nBinsPhi,nBinsC,fPtBinning.GetSize()-1,nBinsInvMass,nBinsSource,nBinsAngle,fPtBinning.GetSize()-1,fEtaBinning.GetSize()-1,kBinsEtaAssociated};
305 // Associated Electron
306 Int_t nBinAssElectron[nDimSingle] = {nBinsC,fPtBinning.GetSize()-1,nBinsSource,kBinsEtaAssociated};
307 fAssElectron = new THnSparseF("fAssElectron","fAssElectron",nDimSingle,nBinAssElectron);
308 fAssElectron->SetBinEdges(0,binLimC);
309 fAssElectron->SetBinEdges(1,fPtBinning.GetArray());
310 fAssElectron->SetBinEdges(2,binLimSource);
311 fAssElectron->SetBinEdges(3,binLimEtaAssociat);
312 fAssElectron->Sumw2();
313 AliDebug(2,"AliHFENonPhotonicElectron: fAssElectron");
315 // Inclusive Electron
316 Int_t nBinIncElectron[nDimSingle] = {nBinsC,fPtBinning.GetSize()-1,nBinsSource,fEtaBinning.GetSize()-1};
317 fIncElectron = new THnSparseF("fIncElectron","fIncElectron",nDimSingle,nBinIncElectron);
318 fIncElectron->SetBinEdges(0,binLimC);
319 fIncElectron->SetBinEdges(1,fPtBinning.GetArray());
320 fIncElectron->SetBinEdges(2,binLimSource);
321 fIncElectron->SetBinEdges(3,fEtaBinning.GetArray());
322 fIncElectron->Sumw2();
323 AliDebug(2,"AliHFENonPhotonicElectron: fIncElectron");
325 // ee invariant mass Unlike Sign
326 fUSign = new THnSparseF("fUSign","fUSign",nDimPair,nBinPair);
327 fUSign->SetBinEdges(0,binLimPhi);
328 fUSign->SetBinEdges(1,binLimC);
329 fUSign->SetBinEdges(2,fPtBinning.GetArray());
330 fUSign->SetBinEdges(3,binLimInvMass);
331 fUSign->SetBinEdges(4,binLimSource);
332 fUSign->SetBinEdges(5,binLimAngle);
333 fUSign->SetBinEdges(6,fPtBinning.GetArray());
334 fUSign->SetBinEdges(7,fEtaBinning.GetArray());
335 fUSign->SetBinEdges(8,binLimEtaAssociat);
337 AliDebug(2,"AliHFENonPhotonicElectron: fUSign");
339 // ee invariant mass Like Sign
340 fLSign = new THnSparseF("fLSign","fLSign",nDimPair,nBinPair);
341 fLSign->SetBinEdges(0,binLimPhi);
342 fLSign->SetBinEdges(1,binLimC);
343 fLSign->SetBinEdges(2,fPtBinning.GetArray());
344 fLSign->SetBinEdges(3,binLimInvMass);
345 fLSign->SetBinEdges(4,binLimSource);
346 fLSign->SetBinEdges(5,binLimAngle);
347 fLSign->SetBinEdges(6,fPtBinning.GetArray());
348 fLSign->SetBinEdges(7,fEtaBinning.GetArray());
349 fLSign->SetBinEdges(8,binLimEtaAssociat);
351 AliDebug(2,"AliHFENonPhotonicElectron: fLSign");
353 // Histograms counting the number of like sign / unlike sign matches per inclusive track
354 const Int_t nBinsMatches = 50;
355 Double_t binLimMatches[nBinsMatches+1];
356 for(int ib = 0; ib <= nBinsMatches; ib++) binLimMatches[ib] = ib;
357 const Int_t nDimMatches = 3; // centrality, pt_inc, number of matches
358 const Int_t nBinsMatchHist[nDimMatches] = {nBinsC, fPtBinning.GetSize()-1, nBinsMatches};
359 fUSmatches = new THnSparseF("fUSmatches", "fUSmatches", nDimMatches, nBinsMatchHist);
360 fUSmatches->SetBinEdges(0,binLimC);
361 fUSmatches->SetBinEdges(1,fPtBinning.GetArray());
362 fUSmatches->SetBinEdges(2,binLimMatches);
364 fLSmatches = new THnSparseF("fLSmatches", "fLSmatches", nDimMatches, nBinsMatchHist);
365 fLSmatches->SetBinEdges(0,binLimC);
366 fLSmatches->SetBinEdges(1,fPtBinning.GetArray());
367 fLSmatches->SetBinEdges(2,binLimMatches);
370 // ee angle Unlike Sign
371 const Int_t nDimUSignAngle=3;
372 Int_t nBinUSignAngle[nDimUSignAngle] = {nBinsAngle,nBinsC,nBinsSource};
373 fUSignAngle = new THnSparseF("fUSignAngle","fUSignAngle",nDimUSignAngle,nBinUSignAngle);
374 fUSignAngle->SetBinEdges(0,binLimAngle);
375 fUSignAngle->SetBinEdges(1,binLimC);
376 fUSignAngle->SetBinEdges(2,binLimSource);
377 fUSignAngle->Sumw2();
378 AliDebug(2,"AliHFENonPhotonicElectron: fUSignAngle");
380 // ee angle Like Sign
381 const Int_t nDimLSignAngle=3;
382 Int_t nBinLSignAngle[nDimLSignAngle] = {nBinsAngle,nBinsC,nBinsSource};
383 fLSignAngle = new THnSparseF("fLSignAngle","fLSignAngle",nDimLSignAngle,nBinLSignAngle);
384 fLSignAngle->SetBinEdges(0,binLimAngle);
385 fLSignAngle->SetBinEdges(1,binLimC);
386 fLSignAngle->SetBinEdges(2,binLimSource);
387 fLSignAngle->Sumw2();
388 AliDebug(2,"AliHFENonPhotonicElectron: fLSignAngle");
391 // control histogram for ITS PID
392 fHnsigmaITS = new TH2F("fHnsigmaITS", "Number of sigmas in the ITS", 30, 0., 0.3, 1200, -10., 10.);
394 fListOutput->Add(fAssElectron);
395 fListOutput->Add(fIncElectron);
396 fListOutput->Add(fUSign);
397 fListOutput->Add(fLSign);
398 fListOutput->Add(fUSmatches);
399 fListOutput->Add(fLSmatches);
400 fListOutput->Add(fHnsigmaITS);
401 // fListOutput->Add(fUSignAngle);
402 // fListOutput->Add(fLSignAngle);
406 //_____________________________________________________________________________________________
407 void AliHFENonPhotonicElectron::InitRun(const AliVEvent *inputEvent,const AliPIDResponse *pidResponse)
415 AliDebug(1, "Using default PID Response");
416 Bool_t hasmc = kFALSE;
417 if(fMCEvent || fAODArrayMCInfo) hasmc=kTRUE;
418 pidResponse = AliHFEtools::GetDefaultPID(hasmc, inputEvent->IsA() == AliESDEvent::Class());
421 if(!fPIDBackground) return;
422 fPIDBackground->SetPIDResponse(pidResponse);
424 if(!fPIDBackground->IsInitialized())
426 // Initialize PID with the given run number
427 fPIDBackground->InitializePID(inputEvent->GetRunNumber());
432 //_____________________________________________________________________________________________
433 Int_t AliHFENonPhotonicElectron::FillPoolAssociatedTracks(AliVEvent *inputEvent, Int_t binct)
436 // Fill the pool of associated tracks
437 // Return the number of associated tracks
442 fHFEBackgroundCuts->SetRecEvent(inputEvent);
443 Int_t nbtracks = inputEvent->GetNumberOfTracks();
446 fArraytrack->~TArrayI();
447 new(fArraytrack) TArrayI(nbtracks);
449 fArraytrack = new TArrayI(nbtracks);
452 fCounterPoolBackground = 0;
454 Bool_t isSelected(kFALSE);
455 Bool_t isAOD = (dynamic_cast<AliAODEvent *>(inputEvent) != NULL);
456 AliDebug(2, Form("isAOD: %s", isAOD ? "yes" : "no"));
457 for(Int_t k = 0; k < nbtracks; k++) {
458 AliVTrack *track = (AliVTrack *) inputEvent->GetTrack(k);
463 if(fSelectCategory1tracks && FilterCategory1Track(track, isAOD, binct)) isSelected = kTRUE;
464 else if(fSelectCategory2tracks && FilterCategory2Track(track, isAOD)) isSelected = kTRUE;
467 AliDebug(2,Form("fCounterPoolBackground %d, track %d",fCounterPoolBackground,k));
468 fArraytrack->AddAt(k,fCounterPoolBackground);
469 fCounterPoolBackground++;
473 //printf(Form("Associated Pool: Tracks %d, fCounterPoolBackground %d \n", nbtracks, fCounterPoolBackground));
475 return fCounterPoolBackground;
479 //_____________________________________________________________________________________________
480 Int_t AliHFENonPhotonicElectron::CountPoolAssociated(AliVEvent *inputEvent, Int_t binct)
483 // Count the pool of assiocated tracks
487 if(fnumberfound > 0) //!count only events with an inclusive electron
489 Double_t valueAssElectron[4] = { binct, -1, -1}; //Centrality Pt Source
491 Int_t indexmother2 = -1;
492 AliVTrack *track2 = 0x0;
494 for(Int_t ii = 0; ii < fCounterPoolBackground; ii++){
495 iTrack2 = fArraytrack->At(ii);
496 AliDebug(2,Form("track %d",iTrack2));
497 track2 = (AliVTrack *)inputEvent->GetTrack(iTrack2);
500 //printf("ERROR: Could not receive track %d", iTrack2);
505 if(fMCEvent || fAODArrayMCInfo) valueAssElectron[2] = FindMother(TMath::Abs(track2->GetLabel()), indexmother2) ;
507 fkPIDRespons = fPIDBackground->GetPIDResponse();
509 valueAssElectron[1] = track2->Pt() ;
510 valueAssElectron[3] = track2->Eta() ;
512 fAssElectron->Fill( valueAssElectron) ;
514 //printf(Form("Associated Pool: fCounterPoolBackground %d \n", fCounterPoolBackground));
519 //_____________________________________________________________________________________________
520 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)
526 /***********************************************************************************
528 * iTrack1: index of the tagged electrons in AliVEvent *
529 * track1: tagged electron *
531 * weight: weight in pt if not realistic *
532 * binct: centrality bin *
533 * deltaphi: phi-phi event plane for v2 *
534 * source: MC sources *
535 * indexmother: MC index mother *
538 * return -1 if nothing *
539 * return 2 if opposite charge within the mass range *
540 * return 4 if like charge within the mass range *
541 * return 6 if opposite & like charge within the mass range *
543 ***********************************************************************************/
545 AliAODEvent *aodeventu = dynamic_cast<AliAODEvent*>(vEvent);
546 Int_t taggedphotonic = -1;
548 AliDebug(2,Form("fCounterPoolBackground %d in LookAtNonHFE!!!",fCounterPoolBackground));
549 if(!fArraytrack) return taggedphotonic;
550 AliDebug(2,Form("process track %d",iTrack1));
551 AliDebug(1,Form("Inclusive source is %d\n", source));
553 fkPIDRespons = fPIDBackground->GetPIDResponse();
555 //Set Fill-Arrays for THnSparse
556 Double_t valueIncElectron[4] = { binct, track1->Pt(), source, track1->Eta()}; //Centrality Pt Source P
557 Double_t valueSign[9] = { deltaphi, binct, track1->Pt(), -1, source, -1, -1, track1->Eta(), -1}; //DeltaPhi Centrality Pt InvariantMass Source Angle Pt
558 //Double_t valueAngle[3] = { -1, binct, source}; //Angle Centrality Source
560 Int_t pdg1 = CheckPdg(TMath::Abs(track1->GetLabel()));
561 AliKFParticle::SetField(vEvent->GetMagneticField());
562 AliKFVertex primV(*(vEvent->GetPrimaryVertex()));
564 AliVTrack *track2(NULL);
566 Int_t indexmother2 = -1;
569 Float_t fCharge2 = 0;
571 // count number of matches with opposite/same sign track in the given mass range
572 Int_t countsMatchLikesign(0),
573 countsMatchUnlikesign(0);
577 Double_t invmass(-1);
579 Float_t fCharge1 = track1->Charge(); //Charge from track1
581 Bool_t kUSignPhotonic = kFALSE;
582 Bool_t kLSignPhotonic = kFALSE;
584 //! FILL Inclusive Electron
585 fIncElectron->Fill(valueIncElectron,weight);
587 //printf(Form("Inclusive Pool: TrackNr. %d, fnumberfound %d \n", iTrack1, fnumberfound));
589 for(Int_t idex = 0; idex < fCounterPoolBackground; idex++){
590 iTrack2 = fArraytrack->At(idex);
591 AliDebug(2,Form("track %d",iTrack2));
592 track2 = (AliVTrack *)vEvent->GetTrack(iTrack2);
595 //printf("ERROR: Could not receive track %d", iTrack2);
599 fCharge2 = track2->Charge(); //Charge from track2
602 //valueAngle[2] = source;
603 valueSign[4] = source;
604 valueSign[6] = track2->Pt();
605 valueSign[8] = track2->Eta();
607 // track cuts and PID already done
609 // Checking if it is the same Track!
610 if(iTrack2==iTrack1) continue;
611 AliDebug(2,"Different");
614 if(fMCEvent || fAODArrayMCInfo){
615 AliDebug(2, "Checking for source");
616 source2 = FindMother(TMath::Abs(track2->GetLabel()), indexmother2);
617 AliDebug(2, Form("source is %d", source2));
618 pdg2 = CheckPdg(TMath::Abs(track2->GetLabel()));
620 if(source == kElectronfromconversion){
621 AliDebug(2, Form("Electron from conversion (source %d), paired with source %d", source, source2));
622 AliDebug(2, Form("Index of the mothers: incl %d, associated %d", indexmother, indexmother2));
623 AliDebug(2, Form("PDGs: incl %d, associated %d", pdg1, pdg2));
627 if((indexmother2 == indexmother) && (source == source2) && ((pdg1*pdg2)<0.0)){
628 AliDebug(1, "Real pair");
630 case kElectronfromconversion:
631 valueSign[4] = kElectronfromconversionboth;
633 case kElectronfrompi0:
634 valueSign[4] = kElectronfrompi0both;
636 case kElectronfrometa:
637 valueSign[4] = kElectronfrometaboth;
645 // Use TLorentzVector
646 if(!MakePairDCA(track1, track2, vEvent, (aodeventu != NULL), invmass, angle)) continue;
649 if(!MakePairKF(track1, track2, primV, invmass, angle)) continue;
652 valueSign[3] = invmass;
653 valueSign[5] = angle;
655 //if((fCharge1*fCharge2)>0.0) fLSignAngle->Fill(&valueAngle[0],weight);
656 //else fUSignAngle->Fill(&valueAngle[0],weight);
658 if(angle > fMaxOpening3D) continue; //! Cut on Opening Angle
659 if(invmass > fMaxInvMass) continue; //! Cut on Invariant Mass
661 if((fCharge1*fCharge2)>0.0){
662 if(invmass < 1.0) fLSign->Fill( valueSign, weight);
663 // count like-sign background matched pairs per inclusive based on mass cut
664 if(invmass < 0.14) countsMatchLikesign++;
665 AliDebug(1, "Selected Like sign");
667 if(invmass < 1.0)fUSign->Fill( valueSign, weight);
668 // count unlike-sign matched pairs per inclusive based on mass cut
669 if(invmass < 0.14) countsMatchUnlikesign++;
670 AliDebug(1, "Selected Unike sign");
673 if((fCharge1*fCharge2)>0.0) kLSignPhotonic=kTRUE;
674 else kUSignPhotonic=kTRUE;
678 Double_t valCountsLS[3] = {binct, track1->Pt(), countsMatchLikesign},
679 valCountsUS[3] = {binct, track1->Pt(), countsMatchUnlikesign};
680 fUSmatches->Fill(valCountsUS);
681 fLSmatches->Fill(valCountsLS);
683 if( kUSignPhotonic && kLSignPhotonic) taggedphotonic = 6;
684 if(!kUSignPhotonic && kLSignPhotonic) taggedphotonic = 4;
685 if( kUSignPhotonic && !kLSignPhotonic) taggedphotonic = 2;
687 return taggedphotonic;
690 //_________________________________________________________________________
691 Int_t AliHFENonPhotonicElectron::FindMother(Int_t tr, Int_t &indexmother) const {
693 // Find the mother if MC
696 if(!fMCEvent && !fAODArrayMCInfo) return 0;
698 Int_t pdg = CheckPdg(tr);
699 if(TMath::Abs(pdg)!= 11)
705 indexmother = IsMotherGamma(tr);
706 if(indexmother > 0) return kElectronfromconversion;
707 indexmother = IsMotherPi0(tr);
708 if(indexmother > 0) return kElectronfrompi0;
709 indexmother = IsMotherC(tr);
710 if(indexmother > 0) return kElectronfromC;
711 indexmother = IsMotherB(tr);
712 if(indexmother > 0) return kElectronfromB;
713 indexmother = IsMotherEta(tr);
714 if(indexmother > 0) return kElectronfrometa;
716 return kElectronfromother;
719 //________________________________________________________________________________________________
720 Int_t AliHFENonPhotonicElectron::CheckPdg(Int_t tr) const {
723 // Return the pdg of the particle
727 if(tr < 0) return pdgcode;
729 AliMCParticle *mctrackesd = NULL; AliAODMCParticle *mctrackaod = NULL;
731 AliVParticle *mctrack = fMCEvent->GetTrack(tr);
733 if((mctrackesd = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))) pdgcode = mctrackesd->PdgCode();
734 else if((mctrackaod = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))) pdgcode = mctrackaod->GetPdgCode();
736 } else if(fAODArrayMCInfo) {
737 if(tr < fAODArrayMCInfo->GetEntriesFast()){
738 mctrackaod = (AliAODMCParticle *) fAODArrayMCInfo->At(tr);
739 if(mctrackaod) return pdgcode = mctrackaod->GetPdgCode();
746 //_______________________________________________________________________________________________
747 Int_t AliHFENonPhotonicElectron::GetMotherPDG(Int_t tr, Int_t &motherIndex) const {
749 // Returns the mother PDG of the track (return value) and the index of the
752 if(tr < 0) return -1;
755 AliMCParticle *mctrackesd(NULL); AliAODMCParticle *mctrackaod(NULL);
759 AliDebug(2, "Using MC Event");
760 AliVParticle *mctrack = fMCEvent->GetTrack(tr);
762 if((mctrackesd = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))){
764 TParticle *particle = mctrackesd->Particle();
768 motherIndex = particle->GetFirstMother();
769 if(motherIndex >= 0){
770 AliMCParticle *mothertrack = NULL;
771 if((mothertrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(TMath::Abs(motherIndex))))){
772 TParticle * mother = mothertrack->Particle();
773 pdg = mother->GetPdgCode();
777 } else if((mctrackaod = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(TMath::Abs(tr))))){
780 motherIndex = mctrackaod->GetMother();
781 if(motherIndex >= 0){
782 AliAODMCParticle *mothertrack = dynamic_cast<AliAODMCParticle *>(fMCEvent->GetTrack(motherIndex));
783 if(mothertrack) pdg = mothertrack->GetPdgCode();
787 } else if(fAODArrayMCInfo) {
788 AliDebug(2, "Using AOD list");
789 if(tr < fAODArrayMCInfo->GetEntriesFast()){
790 mctrackaod = (AliAODMCParticle *) fAODArrayMCInfo->At(tr);
794 motherIndex = mctrackaod->GetMother();
795 if(motherIndex >= 0 && motherIndex < fAODArrayMCInfo->GetEntriesFast()){
796 AliAODMCParticle *mothertrack = dynamic_cast<AliAODMCParticle *>(fAODArrayMCInfo->At(TMath::Abs(motherIndex)));
797 if(mothertrack) pdg = mothertrack->GetPdgCode();
805 //_______________________________________________________________________________________________
806 Int_t AliHFENonPhotonicElectron::IsMotherGamma(Int_t tr) const {
809 // Return the lab of gamma mother or -1 if not gamma
812 Int_t imother(-1), pdg(-1);
813 pdg = GetMotherPDG(tr, imother);
817 if(TMath::Abs(pdg) == 22){
818 AliDebug(2, "Gamma Mother selected");
821 if(TMath::Abs(pdg) == 11){
822 AliDebug(2, "Mother is electron - look further in hierarchy");
823 return IsMotherGamma(imother);
825 AliDebug(2, "Nothing selected");
828 AliDebug(2, "Not mother");
832 //________________________________________________________________________________________________
833 Int_t AliHFENonPhotonicElectron::IsMotherPi0(Int_t tr) const {
836 // Return the lab of pi0 mother or -1 if not pi0
839 Int_t imother(-1), pdg(-1);
840 pdg = GetMotherPDG(tr, imother);
844 if(TMath::Abs(pdg) == 111){
845 AliDebug(2, "Pi0 Mother selected");
848 if(TMath::Abs(pdg) == 11){
849 AliDebug(2, "Mother is electron - look further in hierarchy");
850 return IsMotherPi0(imother);
852 AliDebug(2, "Nothing selected");
855 AliDebug(2, "Not mother");
858 //________________________________________________________________________________________________
859 Int_t AliHFENonPhotonicElectron::IsMotherC(Int_t tr) const {
862 // Return the lab of signal mother or -1 if not from C
865 Int_t imother(-1), pdg(-1);
866 pdg = GetMotherPDG(tr, imother);
870 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)){
871 AliDebug(2, "Charm Mother selected");
874 if(TMath::Abs(pdg) == 11){
875 AliDebug(2, "Mother is electron - look further in hierarchy");
876 return IsMotherC(imother);
878 AliDebug(2, "Nothing selected");
881 AliDebug(2, "Not mother");
885 //_______________________________________________________________________________________________
886 Int_t AliHFENonPhotonicElectron::IsMotherB(Int_t tr) const {
889 // Return the lab of signal mother or -1 if not B
892 Int_t imother(-1), pdg(-1);
893 pdg = GetMotherPDG(tr, imother);
897 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)){
898 AliDebug(2, "Bottom Mother selected");
901 if(TMath::Abs(pdg) == 11){
902 return IsMotherB(imother);
903 AliDebug(2, "Mother is electron - look further in hierarchy");
905 AliDebug(2, "Nothing selected");
908 AliDebug(2, "Not mother");
912 //_______________________________________________________________________________________________
913 Int_t AliHFENonPhotonicElectron::IsMotherEta(Int_t tr) const {
916 // Return the lab of eta mother or -1 if not eta
919 Int_t imother(-1), pdg(-1);
920 pdg = GetMotherPDG(tr, imother);
924 if(TMath::Abs(pdg) == 221){
925 AliDebug(2, "Eta mother selected");
928 if(TMath::Abs(pdg) == 11){
929 AliDebug(2, "Mother is electron - look further in hierarchy");
930 return IsMotherEta(imother);
932 AliDebug(2, "Nothing selected");
935 AliDebug(2, "Not mother");
939 //_______________________________________________________________________________________________
940 Bool_t AliHFENonPhotonicElectron::MakePairDCA(const AliVTrack *inclusive, const AliVTrack *associated, AliVEvent *vEvent, Bool_t isAOD, Double_t &invMass, Double_t &angle) const {
942 // Make Pairs of electrons using TLorentzVector
944 Double_t eMass = TDatabasePDG::Instance()->GetParticle(11)->Mass(); //Electron mass in GeV
945 Double_t bfield = vEvent->GetMagneticField();
947 AliESDtrack *esdtrack1, *esdtrack2;
949 // call copy constructor for AODs
950 esdtrack1 = new AliESDtrack(inclusive);
951 esdtrack2 = new AliESDtrack(associated);
953 // call copy constructor for ESDs
954 esdtrack1 = new AliESDtrack(*(static_cast<const AliESDtrack *>(inclusive)));
955 esdtrack2 = new AliESDtrack(*(static_cast<const AliESDtrack *>(associated)));
957 if((!esdtrack1) || (!esdtrack2)){
963 Double_t xt1 = 0; //radial position track 1 at the DCA point
964 Double_t xt2 = 0; //radial position track 2 at the DCA point
965 Double_t dca = esdtrack2->GetDCA(esdtrack1,bfield,xt2,xt1); //DCA track1-track2
967 // Apply DCA cut already in the function
973 //Momenta of the track extrapolated to DCA track-track
974 Double_t p1[3] = {0,0,0};
975 Double_t p2[3] = {0,0,0};
976 Bool_t kHasdcaT1 = esdtrack1->GetPxPyPzAt(xt1,bfield,p1); //Track1
977 Bool_t kHasdcaT2 = esdtrack2->GetPxPyPzAt(xt2,bfield,p2); //Track2
978 if(!kHasdcaT1 || !kHasdcaT2) AliWarning("It could be a problem in the extrapolation");
980 TLorentzVector electron1, electron2, mother;
981 electron1.SetXYZM(p1[0], p1[1], p1[2], eMass);
982 electron2.SetXYZM(p2[0], p2[1], p2[2], eMass);
984 mother = electron1 + electron2;
985 invMass = mother.M();
986 angle = TVector2::Phi_0_2pi(electron1.Angle(electron2.Vect()));
993 //_______________________________________________________________________________________________
994 Bool_t AliHFENonPhotonicElectron::MakePairKF(const AliVTrack *inclusive, const AliVTrack *associated, AliKFVertex &primV, Double_t &invMass, Double_t &angle) const {
996 // Make pairs of electrons using the AliKF package
999 //printf("AOD HFE non photonic\n");
1001 Int_t fPDGtrack1 = 11;
1002 if(inclusive->Charge()>0) fPDGtrack1 = -11;
1003 Int_t fPDGtrack2 = 11;
1004 if(associated->Charge()>0) fPDGtrack2 = -11;
1006 AliKFParticle ktrack1(*inclusive, fPDGtrack1);
1007 AliKFParticle ktrack2(*associated, fPDGtrack2);
1008 AliKFParticle recoGamma(ktrack1,ktrack2);
1010 if(recoGamma.GetNDF()<1) return kFALSE; //! Cut on Reconstruction
1012 Double_t chi2OverNDF = recoGamma.GetChi2()/recoGamma.GetNDF();
1013 if(TMath::Sqrt(TMath::Abs(chi2OverNDF))>fChi2OverNDFCut) return kFALSE;
1015 if(fSetMassConstraint){
1019 recoGamma.SetProductionVertex(primV);
1020 recoGamma.SetMassConstraint(0,0.0001);
1024 recoGamma.GetMass(invMass,width);
1025 angle = ktrack1.GetAngle(ktrack2);
1029 //_______________________________________________________________________________________________
1030 Bool_t AliHFENonPhotonicElectron::FilterCategory1Track(const AliVTrack * const track, Bool_t isAOD, Int_t binct){
1032 // Selection of good associated tracks for the pool
1033 // selection is done using strong cuts
1034 // Tracking in the TPC and the ITS is a minimal requirement
1036 Bool_t survivedbackground = kTRUE;
1038 if(!fHFEBackgroundCuts->CheckParticleCuts(AliHFEcuts::kStepRecKineITSTPC + AliHFEcuts::kNcutStepsMCTrack, (TObject *) track)) survivedbackground = kFALSE;
1039 AliDebug(3, Form("First cut: %s\n", survivedbackground == kTRUE ? "yes" : "no"));
1040 if(!fHFEBackgroundCuts->CheckParticleCuts(AliHFEcuts::kStepRecPrim + AliHFEcuts::kNcutStepsMCTrack, (TObject *) track)) survivedbackground = kFALSE;
1041 AliDebug(3, Form("Second cut: %s\n", survivedbackground == kTRUE ? "yes" : "no"));
1043 if(survivedbackground){
1045 AliHFEpidObject hfetrack2;
1047 if(!isAOD) hfetrack2.SetAnalysisType(AliHFEpidObject::kESDanalysis);
1048 else hfetrack2.SetAnalysisType(AliHFEpidObject::kAODanalysis);
1050 hfetrack2.SetRecTrack(track);
1052 hfetrack2.SetCentrality((Int_t)binct);
1053 AliDebug(3,Form("centrality %d and %d",binct,hfetrack2.GetCentrality()));
1054 hfetrack2.SetPbPb();
1057 if(fPIDBackground->IsSelected(&hfetrack2,0x0,"recTrackCont",fPIDBackgroundQA)){
1058 survivedbackground = kTRUE;
1059 } else survivedbackground = kFALSE;
1061 AliDebug(3, Form("PID: %s\n", survivedbackground == kTRUE ? "yes" : "no"));
1062 return survivedbackground;
1065 //_______________________________________________________________________________________________
1066 Bool_t AliHFENonPhotonicElectron::FilterCategory2Track(const AliVTrack * const track, Bool_t isAOD){
1068 // Selection of category 2 tracks: These tracks are exclusively low pt tracks below
1069 // 300 MeV/c which have at least 2 hits in the 4 outer ITS layers and are identified as
1070 // electron candidates by the ITS
1072 if(TMath::Abs(track->Pt()) > 0.3) return kFALSE;
1073 Int_t nclustersITS(0), nclustersOuter(0);
1075 const AliAODTrack *aodtrack = static_cast<const AliAODTrack *>(track);
1076 if(!(aodtrack->TestFilterBit(AliAODTrack::kTrkGlobalNoDCA) || aodtrack->TestFilterBit(AliAODTrack::kTrkITSsa))) return kFALSE;
1077 nclustersITS = aodtrack->GetITSNcls();
1078 for(int ily = 2; ily < 5; ily++)
1079 if(aodtrack->HasPointOnITSLayer(ily)) nclustersOuter++;
1081 const AliESDtrack *esdtrack = static_cast<const AliESDtrack *>(track);
1082 if(esdtrack->GetStatus() & AliESDtrack::kITSpureSA) return kFALSE;
1083 nclustersITS = esdtrack->GetITSclusters(NULL);
1084 for(int ily = 2; ily < 5; ily++)
1085 if(esdtrack->HasPointOnITSLayer(ily)) nclustersOuter++;
1087 if(nclustersITS < 4) return kFALSE;
1088 if(nclustersOuter < 3) return kFALSE;
1091 Double_t nsigmaITS = fPIDBackground->GetPIDResponse()->NumberOfSigmasITS(track, AliPID::kElectron);
1092 fHnsigmaITS->Fill(track->Pt(), nsigmaITS);
1093 if(TMath::Abs(nsigmaITS - fITSmeanShift) > 3.) return kFALSE;
1094 // if global track, we apply also TPC PID