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 #include "AliTwoParticlePIDCorr.h"
17 #include "AliVParticle.h"
29 #include "AliCentrality.h"
30 #include "Riostream.h"
33 #include "AliCFContainer.h"
35 #include "THnSparse.h"
39 #include "AliESDpid.h"
40 #include "AliAODpidUtil.h"
41 #include <AliPIDResponse.h>
43 #include <AliAnalysisManager.h>
44 #include <AliInputEventHandler.h>
45 #include "AliAODInputHandler.h"
47 #include "AliAnalysisTaskSE.h"
48 #include "AliAnalysisManager.h"
49 #include "AliCentrality.h"
51 #include "AliVEvent.h"
52 #include "AliAODEvent.h"
53 #include "AliAODTrack.h"
54 #include "AliVTrack.h"
56 #include "THnSparse.h"
58 #include "AliAODMCHeader.h"
59 #include "AliAODMCParticle.h"
60 #include "AliMCEventHandler.h"
61 #include "AliMCEvent.h"
62 #include "AliMCParticle.h"
63 #include "TParticle.h"
64 #include <TDatabasePDG.h>
65 #include <TParticlePDG.h>
67 #include "AliGenCocktailEventHeader.h"
68 #include "AliGenEventHeader.h"
70 #include "AliEventPoolManager.h"
71 //#include "AliAnalysisUtils.h"
72 using namespace AliPIDNameSpace;
75 ClassImp(AliTwoParticlePIDCorr)
76 ClassImp(LRCParticlePID)
78 const char * kPIDTypeName[]={"TPC","TOF","TPC-TOF"} ;
79 const char * kDetectorName[]={"ITS","TPC","TOF"} ;
80 const char * kParticleSpeciesName[]={"Pions","Kaons","Protons","Undefined"} ;
82 //________________________________________________________________________
83 AliTwoParticlePIDCorr::AliTwoParticlePIDCorr() // All data members should be initialised here
86 fCentralityMethod("V0A"),
88 fnTracksVertex(1), // QA tracks pointing to principal vertex (= 3 default)
92 fSharedClusterCut(-1),
95 ffilltrigassoUNID(kFALSE),
96 ffilltrigUNIDassoID(kFALSE),
97 ffilltrigIDassoUNID(kTRUE),
98 ffilltrigIDassoID(kFALSE),
99 ffilltrigIDassoIDMCTRUTH(kFALSE),
100 fMaxNofMixingTracks(50000),
101 fPtOrderMCTruth(kFALSE),
102 fTriggerSpeciesSelection(kFALSE),
103 fAssociatedSpeciesSelection(kFALSE),
104 fTriggerSpecies(SpPion),
105 fAssociatedSpecies(SpPion),
108 fSelectHighestPtTrig(kFALSE),
109 fcontainPIDtrig(kTRUE),
110 fcontainPIDasso(kFALSE),
111 //frejectPileUp(kFALSE),
116 fminprotonsigmacut(-6.0),
117 fmaxprotonsigmacut(-3.0),
118 fminpionsigmacut(0.0),
119 fmaxpionsigmacut(4.0),
120 fselectprimaryTruth(kTRUE),
121 fonlyprimarydatareco(kFALSE),
124 ffillhistQAReco(kFALSE),
125 ffillhistQATruth(kFALSE),
126 kTrackVariablesPair(0),
155 fCentralityCorrelation(0x0),
170 fCorrelatonTruthPrimary(0),
171 fCorrelatonTruthPrimarymix(0),
177 fTHnCorrIDUNIDmix(0),
179 fTHnTrigcountMCTruthPrim(0),
182 fAnalysisType("AOD"),
184 twoTrackEfficiencyCutValue(0.02),
185 //fControlConvResoncances(0),
190 fRequestTOFPID(kTRUE),
191 fPIDType(NSigmaTPCTOF),
192 fFIllPIDQAHistos(kTRUE),
194 fUseExclusiveNSigma(kFALSE),
195 fRemoveTracksT0Fill(kFALSE),
197 fTriggerSelectCharge(0),
198 fAssociatedSelectCharge(0),
199 fTriggerRestrictEta(-1),
200 fEtaOrdering(kFALSE),
201 fCutConversions(kFALSE),
202 fCutResonances(kFALSE),
203 fRejectResonanceDaughters(-1),
205 fInjectedSignals(kFALSE),
206 fRemoveWeakDecays(kFALSE),
207 fRemoveDuplicates(kFALSE),
208 fapplyTrigefficiency(kFALSE),
209 fapplyAssoefficiency(kFALSE),
210 ffillefficiency(kFALSE),
211 fmesoneffrequired(kFALSE),
212 fkaonprotoneffrequired(kFALSE),
213 //fAnalysisUtils(0x0),
217 for ( Int_t i = 0; i < 16; i++) {
221 for ( Int_t i = 0; i < 6; i++ ){
222 fTHnrecomatchedallPid[i] = NULL;
223 fTHngenprimPidTruth[i] = NULL;
224 effcorection[i]=NULL;
229 for(Int_t ipart=0;ipart<NSpecies;ipart++)
230 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++)
231 fnsigmas[ipart][ipid]=999.;
233 for(Int_t ipart=0;ipart<NSpecies;ipart++) {fHasDoubleCounting[ipart]=kFALSE;}
236 //________________________________________________________________________
237 AliTwoParticlePIDCorr::AliTwoParticlePIDCorr(const char *name) // All data members should be initialised here
238 :AliAnalysisTaskSE(name),
240 fCentralityMethod("V0A"),
242 fnTracksVertex(1), // QA tracks pointing to principal vertex (= 3 default)
246 fSharedClusterCut(-1),
249 ffilltrigassoUNID(kFALSE),
250 ffilltrigUNIDassoID(kFALSE),
251 ffilltrigIDassoUNID(kTRUE),
252 ffilltrigIDassoID(kFALSE),
253 ffilltrigIDassoIDMCTRUTH(kFALSE),
254 fMaxNofMixingTracks(50000),
255 fPtOrderMCTruth(kFALSE),
256 fTriggerSpeciesSelection(kFALSE),
257 fAssociatedSpeciesSelection(kFALSE),
258 fTriggerSpecies(SpPion),
259 fAssociatedSpecies(SpPion),
262 fSelectHighestPtTrig(kFALSE),
263 fcontainPIDtrig(kTRUE),
264 fcontainPIDasso(kFALSE),
265 // frejectPileUp(kFALSE),
270 fminprotonsigmacut(-6.0),
271 fmaxprotonsigmacut(-3.0),
272 fminpionsigmacut(0.0),
273 fmaxpionsigmacut(4.0),
274 fselectprimaryTruth(kTRUE),
275 fonlyprimarydatareco(kFALSE),
278 ffillhistQAReco(kFALSE),
279 ffillhistQATruth(kFALSE),
280 kTrackVariablesPair(0),
309 fCentralityCorrelation(0x0),
324 fCorrelatonTruthPrimary(0),
325 fCorrelatonTruthPrimarymix(0),
331 fTHnCorrIDUNIDmix(0),
333 fTHnTrigcountMCTruthPrim(0),
336 fAnalysisType("AOD"),
338 twoTrackEfficiencyCutValue(0.02),
339 //fControlConvResoncances(0),
344 fRequestTOFPID(kTRUE),
345 fPIDType(NSigmaTPCTOF),
346 fFIllPIDQAHistos(kTRUE),
348 fUseExclusiveNSigma(kFALSE),
349 fRemoveTracksT0Fill(kFALSE),
351 fTriggerSelectCharge(0),
352 fAssociatedSelectCharge(0),
353 fTriggerRestrictEta(-1),
354 fEtaOrdering(kFALSE),
355 fCutConversions(kFALSE),
356 fCutResonances(kFALSE),
357 fRejectResonanceDaughters(-1),
359 fInjectedSignals(kFALSE),
360 fRemoveWeakDecays(kFALSE),
361 fRemoveDuplicates(kFALSE),
362 fapplyTrigefficiency(kFALSE),
363 fapplyAssoefficiency(kFALSE),
364 ffillefficiency(kFALSE),
365 fmesoneffrequired(kFALSE),
366 fkaonprotoneffrequired(kFALSE),
367 //fAnalysisUtils(0x0),
371 for ( Int_t i = 0; i < 16; i++) {
375 for ( Int_t i = 0; i < 6; i++ ){
376 fTHnrecomatchedallPid[i] = NULL;
377 fTHngenprimPidTruth[i] = NULL;
378 effcorection[i]=NULL;
383 for(Int_t ipart=0;ipart<NSpecies;ipart++)
384 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++)
385 fnsigmas[ipart][ipid]=999.;
387 for(Int_t ipart=0;ipart<NSpecies;ipart++) {fHasDoubleCounting[ipart]=kFALSE;}
389 // The last in the above list should not have a comma after it
392 // Define input and output slots here (never in the dummy constructor)
393 // Input slot #0 works with a TChain - it is connected to the default input container
394 // Output slot #1 writes into a TH1 container
396 DefineOutput(1, TList::Class()); // for output list
397 DefineOutput(2, TList::Class());
401 //________________________________________________________________________
402 AliTwoParticlePIDCorr::~AliTwoParticlePIDCorr()
404 // Destructor. Clean-up the output list, but not the histograms that are put inside
405 // (the list is owner and will clean-up these histograms). Protect in PROOF case.
406 if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
411 if (fOutputList && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
416 if (fPID) delete fPID;
419 //________________________________________________________________________
421 //////////////////////////////////////////////////////////////////////////////////////////////////
423 TH2F* AliTwoParticlePIDCorr::GetHistogram2D(const char * name){
424 // returns histo named name
425 return (TH2F*) fOutputList->FindObject(name);
428 //////////////////////////////////////////////////////////////////////////////////////////////////
430 Float_t AliTwoParticlePIDCorr::PhiRange(Float_t DPhi)
434 // Puts the argument in the range [-pi/2,3 pi/2].
437 if (DPhi < -TMath::Pi()/2) DPhi += 2*TMath::Pi();
438 if (DPhi > 3*TMath::Pi()/2) DPhi -= 2*TMath::Pi();
443 //________________________________________________________________________
444 void AliTwoParticlePIDCorr::UserCreateOutputObjects()
447 // Called once (on the worker node)
448 AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
449 AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
450 fPID = inputHandler->GetPIDResponse();
452 //AliAnalysisUtils *fUtils = new AliAnalysisUtils();
454 //get the efficiency correction map
456 // global switch disabling the reference
457 // (to avoid "Replacing existing TH1" if several wagons are created in train)
458 Bool_t oldStatus = TH1::AddDirectoryStatus();
459 TH1::AddDirectory(kFALSE);
461 fOutput = new TList();
462 fOutput->SetOwner(); // IMPORTANT!
464 fOutputList = new TList;
465 fOutputList->SetOwner();
466 fOutputList->SetName("PIDQAList");
469 Int_t centmultbins=10;
470 Double_t centmultmin=0.0;
471 Double_t centmultmax=100.0;
472 if(fSampleType=="pPb" || fSampleType=="PbPb")
478 if(fSampleType=="pp")
485 fhistcentrality=new TH1F("fhistcentrality","fhistcentrality",centmultbins*4,centmultmin,centmultmax);
486 fOutput->Add(fhistcentrality);
488 fEventCounter = new TH1F("fEventCounter","EventCounter", 10, 0.5,10.5);
489 fEventCounter->GetXaxis()->SetBinLabel(1,"Event Accesed");
490 fEventCounter->GetXaxis()->SetBinLabel(2,"Have a vertex");
491 fEventCounter->GetXaxis()->SetBinLabel(5,"After vertex Cut");
492 fEventCounter->GetXaxis()->SetBinLabel(6,"Within 0-100% centrality");
493 fEventCounter->GetXaxis()->SetBinLabel(7,"Event Analyzed");
494 //fEventCounter->GetXaxis()->SetBinLabel(8,"Event Analysis finished");
495 fOutput->Add(fEventCounter);
497 fEtaSpectrasso=new TH2F("fEtaSpectraasso","fEtaSpectraasso",180,-0.9,0.9,100,0.,20. );
498 fOutput->Add(fEtaSpectrasso);
500 fphiSpectraasso=new TH2F("fphiSpectraasso","fphiSpectraasso",72,0,2*TMath::Pi(),100,0.,20.);
501 fOutput->Add(fphiSpectraasso);
503 if(fSampleType=="pPb" || fSampleType=="PbPb"){ fCentralityCorrelation = new TH2D("fCentralityCorrelation", ";centrality;multiplicity", 101, 0, 101, 20000, 0,40000);
504 fOutput->Add(fCentralityCorrelation);
507 fHistoTPCdEdx = new TH2F("hHistoTPCdEdx", ";p_{T} (GeV/c);dE/dx (au.)",200,0.0,10.0,500, 0., 500.);
508 fOutputList->Add(fHistoTPCdEdx);
509 fHistoTOFbeta = new TH2F(Form("hHistoTOFbeta"), ";p_{T} (GeV/c);v/c",100, 0., fmaxPt, 500, 0.1, 1.1);
510 fOutputList->Add(fHistoTOFbeta);
512 fTPCTOFPion3d=new TH3F ("fTPCTOFpion3d", "fTPCTOFpion3d",100,0., 10., 120,-60.,60.,120,-60.,60);
513 fOutputList->Add(fTPCTOFPion3d);
515 fTPCTOFKaon3d=new TH3F ("fTPCTOFKaon3d", "fTPCTOFKaon3d",100,0., 10., 120,-60.,60.,120,-60.,60);
516 fOutputList->Add(fTPCTOFKaon3d);
518 fTPCTOFProton3d=new TH3F ("fTPCTOFProton3d", "fTPCTOFProton3d",100,0., 10., 120,-60.,60.,120,-60.,60);
519 fOutputList->Add(fTPCTOFProton3d);
523 fPionPt = new TH1F("fHistQAPionPt","p_{T} distribution",200,0.,10.);
524 fOutputList->Add(fPionPt);
525 fPionEta= new TH1F("fHistQAPionEta","#eta distribution",360,-1.8,1.8);
526 fOutputList->Add(fPionEta);
527 fPionPhi = new TH1F("fHistQAPionPhi","#phi distribution",340,0,6.8);
528 fOutputList->Add(fPionPhi);
530 fKaonPt = new TH1F("fHistQAKaonPt","p_{T} distribution",200,0.,10.);
531 fOutputList->Add(fKaonPt);
532 fKaonEta= new TH1F("fHistQAKaonEta","#eta distribution",360,-1.8,1.8);
533 fOutputList->Add(fKaonEta);
534 fKaonPhi = new TH1F("fHistQAKaonPhi","#phi distribution",340,0,6.8);
535 fOutputList->Add(fKaonPhi);
537 fProtonPt = new TH1F("fHistQAProtonPt","p_{T} distribution",200,0.,10.);
538 fOutputList->Add(fProtonPt);
539 fProtonEta= new TH1F("fHistQAProtonEta","#eta distribution",360,-1.8,1.8);
540 fOutputList->Add(fProtonEta);
541 fProtonPhi= new TH1F("fHistQAProtonPhi","#phi distribution",340,0,6.8);
542 fOutputList->Add(fProtonPhi);
545 fHistQA[0] = new TH1F("fHistQAvx", "Histo Vx All ", 50, -5., 5.);
546 fHistQA[1] = new TH1F("fHistQAvy", "Histo Vy All", 50, -5., 5.);
547 fHistQA[2] = new TH1F("fHistQAvz", "Histo Vz All", 50, -25., 25.);
548 fHistQA[3] = new TH1F("fHistQAvxA", "Histo Vx After Cut ", 50, -5., 5.);
549 fHistQA[4] = new TH1F("fHistQAvyA", "Histo Vy After Cut", 50, -5., 5.);
550 fHistQA[5] = new TH1F("fHistQAvzA", "Histo Vz After Cut", 50, -25., 25.);
551 fHistQA[6] = new TH1F("fHistQADcaXyC", "Histo DCAxy after cut", 50, -5., 5.);
552 fHistQA[7] = new TH1F("fHistQADcaZC", "Histo DCAz after cut", 50, -5., 5.);
553 fHistQA[8] = new TH1F("fHistQAPt","p_{T} distribution",200,0.,10.);
554 fHistQA[9] = new TH1F("fHistQAEta","#eta distribution",360,-1.8,1.8);
555 fHistQA[10] = new TH1F("fHistQAPhi","#phi distribution",340,0,6.8);
556 fHistQA[11] = new TH1F("fHistQANCls","Number of TPC cluster",200,0,200);
557 fHistQA[13] = new TH1F("fHistQAChi2","Chi2 per NDF",100,0,10);
558 fHistQA[12] = new TH1F("fHistQANCls1","Number of TPC cluster1",200,0,200);
559 fHistQA[14] = new TH1F("nCrossedRowsTPC","Number of TPC ccrossed rows",200,0,200);
560 fHistQA[15] = new TH1F("ratioCrossedRowsOverFindableClustersTPC","Number of TPC ccrossed rows find clusters",200,0,2);
562 for(Int_t i = 0; i < 16; i++)
564 fOutput->Add(fHistQA[i]);
567 kTrackVariablesPair=6 ;
569 if(fcontainPIDtrig && !fcontainPIDasso) kTrackVariablesPair=7;
571 if(!fcontainPIDtrig && fcontainPIDasso) kTrackVariablesPair=7;
573 if(fcontainPIDtrig && fcontainPIDasso) kTrackVariablesPair=8;
576 // two particle histograms
577 Int_t anaSteps = 1; // analysis steps
578 const char* title = "d^{2}N_{ch}/d#varphid#eta";
580 Int_t iBinPair[kTrackVariablesPair]; // binning for track variables
581 Double_t* dBinsPair[kTrackVariablesPair]; // bins for track variables
582 TString* axisTitlePair; // axis titles for track variables
583 axisTitlePair=new TString[kTrackVariablesPair];
585 TString defaultBinningStr;
586 defaultBinningStr = "eta: -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\n"
587 "p_t_assoc: 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 8.0,10.0\n"
588 "p_t_leading_course: 0.5, 1.0, 2.0, 3.0, 4.0, 6.0, 8.0,10.0\n"
589 "p_t_eff:0.0,0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0,5.5, 6.0, 7.0, 8.0,9.0,10.0\n"
590 "vertex: -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10\n"
591 "delta_phi: -1.570796, -1.483530, -1.396263, -1.308997, -1.221730, -1.134464, -1.047198, -0.959931, -0.872665, -0.785398, -0.698132, -0.610865, -0.523599, -0.436332, -0.349066, -0.261799, -0.174533, -0.087266, 0.0, 0.087266, 0.174533, 0.261799, 0.349066, 0.436332, 0.523599, 0.610865, 0.698132, 0.785398, 0.872665, 0.959931, 1.047198, 1.134464, 1.221730, 1.308997, 1.396263, 1.483530, 1.570796, 1.658063, 1.745329, 1.832596, 1.919862, 2.007129, 2.094395, 2.181662, 2.268928, 2.356194, 2.443461, 2.530727, 2.617994, 2.705260, 2.792527, 2.879793, 2.967060, 3.054326, 3.141593, 3.228859, 3.316126, 3.403392, 3.490659, 3.577925, 3.665191, 3.752458, 3.839724, 3.926991, 4.014257, 4.101524, 4.188790, 4.276057, 4.363323, 4.450590, 4.537856, 4.625123, 4.712389\n" // this binning starts at -pi/2 and is modulo 3
592 "delta_eta: -2.4, -2.3, -2.2, -2.1, -2.0, -1.9, -1.8, -1.7, -1.6, -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, 1.6, 1.7, 1.8, 1.9, 2.0,2.1, 2.2, 2.3, 2.4\n"
593 "multiplicity: 0, 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.1\n";
596 defaultBinningStr += "PIDTrig: -0.5,0.5,1.5,2.5,3.5\n"; // course
599 defaultBinningStr += "PIDAsso: -0.5,0.5,1.5,2.5,3.5\n"; // course
601 // =========================================================
602 // Customization (adopted from AliUEHistograms)
603 // =========================================================
605 TObjArray* lines = defaultBinningStr.Tokenize("\n");
606 for (Int_t i=0; i<lines->GetEntriesFast(); i++)
608 TString line(lines->At(i)->GetName());
609 TString tag = line(0, line.Index(":")+1);
610 if (!fCustomBinning.BeginsWith(tag) && !fCustomBinning.Contains(TString("\n") + tag))
611 fBinningString += line + "\n";
613 AliInfo(Form("Using custom binning for %s", tag.Data()));
616 fBinningString += fCustomBinning;
618 AliInfo(Form("Used AliTHn Binning:\n%s",fBinningString.Data()));
620 // =========================================================
622 // =========================================================
624 dBinsPair[0] = GetBinning(fBinningString, "multiplicity", iBinPair[0]);
625 axisTitlePair[0] = " multiplicity";
627 dBinsPair[1] = GetBinning(fBinningString, "vertex", iBinPair[1]);
628 axisTitlePair[1] = "v_{Z} (cm)";
630 dBinsPair[2] = GetBinning(fBinningString, "p_t_leading_course", iBinPair[2]);
631 axisTitlePair[2] = "p_{T,trig.} (GeV/c)";
633 dBinsPair[3] = GetBinning(fBinningString, "p_t_assoc", iBinPair[3]);
634 axisTitlePair[3] = "p_{T,assoc.} (GeV/c)";
636 dBinsPair[4] = GetBinning(fBinningString, "delta_eta", iBinPair[4]);
637 axisTitlePair[4] = "#Delta#eta";
639 dBinsPair[5] = GetBinning(fBinningString, "delta_phi", iBinPair[5]);
640 axisTitlePair[5] = "#Delta#varphi (rad)";
642 if(fcontainPIDtrig && !fcontainPIDasso){
643 dBinsPair[6] = GetBinning(fBinningString, "PIDTrig", iBinPair[6]);
644 axisTitlePair[6] = "PIDTrig";
647 if(!fcontainPIDtrig && fcontainPIDasso){
648 dBinsPair[6] = GetBinning(fBinningString, "PIDAsso", iBinPair[6]);
649 axisTitlePair[6] = "PIDAsso";
652 if(fcontainPIDtrig && fcontainPIDasso){
654 dBinsPair[6] = GetBinning(fBinningString, "PIDTrig", iBinPair[6]);
655 axisTitlePair[6] = "PIDTrig";
657 dBinsPair[7] = GetBinning(fBinningString, "PIDAsso", iBinPair[7]);
658 axisTitlePair[7] = "PIDAsso";
662 Double_t* EtaBin = GetBinning(fBinningString, "eta", nEtaBin);
664 Int_t nPteffbin = -1;
665 Double_t* Pteff = GetBinning(fBinningString, "p_t_eff", nPteffbin);
668 fminPtTrig=dBinsPair[2][0];
669 fmaxPtTrig=dBinsPair[2][iBinPair[2]];
670 fminPtAsso=dBinsPair[3][0];
671 fmaxPtAsso=dBinsPair[3][iBinPair[3]];
673 //fminPtComboeff=fminPtTrig;***then this value will be fixed ,even Setter can't change it's value
674 //fmaxPtComboeff=fmaxPtTrig;
675 //THnSparses for calculation of efficiency
677 if((fAnalysisType =="MCAOD") && ffillefficiency) {
678 const Int_t nDim = 4;// cent zvtx pt eta
679 Int_t fBinsCh[nDim] = {iBinPair[0], iBinPair[1], nPteffbin ,nEtaBin};//**********************change it
680 Double_t fMinCh[nDim] = { dBinsPair[0][0],dBinsPair[1][0], Pteff[0], EtaBin[0] };
681 Double_t fMaxCh[nDim] = { dBinsPair[0][iBinPair[0]], dBinsPair[1][iBinPair[1]], Pteff[nPteffbin], EtaBin[nEtaBin]};
684 for(Int_t jj=0;jj<6;jj++)//PID type binning
686 Histrename="fTHnrecomatchedallPid";Histrename+=jj;
687 fTHnrecomatchedallPid[jj] = new THnSparseF(Histrename.Data(),"cent:zvtx::Pt:eta", nDim, fBinsCh, fMinCh, fMaxCh);
688 fTHnrecomatchedallPid[jj]->Sumw2();
689 fTHnrecomatchedallPid[jj]->GetAxis(0)->Set(iBinPair[0], dBinsPair[0]);
690 fTHnrecomatchedallPid[jj]->GetAxis(0)->SetTitle("Centrality");
691 fTHnrecomatchedallPid[jj]->GetAxis(1)->Set(iBinPair[1],dBinsPair[1]);
692 fTHnrecomatchedallPid[jj]->GetAxis(1)->SetTitle("zvtx");
693 fTHnrecomatchedallPid[jj]->GetAxis(2)->Set(nPteffbin, Pteff);
694 fTHnrecomatchedallPid[jj]->GetAxis(2)->SetTitle("p_{T} (GeV/c)");
695 fTHnrecomatchedallPid[jj]->GetAxis(3)->Set(nEtaBin,EtaBin);
696 fTHnrecomatchedallPid[jj]->GetAxis(3)->SetTitle("#eta");
697 fOutput->Add(fTHnrecomatchedallPid[jj]);
699 Histrename="fTHngenprimPidTruth";Histrename+=jj;
700 fTHngenprimPidTruth[jj] = new THnSparseF(Histrename.Data(),"cent:zvtx::Pt:eta", nDim, fBinsCh, fMinCh, fMaxCh);
701 fTHngenprimPidTruth[jj]->Sumw2();
702 fTHngenprimPidTruth[jj]->GetAxis(0)->Set(iBinPair[0],dBinsPair[0]);
703 fTHngenprimPidTruth[jj]->GetAxis(0)->SetTitle("Centrality");
704 fTHngenprimPidTruth[jj]->GetAxis(1)->Set(iBinPair[1], dBinsPair[1]);
705 fTHngenprimPidTruth[jj]->GetAxis(1)->SetTitle("zvtx");
706 fTHngenprimPidTruth[jj]->GetAxis(2)->Set(nPteffbin, Pteff);
707 fTHngenprimPidTruth[jj]->GetAxis(2)->SetTitle("p_{T} (GeV/c)");
708 fTHngenprimPidTruth[jj]->GetAxis(3)->Set(nEtaBin, EtaBin);
709 fTHngenprimPidTruth[jj]->GetAxis(3)->SetTitle("#eta");
710 fOutput->Add(fTHngenprimPidTruth[jj]);
714 //AliThns for Correlation plots(data & MC)
716 if(ffilltrigassoUNID)
718 fTHnCorrUNID = new AliTHn("fTHnCorrUNID", title, anaSteps, kTrackVariablesPair, iBinPair);
719 for (Int_t j=0; j<kTrackVariablesPair; j++) {
720 fTHnCorrUNID->SetBinLimits(j, dBinsPair[j]);
721 fTHnCorrUNID->SetVarTitle(j, axisTitlePair[j]);
723 fOutput->Add(fTHnCorrUNID);
725 fTHnCorrUNIDmix = new AliTHn("fTHnCorrUNIDmix", title, anaSteps, kTrackVariablesPair, iBinPair);
726 for (Int_t j=0; j<kTrackVariablesPair; j++) {
727 fTHnCorrUNIDmix->SetBinLimits(j, dBinsPair[j]);
728 fTHnCorrUNIDmix->SetVarTitle(j, axisTitlePair[j]);
730 fOutput->Add(fTHnCorrUNIDmix);
733 if(ffilltrigIDassoID)
735 fTHnCorrID = new AliTHn("fTHnCorrID", title, anaSteps, kTrackVariablesPair, iBinPair);
736 for (Int_t j=0; j<kTrackVariablesPair; j++) {
737 fTHnCorrID->SetBinLimits(j, dBinsPair[j]);
738 fTHnCorrID->SetVarTitle(j, axisTitlePair[j]);
740 fOutput->Add(fTHnCorrID);
742 fTHnCorrIDmix = new AliTHn("fTHnCorrIDmix", title, anaSteps, kTrackVariablesPair, iBinPair);
743 for (Int_t j=0; j<kTrackVariablesPair; j++) {
744 fTHnCorrIDmix->SetBinLimits(j, dBinsPair[j]);
745 fTHnCorrIDmix->SetVarTitle(j, axisTitlePair[j]);
747 fOutput->Add(fTHnCorrIDmix);
750 if(ffilltrigUNIDassoID || ffilltrigIDassoUNID)//***********a bit tricky, be careful
752 fTHnCorrIDUNID = new AliTHn("fTHnCorrIDUNID", title, anaSteps, kTrackVariablesPair, iBinPair);
753 for (Int_t j=0; j<kTrackVariablesPair; j++) {
754 fTHnCorrIDUNID->SetBinLimits(j, dBinsPair[j]);
755 fTHnCorrIDUNID->SetVarTitle(j, axisTitlePair[j]);
757 fOutput->Add(fTHnCorrIDUNID);
760 fTHnCorrIDUNIDmix = new AliTHn("fTHnCorrIDUNIDmix", title, anaSteps, kTrackVariablesPair, iBinPair);
761 for (Int_t j=0; j<kTrackVariablesPair; j++) {
762 fTHnCorrIDUNIDmix->SetBinLimits(j, dBinsPair[j]);
763 fTHnCorrIDUNIDmix->SetVarTitle(j, axisTitlePair[j]);
765 fOutput->Add(fTHnCorrIDUNIDmix);
770 //ThnSparse for Correlation plots(truth MC)
771 if((fAnalysisType == "MCAOD") && ffilltrigIDassoIDMCTRUTH) {//remember that in this case uidentified means other than pions, kaons, protons
773 fCorrelatonTruthPrimary = new AliTHn("fCorrelatonTruthPrimary", title, anaSteps, kTrackVariablesPair, iBinPair);
774 for (Int_t j=0; j<kTrackVariablesPair; j++) {
775 fCorrelatonTruthPrimary->SetBinLimits(j, dBinsPair[j]);
776 fCorrelatonTruthPrimary->SetVarTitle(j, axisTitlePair[j]);
778 fOutput->Add(fCorrelatonTruthPrimary);
781 fCorrelatonTruthPrimarymix = new AliTHn("fCorrelatonTruthPrimarymix", title, anaSteps, kTrackVariablesPair, iBinPair);
782 for (Int_t j=0; j<kTrackVariablesPair; j++) {
783 fCorrelatonTruthPrimarymix->SetBinLimits(j, dBinsPair[j]);
784 fCorrelatonTruthPrimarymix->SetVarTitle(j, axisTitlePair[j]);
786 fOutput->Add(fCorrelatonTruthPrimarymix);
789 //binning for trigger no. counting
793 if(fcontainPIDtrig) dims=4;
794 fBinst= new Int_t[dims];
795 for(Int_t i=0; i<3;i++)
797 fBinst[i]=iBinPair[i];
800 fBinst[3]=iBinPair[6];
803 //ThSparse for trigger counting(data & reco MC)
804 if(ffilltrigassoUNID || ffilltrigUNIDassoID || ffilltrigIDassoUNID || ffilltrigIDassoID)
806 fTHnTrigcount = new AliTHn("fTHnTrigcount", "fTHnTrigcount", anaSteps, dims, fBinst);
807 for(Int_t i=0; i<3;i++){
808 fTHnTrigcount->SetBinLimits(i, dBinsPair[i]);
809 fTHnTrigcount->SetVarTitle(i, axisTitlePair[i]);
813 fTHnTrigcount->SetBinLimits(3, dBinsPair[6]);
814 fTHnTrigcount->SetVarTitle(3, axisTitlePair[6]);
816 fOutput->Add(fTHnTrigcount);
819 if((fAnalysisType =="MCAOD") && ffilltrigIDassoIDMCTRUTH) {
820 //AliTHns for trigger counting(truth MC)
821 fTHnTrigcountMCTruthPrim = new AliTHn("fTHnTrigcountMCTruthPrim", "fTHnTrigcountMCTruthPrim", anaSteps, dims, fBinst);
822 for(Int_t i=0; i<3;i++){
823 fTHnTrigcountMCTruthPrim->SetBinLimits(i, dBinsPair[i]);
824 fTHnTrigcountMCTruthPrim->SetVarTitle(i, axisTitlePair[i]);
828 fTHnTrigcountMCTruthPrim->SetBinLimits(3, dBinsPair[6]);
829 fTHnTrigcountMCTruthPrim->SetVarTitle(3, axisTitlePair[6]);
831 fOutput->Add(fTHnTrigcountMCTruthPrim);
834 if(fAnalysisType=="MCAOD"){
837 MCtruthpt=new TH1F ("MCtruthpt","ptdistributiontruthprim",100,0.,10.);
838 fOutputList->Add(MCtruthpt);
840 MCtrutheta=new TH1F ("MCtrutheta","etadistributiontruthprim",360,-1.8,1.8);
841 fOutputList->Add(MCtrutheta);
843 MCtruthphi=new TH1F ("MCtruthphi","phidisttruthprim",340,0,6.8);
844 fOutputList->Add(MCtruthphi);
846 MCtruthpionpt=new TH1F ("MCtruthpionpt","MCtruthpionpt",100,0.,10.);
847 fOutputList->Add(MCtruthpionpt);
849 MCtruthpioneta=new TH1F ("MCtruthpioneta","MCtruthpioneta",360,-1.8,1.8);
850 fOutputList->Add(MCtruthpioneta);
852 MCtruthpionphi=new TH1F ("MCtruthpionphi","MCtruthpionphi",340,0,6.8);
853 fOutputList->Add(MCtruthpionphi);
855 MCtruthkaonpt=new TH1F ("MCtruthkaonpt","MCtruthkaonpt",100,0.,10.);
856 fOutputList->Add(MCtruthkaonpt);
858 MCtruthkaoneta=new TH1F ("MCtruthkaoneta","MCtruthkaoneta",360,-1.8,1.8);
859 fOutputList->Add(MCtruthkaoneta);
861 MCtruthkaonphi=new TH1F ("MCtruthkaonphi","MCtruthkaonphi",340,0,6.8);
862 fOutputList->Add(MCtruthkaonphi);
864 MCtruthprotonpt=new TH1F ("MCtruthprotonpt","MCtruthprotonpt",100,0.,10.);
865 fOutputList->Add(MCtruthprotonpt);
867 MCtruthprotoneta=new TH1F ("MCtruthprotoneta","MCtruthprotoneta",360,-1.8,1.8);
868 fOutputList->Add(MCtruthprotoneta);
870 MCtruthprotonphi=new TH1F ("MCtruthprotonphi","MCtruthprotonphi",340,0,6.8);
871 fOutputList->Add(MCtruthprotonphi);
873 fPioncont=new TH2F("fPioncont", "fPioncont",10,-0.5,9.5,100,0.,10.);
874 fOutputList->Add(fPioncont);
876 fKaoncont=new TH2F("fKaoncont","fKaoncont",10,-0.5,9.5,100,0.,10.);
877 fOutputList->Add(fKaoncont);
879 fProtoncont=new TH2F("fProtoncont","fProtoncont",10,-0.5,9.5,100,0.,10.);
880 fOutputList->Add(fProtoncont);
883 fEventno=new TH2F("fEventno","fEventno",iBinPair[0], dBinsPair[0],iBinPair[1],dBinsPair[1]);
884 fEventno->GetXaxis()->SetTitle("Centrality");
885 fEventno->GetYaxis()->SetTitle("Z_Vtx");
886 fOutput->Add(fEventno);
887 fEventnobaryon=new TH2F("fEventnobaryon","fEventnobaryon",iBinPair[0], dBinsPair[0],iBinPair[1],dBinsPair[1]);
888 fEventnobaryon->GetXaxis()->SetTitle("Centrality");
889 fEventnobaryon->GetYaxis()->SetTitle("Z_Vtx");
890 fOutput->Add(fEventnobaryon);
891 fEventnomeson=new TH2F("fEventnomeson","fEventnomeson",iBinPair[0], dBinsPair[0],iBinPair[1],dBinsPair[1]);
892 fEventnomeson->GetXaxis()->SetTitle("Centrality");
893 fEventnomeson->GetYaxis()->SetTitle("Z_Vtx");
894 fOutput->Add(fEventnomeson);
900 if(fapplyTrigefficiency || fapplyAssoefficiency)
902 const Int_t nDimt = 4;// cent zvtx pt eta
903 Int_t fBinsCht[nDimt] = {iBinPair[0], iBinPair[1], nPteffbin ,nEtaBin};//*************change it
904 Double_t fMinCht[nDimt] = { dBinsPair[0][0],dBinsPair[1][0], Pteff[0], EtaBin[0] };
905 Double_t fMaxCht[nDimt] = {dBinsPair[0][iBinPair[0]], dBinsPair[1][iBinPair[1]], Pteff[nPteffbin], EtaBin[nEtaBin]};
908 for(Int_t jj=0;jj<6;jj++)// PID type binning
910 Histrexname="effcorection";Histrexname+=jj;
911 effcorection[jj] = new THnSparseF(Histrexname.Data(),"cent:zvtx::Pt:eta", nDimt, fBinsCht, fMinCht, fMaxCht);
912 effcorection[jj]->Sumw2();
913 effcorection[jj]->GetAxis(0)->Set(iBinPair[0], dBinsPair[0]);
914 effcorection[jj]->GetAxis(0)->SetTitle("Centrality");
915 effcorection[jj]->GetAxis(1)->Set( iBinPair[1],dBinsPair[1]);
916 effcorection[jj]->GetAxis(1)->SetTitle("zvtx");
917 effcorection[jj]->GetAxis(2)->Set(nPteffbin, Pteff);
918 effcorection[jj]->GetAxis(2)->SetTitle("p_{T} (GeV/c)");
919 effcorection[jj]->GetAxis(3)->Set( nEtaBin,EtaBin);
920 effcorection[jj]->GetAxis(3)->SetTitle("#eta");
921 fOutput->Add(effcorection[jj]);
923 // TFile *fsifile = new TFile(fefffilename,"READ");
925 if (TString(fefffilename).BeginsWith("alien:"))
926 TGrid::Connect("alien:");
927 TFile *fileT=TFile::Open(fefffilename);
929 for(Int_t jj=0;jj<6;jj++)//type binning
931 Nameg="effmap";Nameg+=jj;
932 //effcorection[jj] = (THnSparseF*)fsifile->Get(Nameg.Data());
933 effcorection[jj] = (THnSparseF*)fileT->Get(Nameg.Data());
935 //effcorection[jj]->SetDirectory(0);//****************************not present in case oh THnF
942 //fControlConvResoncances = new TH2F("fControlConvResoncances", ";id;delta mass", 3, -0.5, 2.5, 100, -0.1, 0.1);
943 // fOutput->Add(fControlConvResoncances);
949 //*****************************************************PIDQA histos*****************************************************//
953 for(Int_t ipart=0;ipart<NSpecies;ipart++){
954 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
957 if(ipid==NSigmaTPCTOF){miny=0;maxy=50;}
958 TH2F *fHistoNSigma=new TH2F(Form("NSigma_%d_%d",ipart,ipid),Form("n#sigma %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]),200,0,10,500,miny,maxy);
959 fHistoNSigma->GetXaxis()->SetTitle("P_{T} (GeV / c)");
960 fHistoNSigma->GetYaxis()->SetTitle(Form("n#sigma %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]));
961 fOutputList->Add(fHistoNSigma);
966 for(Int_t ipart=0;ipart<NSpecies;ipart++){
967 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
970 if(ipid==NSigmaTPCTOF){miny=0;maxy=20;}
971 TH2F *fHistoNSigma=new TH2F(Form("NSigmaRec_%d_%d",ipart,ipid),
972 Form("n#sigma for reconstructed %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]),200,0,10,500,miny,maxy);
973 fHistoNSigma->GetXaxis()->SetTitle("P_{T} (GeV / c)");
974 fHistoNSigma->GetYaxis()->SetTitle(Form("n#sigma %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]));
975 fOutputList->Add(fHistoNSigma);
980 if(fUseExclusiveNSigma) {
981 for(Int_t ipart=0;ipart<NSpecies;ipart++){
982 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
985 if(ipid==NSigmaTPCTOF){miny=0;maxy=20;}
986 TH2F *fHistoNSigma=new TH2F(Form("NSigmaDC_%d_%d",ipart,ipid),
987 Form("n#sigma for double counting %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]),200,0,10,500,miny,maxy);
988 fHistoNSigma->GetXaxis()->SetTitle("P_{T} (GeV / c)");
989 fHistoNSigma->GetYaxis()->SetTitle(Form("n#sigma %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]));
990 fOutputList->Add(fHistoNSigma);
995 if (fAnalysisType == "MCAOD"){
996 for(Int_t ipart=0;ipart<NSpecies;ipart++){
997 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
1000 if(ipid==NSigmaTPCTOF){miny=0;maxy=50;}
1001 TH2F *fHistoNSigma=new TH2F(Form("NSigmaMC_%d_%d",ipart,ipid),
1002 Form("n#sigma for MC %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]),200,0,10,500,miny,maxy);
1003 fHistoNSigma->GetXaxis()->SetTitle("P_{T} (GeV / c)");
1004 fHistoNSigma->GetYaxis()->SetTitle(Form("n#sigma %s %s",kParticleSpeciesName[ipart],kPIDTypeName[ipid]));
1005 fOutputList->Add(fHistoNSigma);
1010 for(Int_t idet=0;idet<fNDetectors;idet++){
1011 for(Int_t ipart=0;ipart<NSpecies;ipart++){
1013 if(idet==fTOF)maxy=1.1;
1014 TH2F *fHistoPID=new TH2F(Form("PID_%d_%d",idet,ipart),Form("%s signal - %s",kDetectorName[idet],kParticleSpeciesName[ipart]),200,0,10,500,-maxy,maxy);
1015 fHistoPID->GetXaxis()->SetTitle("P (GeV / c)");
1016 fHistoPID->GetYaxis()->SetTitle(Form("%s signal",kDetectorName[idet]));
1017 fOutputList->Add(fHistoPID);
1020 //PID signal plot, before PID cut
1021 for(Int_t idet=0;idet<fNDetectors;idet++){
1023 if(idet==fTOF)maxy=1.1;
1024 TH2F *fHistoPID=new TH2F(Form("PIDAll_%d",idet),Form("%s signal",kDetectorName[idet]),200,0,10,500,-maxy,maxy);
1025 fHistoPID->GetXaxis()->SetTitle("P (GeV / c)");
1026 fHistoPID->GetYaxis()->SetTitle(Form("%s signal",kDetectorName[idet]));
1027 fOutputList->Add(fHistoPID);
1030 PostData(1, fOutput); // Post data for ALL output slots >0 here, to get at least an empty histogram
1031 PostData(2, fOutputList);
1033 AliInfo("Finished setting up the Output");
1035 TH1::AddDirectory(oldStatus);
1040 //-------------------------------------------------------------------------------
1041 void AliTwoParticlePIDCorr::UserExec( Option_t * ){
1044 if(fAnalysisType == "AOD") {
1048 }//AOD--analysis-----
1050 else if(fAnalysisType == "MCAOD") {
1059 //-------------------------------------------------------------------------
1060 void AliTwoParticlePIDCorr::doMCAODevent()
1062 AliVEvent *event = InputEvent();
1063 if (!event) { Printf("ERROR: Could not retrieve event"); return; }
1064 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(event);
1066 AliError("Cannot get the AOD event");
1070 // count all events(physics triggered)
1071 fEventCounter->Fill(1);
1073 // get centrality object and check quality(valid for p-Pb and Pb-Pb)
1074 Double_t cent_v0=0.0;
1076 if(fSampleType=="pPb" || fSampleType=="PbPb")
1078 AliCentrality *centrality=0;
1080 centrality = aod->GetHeader()->GetCentralityP();
1081 // if (centrality->GetQuality() != 0) return ;
1085 cent_v0 = centrality->GetCentralityPercentile(fCentralityMethod);
1093 //check the PIDResponse handler
1096 // get mag. field required for twotrack efficiency cut
1098 bSign = (aod->GetMagneticField() > 0) ? 1 : -1;
1100 //check for TClonesArray(truth track MC information)
1101 fArrayMC = dynamic_cast<TClonesArray*>(aod->FindListObject(AliAODMCParticle::StdBranchName()));
1103 AliFatal("Error: MC particles branch not found!\n");
1107 //check for AliAODMCHeader(truth event MC information)
1108 AliAODMCHeader *header=NULL;
1109 header=(AliAODMCHeader*)aod->GetList()->FindObject(AliAODMCHeader::StdBranchName());
1111 printf("MC header branch not found!\n");
1115 //Only consider MC events within the vtx-z region used also as cut on the reconstructed vertex
1116 Float_t zVtxmc =header->GetVtxZ();
1117 if(TMath::Abs(zVtxmc)>fzvtxcut) return;
1119 // For productions with injected signals, figure out above which label to skip particles/tracks
1120 Int_t skipParticlesAbove = 0;
1122 if (fInjectedSignals)
1124 AliGenEventHeader* eventHeader = 0;
1129 AliFatal("fInjectedSignals set but no MC header found");
1131 headers = header->GetNCocktailHeaders();
1132 eventHeader = header->GetCocktailHeader(0);
1136 // We avoid AliFatal here, because the AOD productions sometimes have events where the MC header is missing
1137 // (due to unreadable Kinematics) and we don't want to loose the whole job because of a few events
1138 AliError("First event header not found. Skipping this event.");
1139 //fHistos->FillEvent(centrality, AliUEHist::kCFStepAnaTopology);
1142 skipParticlesAbove = eventHeader->NProduced();
1143 AliInfo(Form("Injected signals in this event (%d headers). Keeping events of %s. Will skip particles/tracks above %d.", headers, eventHeader->ClassName(), skipParticlesAbove));
1146 //vertex selection(is it fine for PP?)
1147 if ( fVertextype==1){
1148 trkVtx = aod->GetPrimaryVertex();
1149 if (!trkVtx || trkVtx->GetNContributors()<=0) return;
1150 TString vtxTtl = trkVtx->GetTitle();
1151 if (!vtxTtl.Contains("VertexerTracks")) return;
1152 zvtx = trkVtx->GetZ();
1153 const AliAODVertex* spdVtx = aod->GetPrimaryVertexSPD();
1154 if (!spdVtx || spdVtx->GetNContributors()<=0) return;
1155 TString vtxTyp = spdVtx->GetTitle();
1156 Double_t cov[6]={0};
1157 spdVtx->GetCovarianceMatrix(cov);
1158 Double_t zRes = TMath::Sqrt(cov[5]);
1159 if (vtxTyp.Contains("vertexer:Z") && (zRes>0.25)) return;
1160 if (TMath::Abs(spdVtx->GetZ() - trkVtx->GetZ())>0.5) return;
1162 else if(fVertextype==2) {//for pp and pb-pb case
1163 Int_t nVertex = aod->GetNumberOfVertices();
1165 trkVtx = aod->GetPrimaryVertex();
1166 Int_t nTracksPrim = trkVtx->GetNContributors();
1167 zvtx = trkVtx->GetZ();
1168 //if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
1169 // Reject TPC only vertex
1170 TString name(trkVtx->GetName());
1171 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return;
1173 // Select a quality vertex by number of tracks?
1174 if( nTracksPrim < fnTracksVertex ) {
1175 //if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
1178 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
1179 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
1181 // if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
1186 else if(fVertextype==0){//default case
1187 trkVtx = aod->GetPrimaryVertex();
1188 if (!trkVtx || trkVtx->GetNContributors()<=0) return;//proper number of contributors
1189 zvtx = trkVtx->GetZ();
1191 trkVtx->GetCovarianceMatrix(fCov);
1192 if(fCov[5] == 0) return;//proper vertex resolution
1195 AliInfo("Wrong Vertextype set for Primary-vertex Selection: event REJECTED ...");
1196 return;//as there is no proper sample type
1200 fHistQA[0]->Fill((trkVtx->GetX()));fHistQA[1]->Fill((trkVtx->GetY()));fHistQA[2]->Fill((trkVtx->GetZ())); //for trkVtx only before vertex cut |zvtx|<10 cm
1202 //count events having a proper vertex
1203 fEventCounter->Fill(2);
1205 if (TMath::Abs(zvtx) > fzvtxcut) return;
1207 fHistQA[3]->Fill((trkVtx->GetX()));fHistQA[4]->Fill((trkVtx->GetY()));fHistQA[5]->Fill((trkVtx->GetZ()));//after vertex cut for trkVtx only
1209 //now we have events passed physics trigger, centrality,eventzvtx cut
1211 //count events after vertex cut
1212 fEventCounter->Fill(5);
1214 if(!aod) return; //for safety
1216 if (fSampleType=="pPb" || fSampleType=="PbPb") if (cent_v0 < 0) return;//for pp case it is the multiplicity
1218 Double_t nooftrackstruth=0.0;//in case of pp this will give the multiplicity(for truth case) after the track loop(only for unidentified particles that pass kinematic cuts)
1220 Double_t cent_v0_truth=0.0;
1222 //TObjArray* tracksMCtruth=0;
1223 TObjArray* tracksMCtruth=new TObjArray;//for truth MC particles with PID,here unidentified means any particle other than pion, kaon or proton(Basicaly Spundefined of AliHelperPID)******WARNING::different from data and reco MC
1224 tracksMCtruth->SetOwner(kTRUE); //***********************************IMPORTANT!
1228 //There is a small difference between zvtx and zVtxmc??????
1229 //cout<<"***********************************************zVtxmc="<<zVtxmc<<endl;
1230 //cout<<"***********************************************zvtx="<<zvtx<<endl;
1232 //now process the truth particles(for both efficiency & correlation function)
1233 Int_t nMCTrack = fArrayMC->GetEntriesFast();
1235 for (Int_t iMC = 0; iMC < nMCTrack; iMC++)
1236 { //MC truth track loop starts
1238 AliAODMCParticle *partMC = (AliAODMCParticle*) fArrayMC->At(iMC);
1241 AliError(Form("ERROR: Could not retrieve AODMCtrack %d",iMC));
1245 //consider only charged particles
1246 if(partMC->Charge() == 0) continue;
1248 //consider only primary particles; neglect all secondary particles including from weak decays
1249 if(fselectprimaryTruth && !partMC->IsPhysicalPrimary()) continue;
1252 //remove injected signals(primaries above <maxLabel>)
1253 if (fInjectedSignals && partMC->GetLabel() >= skipParticlesAbove) continue;
1256 Bool_t isduplicate=kFALSE;
1257 if (fRemoveDuplicates)
1259 for (Int_t j=iMC+1; j<nMCTrack; ++j)
1260 {//2nd trutuh loop starts
1261 AliAODMCParticle *partMC2 = (AliAODMCParticle*) fArrayMC->At(j);
1263 AliError(Form("ERROR: Could not retrieve AODMCtrack %d",j));
1266 if (partMC->GetLabel() == partMC2->GetLabel())
1271 }//2nd truth loop ends
1273 if(fRemoveDuplicates && isduplicate) continue;//remove duplicates
1275 //give only kinematic cuts at the truth level
1276 if (partMC->Eta() < fmineta || partMC->Eta() > fmaxeta) continue;
1277 if (partMC->Pt() < fminPt || partMC->Pt() > fmaxPt) continue;
1279 if(!partMC) continue;//for safety
1281 //To determine multiplicity in case of PP
1283 //cout<<"**************************************"<<TMath::Abs(partMC->GetLabel())<<endl;
1284 //only physical primary(all/unidentified)
1285 if(ffillhistQATruth)
1287 MCtruthpt->Fill(partMC->Pt());
1288 MCtrutheta->Fill(partMC->Eta());
1289 MCtruthphi->Fill(partMC->Phi());
1292 Int_t pdgtruth=((AliAODMCParticle*)partMC)->GetPdgCode();
1293 Int_t particletypeTruth=-999;
1294 if (TMath::Abs(pdgtruth)==211)
1296 particletypeTruth=SpPion;
1297 if(ffillhistQATruth)
1299 MCtruthpionpt->Fill(partMC->Pt());
1300 MCtruthpioneta->Fill(partMC->Eta());
1301 MCtruthpionphi->Fill(partMC->Phi());
1304 if (TMath::Abs(pdgtruth)==321)
1306 particletypeTruth=SpKaon;
1307 if(ffillhistQATruth)
1309 MCtruthkaonpt->Fill(partMC->Pt());
1310 MCtruthkaoneta->Fill(partMC->Eta());
1311 MCtruthkaonphi->Fill(partMC->Phi());
1314 if(TMath::Abs(pdgtruth)==2212)
1316 particletypeTruth=SpProton;
1317 if(ffillhistQATruth)
1319 MCtruthprotonpt->Fill(partMC->Pt());
1320 MCtruthprotoneta->Fill(partMC->Eta());
1321 MCtruthprotonphi->Fill(partMC->Phi());
1324 if(TMath::Abs(pdgtruth)!=211 && TMath::Abs(pdgtruth)!=321 && TMath::Abs(pdgtruth)!=2212) particletypeTruth=unidentified;//*********************WARNING:: situation is different from reco MC and data case(here we don't have SpUndefined particles,because here unidentified=SpUndefined)
1326 // -- Fill THnSparse for efficiency and contamination calculation
1327 if (fSampleType=="pp") cent_v0=15.0;//integrated over multiplicity(so put any fixed value for each track so that practically means there is only one bin in multiplicity i.e. multiplicity intregated out )**************Important
1329 Double_t primmctruth[4] = {cent_v0, zVtxmc,partMC->Pt(), partMC->Eta()};
1332 fTHngenprimPidTruth[5]->Fill(primmctruth);//for all primary truth particles(4)
1333 if (TMath::Abs(pdgtruth)==211 || TMath::Abs(pdgtruth)==321) fTHngenprimPidTruth[3]->Fill(primmctruth);//for primary truth mesons(3)
1334 if (TMath::Abs(pdgtruth)==2212 || TMath::Abs(pdgtruth)==321) fTHngenprimPidTruth[4]->Fill(primmctruth);//for primary truth kaons+protons(4)
1335 if (TMath::Abs(pdgtruth)==211) fTHngenprimPidTruth[0]->Fill(primmctruth);//for pions
1336 if (TMath::Abs(pdgtruth)==321) fTHngenprimPidTruth[1]->Fill(primmctruth);//for kaons
1337 if(TMath::Abs(pdgtruth)==2212) fTHngenprimPidTruth[2]->Fill(primmctruth);//for protons
1340 Float_t effmatrixtruth=1.0;//In Truth MC, no case of efficiency correction so it should be always 1.0
1341 if((partMC->Pt()>=fminPtAsso && partMC->Pt()<=fmaxPtAsso) || (partMC->Pt()>=fminPtTrig && partMC->Pt()<=fmaxPtTrig))//to reduce memory consumption in pool
1343 LRCParticlePID* copy6 = new LRCParticlePID(particletypeTruth,partMC->Charge(),partMC->Pt(),partMC->Eta(), partMC->Phi(),effmatrixtruth);
1344 //copy6->SetUniqueID(eventno * 100000 + TMath::Abs(partMC->GetLabel()));
1345 copy6->SetUniqueID(eventno * 100000 + (Int_t)nooftrackstruth);
1346 tracksMCtruth->Add(copy6);//************** TObjArray used for truth correlation function calculation
1348 }//MC truth track loop ends
1350 //*********************still in event loop
1351 Float_t weghtval=1.0;
1353 if (fSampleType=="pp") cent_v0_truth=nooftrackstruth;
1354 else cent_v0_truth=cent_v0;//the notation cent_v0 is reserved for reco/data case
1356 //now cent_v0_truth should be used for all correlation function calculation
1358 if(nooftrackstruth>0.0 && ffilltrigIDassoIDMCTRUTH)
1360 //Fill Correlations for MC truth particles(same event)
1361 if(tracksMCtruth && tracksMCtruth->GetEntriesFast()>0)//hadron triggered correlation
1362 Fillcorrelation(tracksMCtruth,0,cent_v0_truth,zVtxmc,weghtval,bSign,fPtOrderMCTruth,kFALSE,kFALSE,"trigIDassoIDMCTRUTH");//mixcase=kFALSE for same event case
1365 AliEventPool* pool2 = fPoolMgr->GetEventPool(cent_v0_truth, zVtxmc+200);
1366 if (pool2 && pool2->IsReady())
1367 {//start mixing only when pool->IsReady
1368 if(tracksMCtruth && tracksMCtruth->GetEntriesFast()>0)
1369 {//proceed only when no. of trigger particles >0 in current event
1370 Float_t nmix=(Float_t)pool2->GetCurrentNEvents();
1371 for (Int_t jMix=0; jMix<pool2->GetCurrentNEvents(); jMix++)
1372 { //pool event loop start
1373 TObjArray* bgTracks6 = pool2->GetEvent(jMix);
1374 if(!bgTracks6) continue;
1375 Fillcorrelation(tracksMCtruth,bgTracks6,cent_v0_truth,zVtxmc,nmix,bSign,fPtOrderMCTruth,kFALSE,kTRUE,"trigIDassoIDMCTRUTH");//mixcase=kTRUE for mixing case
1377 }// pool event loop ends mixing case
1378 }//if(trackstrig && trackstrig->GetEntriesFast()>0) condition ends mixing case
1379 } //if pool->IsReady() condition ends mixing case
1381 //still in main event loop
1384 if(pool2) pool2->UpdatePool(CloneAndReduceTrackList(tracksMCtruth));//ownership of tracksasso is with pool now, don't delete it
1388 //still in main event loop
1390 if(tracksMCtruth) delete tracksMCtruth;
1392 //now deal with reco tracks
1393 //TObjArray* tracksUNID=0;
1394 TObjArray* tracksUNID = new TObjArray;
1395 tracksUNID->SetOwner(kTRUE);
1397 //TObjArray* tracksID=0;
1398 TObjArray* tracksID = new TObjArray;
1399 tracksID->SetOwner(kTRUE);
1402 Float_t bSign1=aod->GetHeader()->GetMagneticField() ;//used for reconstructed track dca cut
1404 Double_t trackscount=0.0;
1406 // loop over reconstructed tracks
1407 for (Int_t itrk = 0; itrk < aod->GetNumberOfTracks(); itrk++)
1408 { // reconstructed track loop starts
1409 AliAODTrack* track = dynamic_cast<AliAODTrack*>(aod->GetTrack(itrk));
1410 if (!track) continue;
1411 //get the corresponding MC track at the truth level (doing reco matching)
1412 AliAODMCParticle* recomatched = static_cast<AliAODMCParticle*>(fArrayMC->At(TMath::Abs(track->GetLabel())));
1413 if(!recomatched) continue;//if a reco track doesn't have corresponding truth track at generated level is a fake track(label==0), ignore it
1415 //remove injected signals
1416 if(fInjectedSignals)
1418 AliAODMCParticle* mother = recomatched;
1420 while (!mother->IsPhysicalPrimary())
1421 {// find the primary mother;the first stable mother is searched and checked if it is <= <maxLabel>
1422 if (mother->GetMother() < 0)
1428 mother =(AliAODMCParticle*) fArrayMC->At(((AliAODMCParticle*)mother)->GetMother());
1434 Printf("WARNING: No mother found for particle %d:", recomatched->GetLabel());
1437 if (mother->GetLabel() >= skipParticlesAbove) continue;//remove injected signals(primaries above <maxLabel>)
1438 }//remove injected signals
1440 if (fRemoveWeakDecays && ((AliAODMCParticle*) recomatched)->IsSecondaryFromWeakDecay()) continue;//remove weak decays
1442 Bool_t isduplicate2=kFALSE;
1443 if (fRemoveDuplicates)
1445 for (Int_t j =itrk+1; j < aod->GetNumberOfTracks(); j++)
1447 AliAODTrack* track2 = dynamic_cast<AliAODTrack*>(aod->GetTrack(j));
1448 if (!track2) continue;
1449 AliAODMCParticle* recomatched2 = static_cast<AliAODMCParticle*>(fArrayMC->At(TMath::Abs(track2->GetLabel())));
1450 if(!recomatched2) continue;
1452 if (track->GetLabel() == track2->GetLabel())
1459 if(fRemoveDuplicates && isduplicate2) continue;//remove duplicates
1461 fHistQA[11]->Fill(track->GetTPCNcls());
1462 Int_t tracktype=ClassifyTrack(track,trkVtx,bSign1);//dcacut=kFALSE,onlyprimary=kFALSE
1464 if(tracktype==0) continue;
1465 if(tracktype==1)//tracks "not" passed AliAODTrack::kPrimary at reconstructed level & have proper TPC PID response(?)
1467 if(!track) continue;//for safety
1468 //accepted all(primaries+secondary) reconstructed tracks(pt 0.2 to 10.0,,eta -0.8 to 0.8)
1471 //check for eta , phi holes
1472 fEtaSpectrasso->Fill(track->Eta(),track->Pt());
1473 fphiSpectraasso->Fill(track->Phi(),track->Pt());
1475 Int_t particletypeMC=-9999;
1477 //tag all particles as unidentified
1478 particletypeMC=unidentified;
1480 Float_t effmatrix=1.;
1482 // -- Fill THnSparse for efficiency calculation
1483 if (fSampleType=="pp") cent_v0=15.0;//integrated over multiplicity(so put any fixed value for each track so that practically means there is only one bin in multiplicityi.e multiplicity intregated out )**************Important
1484 //NOTE:: this will be used for fillinfg THnSparse of efficiency & also to get the the track by track eff. factor on the fly(only in case of pp)
1486 //Clone & Reduce track list(TObjArray) for unidentified particles
1487 if((track->Pt()>=fminPtAsso && track->Pt()<=fmaxPtAsso) || (track->Pt()>=fminPtTrig && track->Pt()<=fmaxPtTrig))//to reduce memory consumption in pool
1489 if (fapplyTrigefficiency || fapplyAssoefficiency)//get the trackingefficiency x contamination factor for unidentified particles
1490 effmatrix=GetTrackbyTrackeffvalue(track,cent_v0,zvtx,particletypeMC);
1491 LRCParticlePID* copy = new LRCParticlePID(particletypeMC,track->Charge(),track->Pt(),track->Eta(), track->Phi(),effmatrix);
1492 copy->SetUniqueID(eventno * 100000 +(Int_t)trackscount);
1493 tracksUNID->Add(copy);//track information Storage for UNID correlation function(tracks that pass the filterbit & kinematic cuts only)
1495 Double_t allrecomatchedpid[4] = {cent_v0, zVtxmc,recomatched->Pt(), recomatched->Eta()};
1496 if(ffillefficiency) fTHnrecomatchedallPid[5]->Fill(allrecomatchedpid);//for all
1498 //now start the particle identification process:)
1500 //get the pdg code of the corresponding truth particle
1501 Int_t pdgCode = ((AliAODMCParticle*)recomatched)->GetPdgCode();
1503 switch(TMath::Abs(pdgCode)){
1505 if(fFIllPIDQAHistos){
1506 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
1507 if((ipid!=NSigmaTPC) && (!HasTOFPID(track)) && track->Pt()<fPtTOFPIDmin)continue;//not filling TOF and combined if no TOF PID
1508 TH2F *h=GetHistogram2D(Form("NSigmaMC_%d_%d",SpProton,ipid));
1509 h->Fill(track->Pt(),fnsigmas[SpProton][ipid]);
1514 if(fFIllPIDQAHistos){
1515 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
1516 if((ipid!=NSigmaTPC) && (!HasTOFPID(track)) && track->Pt()<fPtTOFPIDmin)continue;//not filling TOF and combined if no TOF PID
1517 TH2F *h=GetHistogram2D(Form("NSigmaMC_%d_%d",SpKaon,ipid));
1518 h->Fill(track->Pt(),fnsigmas[SpKaon][ipid]);
1523 if(fFIllPIDQAHistos){
1524 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
1525 if((ipid!=NSigmaTPC) && (!HasTOFPID(track)) && track->Pt()<fPtTOFPIDmin)continue;//not filling TOF and combined if no TOF PID
1526 TH2F *h=GetHistogram2D(Form("NSigmaMC_%d_%d",SpPion,ipid));
1527 h->Fill(track->Pt(),fnsigmas[SpPion][ipid]);
1534 Float_t dEdx = track->GetTPCsignal();
1535 fHistoTPCdEdx->Fill(track->Pt(), dEdx);
1537 if(HasTOFPID(track))
1539 Double_t beta = GetBeta(track);
1540 fHistoTOFbeta->Fill(track->Pt(), beta);
1543 //do track identification(nsigma method)
1544 particletypeMC=GetParticle(track,fFIllPIDQAHistos);//******************************problem is here
1546 //2-d TPCTOF map(for each Pt interval)
1547 if(HasTOFPID(track)){
1548 fTPCTOFPion3d->Fill(track->Pt(),fnsigmas[SpPion][NSigmaTOF],fnsigmas[SpPion][NSigmaTPC]);
1549 fTPCTOFKaon3d->Fill(track->Pt(),fnsigmas[SpKaon][NSigmaTOF],fnsigmas[SpKaon][NSigmaTPC]);
1550 fTPCTOFProton3d->Fill(track->Pt(),fnsigmas[SpProton][NSigmaTOF],fnsigmas[SpProton][NSigmaTPC]);
1552 if(particletypeMC==SpUndefined) continue;
1554 //Pt, Eta , Phi distribution of the reconstructed identified particles
1557 if (particletypeMC==SpPion)
1559 fPionPt->Fill(track->Pt());
1560 fPionEta->Fill(track->Eta());
1561 fPionPhi->Fill(track->Phi());
1563 if (particletypeMC==SpKaon)
1565 fKaonPt->Fill(track->Pt());
1566 fKaonEta->Fill(track->Eta());
1567 fKaonPhi->Fill(track->Phi());
1569 if (particletypeMC==SpProton)
1571 fProtonPt->Fill(track->Pt());
1572 fProtonEta->Fill(track->Eta());
1573 fProtonPhi->Fill(track->Phi());
1577 //for misidentification fraction calculation(do it with tuneonPID)
1578 if(particletypeMC==SpPion )
1580 if(TMath::Abs(pdgCode)==211) fPioncont->Fill(1.,track->Pt());
1581 if(TMath::Abs(pdgCode)==321) fPioncont->Fill(3.,track->Pt());
1582 if(TMath::Abs(pdgCode)==2212) fPioncont->Fill(5.,track->Pt());
1583 if(TMath::Abs(pdgCode)!=211 && TMath::Abs(pdgCode)!=321 && TMath::Abs(pdgCode)!=2212) fPioncont->Fill(7.,track->Pt());
1585 if(particletypeMC==SpKaon )
1587 if(TMath::Abs(pdgCode)==211) fKaoncont->Fill(1.,track->Pt());
1588 if(TMath::Abs(pdgCode)==321) fKaoncont->Fill(3.,track->Pt());
1589 if(TMath::Abs(pdgCode)==2212) fKaoncont->Fill(5.,track->Pt());
1590 if(TMath::Abs(pdgCode)!=211 && TMath::Abs(pdgCode)!=321 && TMath::Abs(pdgCode)!=2212) fKaoncont->Fill(7.,track->Pt());
1592 if(particletypeMC==SpProton )
1594 if(TMath::Abs(pdgCode)==211) fProtoncont->Fill(1.,track->Pt());
1595 if(TMath::Abs(pdgCode)==321) fProtoncont->Fill(3.,track->Pt());
1596 if(TMath::Abs(pdgCode)==2212) fProtoncont->Fill(5.,track->Pt());
1597 if(TMath::Abs(pdgCode)!=211 && TMath::Abs(pdgCode)!=321 && TMath::Abs(pdgCode)!=2212) fProtoncont->Fill(7.,track->Pt());
1600 //fill tracking efficiency
1603 if(particletypeMC==SpPion || particletypeMC==SpKaon)
1605 if(TMath::Abs(pdgCode)==211 || TMath::Abs(pdgCode)==321) fTHnrecomatchedallPid[3]->Fill(allrecomatchedpid);//for mesons
1607 if(particletypeMC==SpKaon || particletypeMC==SpProton)
1609 if(TMath::Abs(pdgCode)==321 || TMath::Abs(pdgCode)==2212) fTHnrecomatchedallPid[4]->Fill(allrecomatchedpid);//for kaons+protons
1611 if(particletypeMC==SpPion && TMath::Abs(pdgCode)==211) fTHnrecomatchedallPid[0]->Fill(allrecomatchedpid);//for pions
1612 if(particletypeMC==SpKaon && TMath::Abs(pdgCode)==321) fTHnrecomatchedallPid[1]->Fill(allrecomatchedpid);//for kaons
1613 if(particletypeMC==SpProton && TMath::Abs(pdgCode)==2212) fTHnrecomatchedallPid[2]->Fill(allrecomatchedpid);//for protons
1616 if((track->Pt()>=fminPtAsso && track->Pt()<=fmaxPtAsso) || (track->Pt()>=fminPtTrig && track->Pt()<=fmaxPtTrig))//to reduce memory consumption in pool
1618 if (fapplyTrigefficiency || fapplyAssoefficiency)
1619 effmatrix=GetTrackbyTrackeffvalue(track,cent_v0,zvtx,particletypeMC);//get the tracking eff x TOF matching eff x PID eff x contamination factor for identified particles
1620 LRCParticlePID* copy1 = new LRCParticlePID(particletypeMC,track->Charge(),track->Pt(),track->Eta(), track->Phi(),effmatrix);
1621 copy1->SetUniqueID(eventno * 100000 + (Int_t)trackscount);
1622 tracksID->Add(copy1);
1624 }// if(tracktype==1) condition structure ands
1626 }//reco track loop ends
1628 //*************************************************************still in event loop
1630 //same event delta-eta-deltaphi plot
1631 if(fSampleType=="pp") cent_v0=trackscount;//multiplicity
1635 //fill the centrality/multiplicity distribution of the selected events
1636 fhistcentrality->Fill(cent_v0);//*********************************WARNING::binning of cent_v0 is different for pp and pPb/PbPb case
1638 if (fSampleType=="pPb" || fSampleType=="PbPb") fCentralityCorrelation->Fill(cent_v0, trackscount);//only with unidentified tracks(i.e before PID selection);;;;;can be used to remove centrality outliers??????
1640 //count selected events having centrality betn 0-100%
1641 fEventCounter->Fill(6);
1643 //***************************************event no. counting
1644 Bool_t isbaryontrig=kFALSE;
1645 Bool_t ismesontrig=kFALSE;
1646 if(tracksUNID && tracksUNID->GetEntriesFast()>0) fEventno->Fill(cent_v0,zvtx);
1648 if(tracksID && tracksID->GetEntriesFast()>0)
1650 for(Int_t i=0;i<tracksID->GetEntriesFast();i++)
1651 { //trigger loop starts
1652 LRCParticlePID *trig=(LRCParticlePID*)(tracksID->UncheckedAt(i));
1654 if(trig->Pt()<fminPtTrig || trig->Pt()>fmaxPtTrig) continue;
1655 Int_t particlepidtrig=trig->getparticle(); //either 1 or 2
1656 if(particlepidtrig==SpProton) isbaryontrig=kTRUE;
1657 if(particlepidtrig==SpPion) ismesontrig=kTRUE;
1659 if (isbaryontrig) fEventnobaryon->Fill(cent_v0,zvtx);
1660 if (ismesontrig) fEventnomeson->Fill(cent_v0,zvtx);
1663 //same event delte-eta, delta-phi plot
1664 if(tracksUNID && tracksUNID->GetEntriesFast()>0)//hadron triggered correlation
1665 {//same event calculation starts
1666 if(ffilltrigassoUNID) Fillcorrelation(tracksUNID,0,cent_v0,zvtx,weghtval,bSign,kTRUE,kTRUE,kFALSE,"trigassoUNID");//mixcase=kFALSE (hadron-hadron correlation)
1667 if(tracksID && tracksID->GetEntriesFast()>0 && ffilltrigUNIDassoID) Fillcorrelation(tracksUNID,tracksID,cent_v0,zvtx,weghtval,bSign,kFALSE,kTRUE,kFALSE,"trigUNIDassoID");//mixcase=kFALSE (hadron-ID correlation)
1670 if(tracksID && tracksID->GetEntriesFast()>0)//ID triggered correlation
1671 {//same event calculation starts
1672 if(tracksUNID && tracksUNID->GetEntriesFast()>0 && ffilltrigIDassoUNID) Fillcorrelation(tracksID,tracksUNID,cent_v0,zvtx,weghtval,bSign,kFALSE,kTRUE,kFALSE,"trigIDassoUNID");//mixcase=kFALSE (ID-hadron correlation)
1673 if(ffilltrigIDassoID) Fillcorrelation(tracksID,0,cent_v0,zvtx,weghtval,bSign,kFALSE,kTRUE,kFALSE,"trigIDassoID");//mixcase=kFALSE (ID-ID correlation)
1676 //still in main event loop
1678 if(ffilltrigassoUNID || ffilltrigIDassoUNID){//mixing with unidentified particles
1679 AliEventPool* pool = fPoolMgr->GetEventPool(cent_v0, zvtx);//In the pool there is tracksUNID(i.e associateds are unidentified)
1680 if (pool && pool->IsReady())
1681 {//start mixing only when pool->IsReady
1682 Float_t nmix1=(Float_t)pool->GetCurrentNEvents();
1683 for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++)
1684 { //pool event loop start
1685 TObjArray* bgTracks = pool->GetEvent(jMix);
1686 if(!bgTracks) continue;
1687 if(ffilltrigassoUNID && tracksUNID && tracksUNID->GetEntriesFast()>0)//*******************************hadron trggered mixing
1688 Fillcorrelation(tracksUNID,bgTracks,cent_v0,zvtx,nmix1,bSign,kTRUE,kTRUE,kTRUE,"trigassoUNID");//mixcase=kTRUE
1689 if(ffilltrigIDassoUNID && tracksID && tracksID->GetEntriesFast()>0)//***********************************ID trggered mixing
1690 Fillcorrelation(tracksID,bgTracks,cent_v0,zvtx,nmix1,bSign,kFALSE,kTRUE,kTRUE,"trigIDassoUNID");//mixcase=kTRUE
1691 }// pool event loop ends mixing case
1693 } //if pool->IsReady() condition ends mixing case
1696 pool->UpdatePool(CloneAndReduceTrackList(tracksUNID));
1698 }//mixing with unidentified particles
1700 if(ffilltrigUNIDassoID || ffilltrigIDassoID){//mixing with identified particles
1701 AliEventPool* pool1 = fPoolMgr->GetEventPool(cent_v0, zvtx+100);//In the pool1 there is tracksID(i.e associateds are identified)
1702 if (pool1 && pool1->IsReady())
1703 {//start mixing only when pool->IsReady
1704 Float_t nmix2=(Float_t)pool1->GetCurrentNEvents();
1705 for (Int_t jMix=0; jMix<pool1->GetCurrentNEvents(); jMix++)
1706 { //pool event loop start
1707 TObjArray* bgTracks2 = pool1->GetEvent(jMix);
1708 if(!bgTracks2) continue;
1709 if(ffilltrigUNIDassoID && tracksUNID && tracksUNID->GetEntriesFast()>0)
1710 Fillcorrelation(tracksUNID,bgTracks2,cent_v0,zvtx,nmix2,bSign,kFALSE,kTRUE,kTRUE,"trigUNIDassoID");//mixcase=kTRUE
1711 if(ffilltrigIDassoID && tracksID && tracksID->GetEntriesFast()>0)
1712 Fillcorrelation(tracksID,bgTracks2,cent_v0,zvtx,nmix2,bSign,kFALSE,kTRUE,kTRUE,"trigIDassoID");//mixcase=kTRUE
1714 }// pool event loop ends mixing case
1715 } //if pool1->IsReady() condition ends mixing case
1719 pool1->UpdatePool(CloneAndReduceTrackList(tracksID));//ownership of tracksasso is with pool now, don't delete it(tracksUNID is with pool)
1721 }//mixing with identified particles
1723 //no. of events analyzed
1724 fEventCounter->Fill(7);
1727 if(tracksUNID) delete tracksUNID;
1729 if(tracksID) delete tracksID;
1732 PostData(1, fOutput);
1735 //________________________________________________________________________
1736 void AliTwoParticlePIDCorr::doAODevent()
1740 AliVEvent *event = InputEvent();
1741 if (!event) { Printf("ERROR: Could not retrieve event"); return; }
1742 AliAODEvent* aod = dynamic_cast<AliAODEvent*>(event);
1744 AliError("Cannot get the AOD event");
1749 fEventCounter->Fill(1);
1751 // get centrality object and check quality
1754 if(fSampleType=="pPb" || fSampleType=="PbPb")
1756 AliCentrality *centrality=0;
1758 centrality = aod->GetHeader()->GetCentralityP();
1759 // if (centrality->GetQuality() != 0) return ;
1763 cent_v0 = centrality->GetCentralityPercentile(fCentralityMethod);
1771 Float_t bSign = (aod->GetMagneticField() > 0) ? 1 : -1;//for two track efficiency cut in correlation function calculation
1772 Float_t bSign1=aod->GetHeader()->GetMagneticField() ;//for dca cut in ClassifyTrack(), i.e in track loop
1774 // Pileup selection ************************************************
1775 // if(frejectPileUp) //applicable only for TPC only tracks,not for hybrid tracks?.
1777 //if (fAnalysisUtils && fAnalysisUtils->IsPileUpEvent(aod)) return;
1780 if (!fPID) return;//this should be available with each event even if we don't do PID selection
1782 //vertex selection(is it fine for PP?)
1783 if ( fVertextype==1){//for pPb basically if(!fAnalysisUtils->IsVertexSelected2013pA(aod)) return;
1784 trkVtx = aod->GetPrimaryVertex();
1785 if (!trkVtx || trkVtx->GetNContributors()<=0) return;
1786 TString vtxTtl = trkVtx->GetTitle();
1787 if (!vtxTtl.Contains("VertexerTracks")) return;
1788 zvtx = trkVtx->GetZ();
1789 const AliAODVertex* spdVtx = aod->GetPrimaryVertexSPD();
1790 if (!spdVtx || spdVtx->GetNContributors()<=0) return;
1791 TString vtxTyp = spdVtx->GetTitle();
1792 Double_t cov[6]={0};
1793 spdVtx->GetCovarianceMatrix(cov);
1794 Double_t zRes = TMath::Sqrt(cov[5]);
1795 if (vtxTyp.Contains("vertexer:Z") && (zRes>0.25)) return;
1796 if (TMath::Abs(spdVtx->GetZ() - trkVtx->GetZ())>0.5) return;
1798 else if(fVertextype==2) {//for pp and pb-pb case , taken from Jan's code
1799 Int_t nVertex = aod->GetNumberOfVertices();
1801 trkVtx = aod->GetPrimaryVertex();
1802 Int_t nTracksPrim = trkVtx->GetNContributors();
1803 zvtx = trkVtx->GetZ();
1804 //if (fDebug > 1)AliInfo(Form(" Vertex in = %f with %d particles by %s data ...",zVertex,nTracksPrim,vertex->GetName()));
1805 // Reject TPC only vertex
1806 TString name(trkVtx->GetName());
1807 if (name.CompareTo("PrimaryVertex") && name.CompareTo("SPDVertex"))return;
1809 // Select a quality vertex by number of tracks?
1810 if( nTracksPrim < fnTracksVertex ) {
1811 //if (fDebug > 1) AliInfo(" Primary-vertex Selection: event REJECTED ...");
1814 // TODO remove vertexer Z events with dispersion > 0.02: Doesn't work for AOD at present
1815 //if (strcmp(vertex->GetTitle(), "AliVertexerZ") == 0 && vertex->GetDispersion() > 0.02)
1817 // if (fDebug > 1) AliInfo(" Primary-vertex Selection: event ACCEPTED...");
1822 else if(fVertextype==0){//default case
1823 trkVtx = aod->GetPrimaryVertex();
1824 if (!trkVtx || trkVtx->GetNContributors()<=0) return;//proper number of contributors
1825 zvtx = trkVtx->GetZ();
1827 trkVtx->GetCovarianceMatrix(fCov);
1828 if(fCov[5] == 0) return;//proper vertex resolution
1831 AliInfo("Wrong Vertextype set for Primary-vertex Selection: event REJECTED ...");
1832 return;//as there is no proper sample type
1835 fHistQA[0]->Fill((trkVtx->GetX()));fHistQA[1]->Fill((trkVtx->GetY()));fHistQA[2]->Fill((trkVtx->GetZ())); //for trkVtx only before vertex cut |zvtx|<10 cm
1837 //count events having a proper vertex
1838 fEventCounter->Fill(2);
1840 if (TMath::Abs(zvtx) > fzvtxcut) return;
1842 //count events after vertex cut
1843 fEventCounter->Fill(5);
1846 //if(!fAnalysisUtils->IsVertexSelected2013pA(aod)) return;
1848 fHistQA[3]->Fill((trkVtx->GetX()));fHistQA[4]->Fill((trkVtx->GetY()));fHistQA[5]->Fill((trkVtx->GetZ()));//after vertex cut,for trkVtx only
1851 if(!aod) return; //for safety
1853 if(fSampleType=="pPb" || fSampleType=="PbPb") if (cent_v0 < 0) return;//for pp case it is the multiplicity
1855 TObjArray* tracksUNID= new TObjArray;//track info before doing PID
1856 tracksUNID->SetOwner(kTRUE); // IMPORTANT!
1858 TObjArray* tracksID= new TObjArray;//only pions, kaons,protonsi.e. after doing the PID selection
1859 tracksID->SetOwner(kTRUE); // IMPORTANT!
1861 Double_t trackscount=0.0;//in case of pp this will give the multiplicity after the track loop(only for unidentified particles that pass the filterbit and kinematic cuts)
1865 for (Int_t itrk = 0; itrk < aod->GetNumberOfTracks(); itrk++)
1866 { //track loop starts for TObjArray(containing track and event information) filling; used for correlation function calculation
1867 AliAODTrack* track = dynamic_cast<AliAODTrack*>(aod->GetTrack(itrk));
1868 if (!track) continue;
1869 fHistQA[11]->Fill(track->GetTPCNcls());
1870 Int_t particletype=-9999;//required for PID filling
1871 Int_t tracktype=ClassifyTrack(track,trkVtx,bSign1);//dcacut=kFALSE,onlyprimary=kFALSE
1872 if(tracktype!=1) continue;
1874 if(!track) continue;//for safety
1876 //check for eta , phi holes
1877 fEtaSpectrasso->Fill(track->Eta(),track->Pt());
1878 fphiSpectraasso->Fill(track->Phi(),track->Pt());
1882 //if no applyefficiency , set the eff factor=1.0
1883 Float_t effmatrix=1.0;
1885 //tag all particles as unidentified that passed filterbit & kinematic cuts
1886 particletype=unidentified;
1889 if (fSampleType=="pp") cent_v0=15.0;//integrated over multiplicity [i.e each track has multiplicity 15.0](so put any fixed value for each track so that practically means there is only one bin in multiplicityi.e multiplicity intregated out )**************Important for efficiency related issues
1892 //to reduce memory consumption in pool
1893 if((track->Pt()>=fminPtAsso && track->Pt()<=fmaxPtAsso) || (track->Pt()>=fminPtTrig && track->Pt()<=fmaxPtTrig))
1895 //Clone & Reduce track list(TObjArray) for unidentified particles
1896 if (fapplyTrigefficiency || fapplyAssoefficiency)//get the trackingefficiency x contamination factor for unidentified particles
1897 effmatrix=GetTrackbyTrackeffvalue(track,cent_v0,zvtx,particletype);
1898 LRCParticlePID* copy = new LRCParticlePID(particletype,track->Charge(),track->Pt(),track->Eta(), track->Phi(),effmatrix);
1899 copy->SetUniqueID(eventno * 100000 + (Int_t)trackscount);
1900 tracksUNID->Add(copy);//track information Storage for UNID correlation function(tracks that pass the filterbit & kinematic cuts only)
1903 //now start the particle identificaion process:)
1905 //track passing filterbit 768 have proper TPC response,or need to be checked explicitly before doing PID????
1907 Float_t dEdx = track->GetTPCsignal();
1908 fHistoTPCdEdx->Fill(track->Pt(), dEdx);
1910 //fill beta vs Pt plots only for tracks having proper TOF response(much less tracks compared to the no. that pass the filterbit & kinematic cuts)
1911 if(HasTOFPID(track))
1913 Double_t beta = GetBeta(track);
1914 fHistoTOFbeta->Fill(track->Pt(), beta);
1918 //track identification(using nsigma method)
1919 particletype=GetParticle(track,fFIllPIDQAHistos);//*******************************change may be required(It should return only pion,kaon, proton and Spundefined; NOT unidentifed***************be careful)
1922 //2-d TPCTOF map(for each Pt interval)
1923 if(HasTOFPID(track)){
1924 fTPCTOFPion3d->Fill(track->Pt(),fnsigmas[SpPion][NSigmaTOF],fnsigmas[SpPion][NSigmaTPC]);
1925 fTPCTOFKaon3d->Fill(track->Pt(),fnsigmas[SpKaon][NSigmaTOF],fnsigmas[SpKaon][NSigmaTPC]);
1926 fTPCTOFProton3d->Fill(track->Pt(),fnsigmas[SpProton][NSigmaTOF],fnsigmas[SpProton][NSigmaTPC]);
1929 //ignore the Spundefined particles as they also contain pion, kaon, proton outside the nsigma cut(also if tracks don't have proper TOF PID in a certain Pt interval) & these tracks are actually counted when we do the the efficiency correction, so considering them as unidentified particles & doing the efficiency correction(i.e defining unidentified=pion+Kaon+proton+SpUndefined is right only without efficiency correction) for them will be two times wrong!!!!!
1930 if (particletype==SpUndefined) continue;//this condition creating a modulated structure in delphi projection in mixed event case(only when we are dealing with identified particles i.e. tracksID)!!!!!!!!!!!
1932 //Pt, Eta , Phi distribution of the reconstructed identified particles
1935 if (particletype==SpPion)
1937 fPionPt->Fill(track->Pt());
1938 fPionEta->Fill(track->Eta());
1939 fPionPhi->Fill(track->Phi());
1941 if (particletype==SpKaon)
1943 fKaonPt->Fill(track->Pt());
1944 fKaonEta->Fill(track->Eta());
1945 fKaonPhi->Fill(track->Phi());
1947 if (particletype==SpProton)
1949 fProtonPt->Fill(track->Pt());
1950 fProtonEta->Fill(track->Eta());
1951 fProtonPhi->Fill(track->Phi());
1955 if((track->Pt()>=fminPtAsso && track->Pt()<=fmaxPtAsso) || (track->Pt()>=fminPtTrig && track->Pt()<=fmaxPtTrig))
1957 if (fapplyTrigefficiency || fapplyAssoefficiency)
1958 effmatrix=GetTrackbyTrackeffvalue(track,cent_v0,zvtx,particletype);//get the tracking eff x TOF matching eff x PID eff x contamination factor for identified particles; Bool_t mesoneffrequired=kFALSE
1959 LRCParticlePID* copy1 = new LRCParticlePID(particletype,track->Charge(),track->Pt(),track->Eta(), track->Phi(),effmatrix);
1960 copy1->SetUniqueID(eventno * 100000 + (Int_t)trackscount);
1961 tracksID->Add(copy1);
1963 } //track loop ends but still in event loop
1965 if(trackscount<1.0){
1966 if(tracksUNID) delete tracksUNID;
1967 if(tracksID) delete tracksID;
1971 Float_t weightval=1.0;
1974 // cout<<fminPtAsso<<"***"<<fmaxPtAsso<<"*********************"<<fminPtTrig<<"***"<<fmaxPtTrig<<"*****************"<<kTrackVariablesPair<<endl;
1975 if(fSampleType=="pp") cent_v0=trackscount;//multiplicity
1977 //fill the centrality/multiplicity distribution of the selected events
1978 fhistcentrality->Fill(cent_v0);//*********************************WARNING::binning of cent_v0 is different for pp and pPb/PbPb case
1980 if(fSampleType=="pPb" || fSampleType=="PbPb") fCentralityCorrelation->Fill(cent_v0, trackscount);//only with unidentified tracks(i.e before PID selection);;;;;can be used to remove centrality outliers??????
1982 //count selected events having centrality betn 0-100%
1983 fEventCounter->Fill(6);
1985 //***************************************event no. counting
1986 Bool_t isbaryontrig=kFALSE;
1987 Bool_t ismesontrig=kFALSE;
1988 if(tracksUNID && tracksUNID->GetEntriesFast()>0) fEventno->Fill(cent_v0,zvtx);
1990 if(tracksID && tracksID->GetEntriesFast()>0)
1992 for(Int_t i=0;i<tracksID->GetEntriesFast();i++)
1993 { //trigger loop starts
1994 LRCParticlePID *trig=(LRCParticlePID*)(tracksID->UncheckedAt(i));
1996 if(trig->Pt()<fminPtTrig || trig->Pt()>fmaxPtTrig) continue;
1997 Int_t particlepidtrig=trig->getparticle(); //either 1 or 2
1998 if(particlepidtrig==SpProton) isbaryontrig=kTRUE;
1999 if(particlepidtrig==SpPion) ismesontrig=kTRUE;
2001 if (isbaryontrig) fEventnobaryon->Fill(cent_v0,zvtx);
2002 if (ismesontrig) fEventnomeson->Fill(cent_v0,zvtx);
2006 //same event delta-eta-deltaphi plot
2008 if(tracksUNID && tracksUNID->GetEntriesFast()>0)//hadron triggered correlation
2009 {//same event calculation starts
2010 if(ffilltrigassoUNID) Fillcorrelation(tracksUNID,0,cent_v0,zvtx,weightval,bSign,kTRUE,kTRUE,kFALSE,"trigassoUNID");//mixcase=kFALSE (hadron-hadron correlation)
2011 if(tracksID && tracksID->GetEntriesFast()>0 && ffilltrigUNIDassoID) Fillcorrelation(tracksUNID,tracksID,cent_v0,zvtx,weightval,bSign,kFALSE,kTRUE,kFALSE,"trigUNIDassoID");//mixcase=kFALSE (hadron-ID correlation)
2014 if(tracksID && tracksID->GetEntriesFast()>0)//ID triggered correlation
2015 {//same event calculation starts
2016 if(tracksUNID && tracksUNID->GetEntriesFast()>0 && ffilltrigIDassoUNID) Fillcorrelation(tracksID,tracksUNID,cent_v0,zvtx,weightval,bSign,kFALSE,kTRUE,kFALSE,"trigIDassoUNID");//mixcase=kFALSE (ID-hadron correlation)
2017 if(ffilltrigIDassoID) Fillcorrelation(tracksID,0,cent_v0,zvtx,weightval,bSign,kFALSE,kTRUE,kFALSE,"trigIDassoID");//mixcase=kFALSE (ID-ID correlation)
2020 //still in main event loop
2024 if(ffilltrigassoUNID || ffilltrigIDassoUNID){//mixing with unidentified particles
2025 AliEventPool* pool = fPoolMgr->GetEventPool(cent_v0, zvtx);//In the pool there is tracksUNID(i.e associateds are unidentified)
2026 if (pool && pool->IsReady())
2027 {//start mixing only when pool->IsReady
2028 Float_t nmix1=(Float_t)pool->GetCurrentNEvents();
2029 for (Int_t jMix=0; jMix<pool->GetCurrentNEvents(); jMix++)
2030 { //pool event loop start
2031 TObjArray* bgTracks = pool->GetEvent(jMix);
2032 if(!bgTracks) continue;
2033 if(ffilltrigassoUNID && tracksUNID && tracksUNID->GetEntriesFast()>0)//*******************************hadron trggered mixing
2034 Fillcorrelation(tracksUNID,bgTracks,cent_v0,zvtx,nmix1,bSign,kTRUE,kTRUE,kTRUE,"trigassoUNID");//mixcase=kTRUE
2035 if(ffilltrigIDassoUNID && tracksID && tracksID->GetEntriesFast()>0)//***********************************ID trggered mixing
2036 Fillcorrelation(tracksID,bgTracks,cent_v0,zvtx,nmix1,bSign,kFALSE,kTRUE,kTRUE,"trigIDassoUNID");//mixcase=kTRUE
2037 }// pool event loop ends mixing case
2039 } //if pool->IsReady() condition ends mixing case
2042 pool->UpdatePool(CloneAndReduceTrackList(tracksUNID));
2044 }//mixing with unidentified particles
2047 if(ffilltrigUNIDassoID || ffilltrigIDassoID){//mixing with identified particles
2048 AliEventPool* pool1 = fPoolMgr->GetEventPool(cent_v0, zvtx+100);//In the pool1 there is tracksID(i.e associateds are identified)
2049 if (pool1 && pool1->IsReady())
2050 {//start mixing only when pool->IsReady
2051 Float_t nmix2=(Float_t)pool1->GetCurrentNEvents();
2052 for (Int_t jMix=0; jMix<pool1->GetCurrentNEvents(); jMix++)
2053 { //pool event loop start
2054 TObjArray* bgTracks2 = pool1->GetEvent(jMix);
2055 if(!bgTracks2) continue;
2056 if(ffilltrigUNIDassoID && tracksUNID && tracksUNID->GetEntriesFast()>0)
2057 Fillcorrelation(tracksUNID,bgTracks2,cent_v0,zvtx,nmix2,bSign,kFALSE,kTRUE,kTRUE,"trigUNIDassoID");//mixcase=kTRUE
2058 if(ffilltrigIDassoID && tracksID && tracksID->GetEntriesFast()>0)
2059 Fillcorrelation(tracksID,bgTracks2,cent_v0,zvtx,nmix2,bSign,kFALSE,kTRUE,kTRUE,"trigIDassoID");//mixcase=kTRUE
2061 }// pool event loop ends mixing case
2062 } //if pool1->IsReady() condition ends mixing case
2066 pool1->UpdatePool(CloneAndReduceTrackList(tracksID));//ownership of tracksasso is with pool now, don't delete it(tracksUNID is with pool)
2068 }//mixing with identified particles
2071 //no. of events analyzed
2072 fEventCounter->Fill(7);
2074 //still in main event loop
2077 if(tracksUNID) delete tracksUNID;
2079 if(tracksID) delete tracksID;
2082 PostData(1, fOutput);
2084 } // *************************event loop ends******************************************//_______________________________________________________________________
2085 TObjArray* AliTwoParticlePIDCorr::CloneAndReduceTrackList(TObjArray* tracks)
2087 // clones a track list by using AliDPhiBasicParticle which uses much less memory (used for event mixing)
2089 TObjArray* tracksClone = new TObjArray;
2090 tracksClone->SetOwner(kTRUE);
2092 for (Int_t i=0; i<tracks->GetEntriesFast(); i++)
2094 LRCParticlePID* particle = (LRCParticlePID*) tracks->UncheckedAt(i);
2095 LRCParticlePID* copy100 = new LRCParticlePID(particle->getparticle(),particle->Charge(), particle->Pt(),particle->Eta(), particle->Phi(), particle->geteffcorrectionval());
2096 copy100->SetUniqueID(particle->GetUniqueID());
2097 tracksClone->Add(copy100);
2103 //--------------------------------------------------------------------------------
2104 void AliTwoParticlePIDCorr::Fillcorrelation(TObjArray *trackstrig,TObjArray *tracksasso,Double_t cent,Float_t vtx,Float_t weight,Float_t bSign,Bool_t fPtOrder,Bool_t twoTrackEfficiencyCut,Bool_t mixcase,TString fillup)
2107 //before calling this function check that either trackstrig & tracksasso are available
2109 // Eta() is extremely time consuming, therefore cache it for the inner loop here:
2110 TObjArray* input = (tracksasso) ? tracksasso : trackstrig;
2111 TArrayF eta(input->GetEntriesFast());
2112 for (Int_t i=0; i<input->GetEntriesFast(); i++)
2113 eta[i] = ((LRCParticlePID*) input->UncheckedAt(i))->Eta();
2116 Int_t jmax=trackstrig->GetEntriesFast();
2118 jmax=tracksasso->GetEntriesFast();
2120 // identify K, Lambda candidates and flag those particles
2121 // a TObject bit is used for this
2122 const UInt_t kResonanceDaughterFlag = 1 << 14;
2123 if (fRejectResonanceDaughters > 0)
2125 Double_t resonanceMass = -1;
2126 Double_t massDaughter1 = -1;
2127 Double_t massDaughter2 = -1;
2128 const Double_t interval = 0.02;
2129 switch (fRejectResonanceDaughters)
2131 case 1: resonanceMass = 0.9; massDaughter1 = 0.1396; massDaughter2 = 0.9383; break; // method test
2132 case 2: resonanceMass = 0.4976; massDaughter1 = 0.1396; massDaughter2 = massDaughter1; break; // k0
2133 case 3: resonanceMass = 1.115; massDaughter1 = 0.1396; massDaughter2 = 0.9383; break; // lambda
2134 default: AliFatal(Form("Invalid setting %d", fRejectResonanceDaughters));
2137 for (Int_t i=0; i<trackstrig->GetEntriesFast(); i++)
2138 trackstrig->UncheckedAt(i)->ResetBit(kResonanceDaughterFlag);
2139 for (Int_t i=0; tracksasso->GetEntriesFast(); i++)
2140 tracksasso->UncheckedAt(i)->ResetBit(kResonanceDaughterFlag);
2142 for (Int_t i=0; i<trackstrig->GetEntriesFast(); i++)
2144 LRCParticlePID *trig=(LRCParticlePID*)(trackstrig->UncheckedAt(i));
2145 for (Int_t j=0; tracksasso->GetEntriesFast(); j++)
2147 LRCParticlePID *asso=(LRCParticlePID*)(tracksasso->UncheckedAt(j));
2149 // check if both particles point to the same element (does not occur for mixed events, but if subsets are mixed within the same event)
2150 if (trig->IsEqual(asso)) continue;
2152 if (trig->Charge() * asso->Charge() > 0) continue;
2154 Float_t mass = GetInvMassSquaredCheap(trig->Pt(), trig->Eta(), trig->Phi(), asso->Pt(), asso->Eta(), asso->Phi(), massDaughter1, massDaughter2);
2156 if (TMath::Abs(mass - resonanceMass*resonanceMass) < interval*5)
2158 mass = GetInvMassSquared(trig->Pt(), trig->Eta(), trig->Phi(), asso->Pt(), asso->Eta(), asso->Phi(), massDaughter1, massDaughter2);
2160 if (mass > (resonanceMass-interval)*(resonanceMass-interval) && mass < (resonanceMass+interval)*(resonanceMass+interval))
2162 trig->SetBit(kResonanceDaughterFlag);
2163 asso->SetBit(kResonanceDaughterFlag);
2165 // Printf("Flagged %d %d %f", i, j, TMath::Sqrt(mass));
2172 //Select the highest Pt trigger particle in an event (within a given Pt trigger range)
2174 Float_t TriggerPtMin=fminPtTrig;
2175 Float_t TriggerPtMax=fmaxPtTrig;
2176 Int_t HighestPtTriggerIndx=-99999;
2178 if(fSelectHighestPtTrig)//**************add this data member to the constructor
2180 for(Int_t i=0;i<trackstrig->GetEntriesFast();i++)
2181 { //trigger loop starts(highest Pt trigger selection)
2182 LRCParticlePID *trig=(LRCParticlePID*)(trackstrig->UncheckedAt(i));
2184 Float_t trigpt=trig->Pt();
2185 //to avoid overflow qnd underflow
2186 if(trigpt<fminPtTrig || trigpt>fmaxPtTrig) continue;
2187 Int_t particlepidtrig=trig->getparticle();
2188 if(fTriggerSpeciesSelection){ if (particlepidtrig!=fTriggerSpecies) continue;}
2190 Float_t trigeta=trig->Eta();
2192 // some optimization
2193 if (fTriggerRestrictEta > 0 && TMath::Abs(trigeta) > fTriggerRestrictEta)
2196 if (fOnlyOneEtaSide != 0)
2198 if (fOnlyOneEtaSide * trigeta < 0)
2201 if (fTriggerSelectCharge != 0)
2202 if (trig->Charge() * fTriggerSelectCharge < 0)
2205 if (fRejectResonanceDaughters > 0)
2206 if (trig->TestBit(kResonanceDaughterFlag)) continue;
2208 if(trigpt>TriggerPtMin && trigpt<=TriggerPtMax)
2210 //TriggerPt=trigpt;//*********think about it
2212 HighestPtTriggerIndx=(Int_t)trig->GetUniqueID();
2213 TriggerPtMin=trigpt;
2216 }//trigger loop ends(highest Pt trigger selection)
2218 }//******************SelectHighestPtTrig condition ends
2221 //two particle correlation filling
2222 for(Int_t i=0;i<trackstrig->GetEntriesFast();i++)
2223 { //trigger loop starts
2224 LRCParticlePID *trig=(LRCParticlePID*)(trackstrig->UncheckedAt(i));
2226 Float_t trigpt=trig->Pt();
2227 //to avoid overflow qnd underflow
2228 if(trigpt<fminPtTrig || trigpt>fmaxPtTrig) continue;
2229 Int_t particlepidtrig=trig->getparticle();
2230 if(fTriggerSpeciesSelection){ if (particlepidtrig!=fTriggerSpecies) continue;}
2232 Float_t trigeta=trig->Eta();
2234 // some optimization
2235 if (fTriggerRestrictEta > 0 && TMath::Abs(trigeta) > fTriggerRestrictEta)
2238 if (fOnlyOneEtaSide != 0)
2240 if (fOnlyOneEtaSide * trigeta < 0)
2243 if (fTriggerSelectCharge != 0)
2244 if (trig->Charge() * fTriggerSelectCharge < 0)
2247 if (fRejectResonanceDaughters > 0)
2248 if (trig->TestBit(kResonanceDaughterFlag)) continue;
2250 if(fSelectHighestPtTrig && HighestPtTriggerIndx!=-99999) {
2251 if(trig->GetUniqueID()!=(UInt_t)HighestPtTriggerIndx) continue;
2254 Float_t trigphi=trig->Phi();
2255 Float_t trackefftrig=1.0;
2256 if(fapplyTrigefficiency) trackefftrig=trig->geteffcorrectionval();
2257 //cout<<"*******************trackefftrig="<<trackefftrig<<endl;
2260 if(fcontainPIDtrig) dim=4;
2261 trigval= new Double_t[dim];
2264 trigval[2] = trigpt;
2265 if(fcontainPIDtrig) trigval[3] = particlepidtrig;
2267 //filling only for same event case(mixcase=kFALSE)
2269 //trigger particle counting only when mixcase=kFALSE i.e for same event correlation function calculation
2272 if(ffilltrigassoUNID==kTRUE && ffilltrigUNIDassoID==kTRUE){
2273 if(fillup=="trigassoUNID" ) fTHnTrigcount->Fill(trigval,0,1.0/trackefftrig);
2275 if(ffilltrigassoUNID==kTRUE && ffilltrigUNIDassoID==kFALSE){
2276 if(fillup=="trigassoUNID" ) fTHnTrigcount->Fill(trigval,0,1.0/trackefftrig);
2278 if(ffilltrigassoUNID==kFALSE && ffilltrigUNIDassoID==kTRUE){
2279 if(fillup=="trigUNIDassoID") fTHnTrigcount->Fill(trigval,0,1.0/trackefftrig);
2281 //ensure that trigIDassoID , trigassoUNID, trigIDassoUNID & trigUNIDassoID case FillCorrelation called only once in the event loop for same event correlation function calculation, otherwise there will be multiple counting of pion, kaon,proton,unidentified
2282 if(ffilltrigIDassoUNID==kTRUE && ffilltrigIDassoID==kTRUE){
2283 if(fillup=="trigIDassoID") fTHnTrigcount->Fill(trigval,0,1.0/trackefftrig);
2285 if(ffilltrigIDassoUNID==kTRUE && ffilltrigIDassoID==kFALSE){
2286 if(fillup=="trigIDassoUNID" ) fTHnTrigcount->Fill(trigval,0,1.0/trackefftrig);
2288 if(ffilltrigIDassoUNID==kFALSE && ffilltrigIDassoID==kTRUE){
2289 if(fillup=="trigIDassoID") fTHnTrigcount->Fill(trigval,0,1.0/trackefftrig);
2292 if(fillup=="trigIDassoIDMCTRUTH") fTHnTrigcountMCTruthPrim->Fill(trigval,0,1.0/trackefftrig); //In truth MC case "Unidentified" means any particle other than pion,kaon or proton and no efficiency correction(default value 1.0)************************be careful!!!!
2295 //asso loop starts within trigger loop
2296 for(Int_t j=0;j<jmax;j++)
2298 LRCParticlePID *asso=0;
2300 asso=(LRCParticlePID*)(trackstrig->UncheckedAt(j));
2302 asso=(LRCParticlePID*)(tracksasso->UncheckedAt(j));
2306 //to avoid overflow qnd underflow
2307 if(asso->Pt()<fminPtAsso || asso->Pt()>fmaxPtAsso) continue;//***********************Important
2309 if(fmaxPtAsso==fminPtTrig) {if(asso->Pt()==fminPtTrig) continue;}//******************Think about it!
2311 if(!tracksasso && j==i) continue;
2313 // check if both particles point to the same element (does not occur for mixed events, but if subsets are mixed within the same event,i.e. both Trig and asso TObjArray belongs to the same Pi range but say Trig is Unidentified but asso is identified then the serial no. wise particles are not same and and j==i doesn't aplly)
2314 // if (tracksasso && trig->IsEqual(asso)) continue;
2316 if (tracksasso && (trig->GetUniqueID()==asso->GetUniqueID())) continue;
2319 if (asso->Pt() >= trig->Pt()) continue;
2321 Int_t particlepidasso=asso->getparticle();
2322 if(fAssociatedSpeciesSelection){ if (particlepidasso!=fAssociatedSpecies) continue;}
2325 if (fAssociatedSelectCharge != 0)
2326 if (asso->Charge() * fAssociatedSelectCharge < 0) continue;
2328 if (fSelectCharge > 0)
2331 if (fSelectCharge == 1 && asso->Charge() * trig->Charge() > 0)
2335 if (fSelectCharge == 2 && asso->Charge() * trig->Charge() < 0)
2341 if (trigeta < 0 && asso->Eta() < trigeta)
2343 if (trigeta > 0 && asso->Eta() > trigeta)
2347 if (fRejectResonanceDaughters > 0)
2348 if (asso->TestBit(kResonanceDaughterFlag))
2350 // Printf("Skipped j=%d", j);
2355 if (fCutConversions && asso->Charge() * trig->Charge() < 0)
2357 Float_t mass = GetInvMassSquaredCheap(trig->Pt(), trigeta, trig->Phi(), asso->Pt(),eta[j], asso->Phi(), 0.510e-3, 0.510e-3);
2361 mass = GetInvMassSquared(trig->Pt(), trigeta, trig->Phi(), asso->Pt(), eta[j], asso->Phi(), 0.510e-3, 0.510e-3);
2363 //fControlConvResoncances->Fill(0.0, mass);
2365 if (mass < 0.04*0.04)
2371 if (fCutResonances && asso->Charge() * trig->Charge() < 0)
2373 Float_t mass = GetInvMassSquaredCheap(trig->Pt(), trigeta, trig->Phi(), asso->Pt(), eta[j], asso->Phi(), 0.1396, 0.1396);
2375 const Float_t kK0smass = 0.4976;
2377 if (TMath::Abs(mass - kK0smass*kK0smass) < 0.1)
2379 mass = GetInvMassSquared(trig->Pt(), trigeta, trig->Phi(), asso->Pt(),eta[j], asso->Phi(), 0.1396, 0.1396);
2381 //fControlConvResoncances->Fill(1, mass - kK0smass*kK0smass);
2383 if (mass > (kK0smass-0.02)*(kK0smass-0.02) && mass < (kK0smass+0.02)*(kK0smass+0.02))
2389 if (fCutResonances && asso->Charge() * trig->Charge() < 0)
2391 Float_t mass1 = GetInvMassSquaredCheap(trig->Pt(), trigeta, trig->Phi(), asso->Pt(), eta[j], asso->Phi(), 0.1396, 0.9383);
2392 Float_t mass2 = GetInvMassSquaredCheap(trig->Pt(), trigeta, trig->Phi(), asso->Pt(),eta[j] , asso->Phi(), 0.9383, 0.1396);
2394 const Float_t kLambdaMass = 1.115;
2396 if (TMath::Abs(mass1 - kLambdaMass*kLambdaMass) < 0.1)
2398 mass1 = GetInvMassSquared(trig->Pt(), trigeta, trig->Phi(), asso->Pt(),eta[j], asso->Phi(), 0.1396, 0.9383);
2400 //fControlConvResoncances->Fill(2, mass1 - kLambdaMass*kLambdaMass);
2402 if (mass1 > (kLambdaMass-0.02)*(kLambdaMass-0.02) && mass1 < (kLambdaMass+0.02)*(kLambdaMass+0.02))
2405 if (TMath::Abs(mass2 - kLambdaMass*kLambdaMass) < 0.1)
2407 mass2 = GetInvMassSquared(trig->Pt(), trigeta, trig->Phi(), asso->Pt(),eta[j] , asso->Phi(), 0.9383, 0.1396);
2409 //fControlConvResoncances->Fill(2, mass2 - kLambdaMass*kLambdaMass);
2411 if (mass2 > (kLambdaMass-0.02)*(kLambdaMass-0.02) && mass2 < (kLambdaMass+0.02)*(kLambdaMass+0.02))
2416 if (twoTrackEfficiencyCut)
2418 // the variables & cuthave been developed by the HBT group
2419 // see e.g. https://indico.cern.ch/materialDisplay.py?contribId=36&sessionId=6&materialId=slides&confId=142700
2420 Float_t phi1 = trig->Phi();
2421 Float_t pt1 = trig->Pt();
2422 Float_t charge1 = trig->Charge();
2423 Float_t phi2 = asso->Phi();
2424 Float_t pt2 = asso->Pt();
2425 Float_t charge2 = asso->Charge();
2427 Float_t deta= trigeta - eta[j];
2430 if (TMath::Abs(deta) < twoTrackEfficiencyCutValue * 2.5 * 3)
2433 // check first boundaries to see if is worth to loop and find the minimum
2434 Float_t dphistar1 = GetDPhiStar(phi1, pt1, charge1, phi2, pt2, charge2, 0.8, bSign);
2435 Float_t dphistar2 = GetDPhiStar(phi1, pt1, charge1, phi2, pt2, charge2, 2.5, bSign);
2437 const Float_t kLimit = twoTrackEfficiencyCutValue * 3;
2439 Float_t dphistarminabs = 1e5;
2440 Float_t dphistarmin = 1e5;
2442 if (TMath::Abs(dphistar1) < kLimit || TMath::Abs(dphistar2) < kLimit || dphistar1 * dphistar2 < 0)
2444 for (Double_t rad=0.8; rad<2.51; rad+=0.01)
2446 Float_t dphistar = GetDPhiStar(phi1, pt1, charge1, phi2, pt2, charge2, rad, bSign);
2448 Float_t dphistarabs = TMath::Abs(dphistar);
2450 if (dphistarabs < dphistarminabs)
2452 dphistarmin = dphistar;
2453 dphistarminabs = dphistarabs;
2457 if (dphistarminabs < twoTrackEfficiencyCutValue && TMath::Abs(deta) < twoTrackEfficiencyCutValue)
2459 // Printf("Removed track pair %d %d with %f %f %f %f %f %f %f %f %f", i, j, deta, dphistarminabs, phi1, pt1, charge1, phi2, pt2, charge2, bSign);
2462 //fTwoTrackDistancePt[1]->Fill(deta, dphistarmin, TMath::Abs(pt1 - pt2));
2468 Float_t weightperevent=weight;
2469 Float_t trackeffasso=1.0;
2470 if(fapplyAssoefficiency) trackeffasso=asso->geteffcorrectionval();
2471 //cout<<"*******************trackeffasso="<<trackeffasso<<endl;
2472 Float_t deleta=trigeta-eta[j];
2473 Float_t delphi=PhiRange(trigphi-asso->Phi());
2475 //here get the two particle efficiency correction factor
2476 Float_t effweight=trackefftrig*trackeffasso*weightperevent;
2477 // if(mixcase==kFALSE) cout<<"*******************effweight="<<effweight<<endl;
2479 vars= new Double_t[kTrackVariablesPair];
2486 if(fcontainPIDtrig && !fcontainPIDasso) vars[6]=particlepidtrig;
2487 if(!fcontainPIDtrig && fcontainPIDasso) vars[6]=particlepidasso;
2488 if(fcontainPIDtrig && fcontainPIDasso){
2489 vars[6]=particlepidtrig;
2490 vars[7]=particlepidasso;
2493 //Fill Correlation ThnSparses
2494 if(fillup=="trigassoUNID")
2496 if(mixcase==kFALSE) fTHnCorrUNID->Fill(vars,0,1.0/effweight);
2497 if(mixcase==kTRUE) fTHnCorrUNIDmix->Fill(vars,0,1.0/effweight);
2499 if(fillup=="trigIDassoID")
2501 if(mixcase==kFALSE) fTHnCorrID->Fill(vars,0,1.0/effweight);
2502 if(mixcase==kTRUE) fTHnCorrIDmix->Fill(vars,0,1.0/effweight);
2504 if(fillup=="trigIDassoIDMCTRUTH")//******************************************for TRUTH MC particles
2505 {//in this case effweight should be 1 always
2506 if(mixcase==kFALSE) fCorrelatonTruthPrimary->Fill(vars,0,1.0/effweight);
2507 if(mixcase==kTRUE) fCorrelatonTruthPrimarymix->Fill(vars,0,1.0/effweight);
2509 if(fillup=="trigIDassoUNID" || fillup=="trigUNIDassoID")//****************************be careful
2511 if(mixcase==kFALSE) fTHnCorrIDUNID->Fill(vars,0,1.0/effweight);
2512 if(mixcase==kTRUE) fTHnCorrIDUNIDmix->Fill(vars,0,1.0/effweight);
2518 }//trigger loop ends
2522 //--------------------------------------------------------------------------------
2523 Float_t AliTwoParticlePIDCorr::GetTrackbyTrackeffvalue(AliAODTrack* track,Double_t cent,Float_t evzvtx, Int_t parpid)
2525 //This function is called only when applyefficiency=kTRUE; also ensure that "track" is present before calling that function
2527 Float_t effvalue=1.;
2529 if(parpid==unidentified)
2531 effVars[0] = effcorection[5]->GetAxis(0)->FindBin(cent);
2532 effVars[1] = effcorection[5]->GetAxis(1)->FindBin(evzvtx);
2533 effVars[2] = effcorection[5]->GetAxis(2)->FindBin(track->Pt());
2534 effVars[3] = effcorection[5]->GetAxis(3)->FindBin(track->Eta());
2535 effvalue=effcorection[5]->GetBinContent(effVars);
2537 if(parpid==SpPion || parpid==SpKaon)
2539 if(fmesoneffrequired && !fkaonprotoneffrequired && track->Pt()>=fminPtComboeff && track->Pt()<=fmaxPtComboeff)
2541 effVars[0] = effcorection[3]->GetAxis(0)->FindBin(cent);
2542 effVars[1] = effcorection[3]->GetAxis(1)->FindBin(evzvtx);
2543 effVars[2] = effcorection[3]->GetAxis(2)->FindBin(track->Pt());
2544 effVars[3] = effcorection[3]->GetAxis(3)->FindBin(track->Eta());
2545 effvalue=effcorection[3]->GetBinContent(effVars);
2550 effVars[0] = effcorection[0]->GetAxis(0)->FindBin(cent);
2551 effVars[1] = effcorection[0]->GetAxis(1)->FindBin(evzvtx);
2552 effVars[2] = effcorection[0]->GetAxis(2)->FindBin(track->Pt());
2553 effVars[3] = effcorection[0]->GetAxis(3)->FindBin(track->Eta());
2554 effvalue=effcorection[0]->GetBinContent(effVars);
2559 effVars[0] = effcorection[1]->GetAxis(0)->FindBin(cent);
2560 effVars[1] = effcorection[1]->GetAxis(1)->FindBin(evzvtx);
2561 effVars[2] = effcorection[1]->GetAxis(2)->FindBin(track->Pt());
2562 effVars[3] = effcorection[1]->GetAxis(3)->FindBin(track->Eta());
2563 effvalue=effcorection[1]->GetBinContent(effVars);
2568 if(parpid==SpProton)
2570 effVars[0] = effcorection[2]->GetAxis(0)->FindBin(cent);
2571 effVars[1] = effcorection[2]->GetAxis(1)->FindBin(evzvtx);
2572 effVars[2] = effcorection[2]->GetAxis(2)->FindBin(track->Pt());
2573 effVars[3] = effcorection[2]->GetAxis(3)->FindBin(track->Eta());
2574 effvalue=effcorection[2]->GetBinContent(effVars);
2577 if(fkaonprotoneffrequired && !fmesoneffrequired && track->Pt()>=fminPtComboeff && track->Pt()<=fmaxPtComboeff)
2579 if(parpid==SpProton || parpid==SpKaon)
2581 effVars[0] = effcorection[4]->GetAxis(0)->FindBin(cent);
2582 effVars[1] = effcorection[4]->GetAxis(1)->FindBin(evzvtx);
2583 effVars[2] = effcorection[4]->GetAxis(2)->FindBin(track->Pt());
2584 effVars[3] = effcorection[4]->GetAxis(3)->FindBin(track->Eta());
2585 effvalue=effcorection[4]->GetBinContent(effVars);
2588 // Printf("%d %d %d %d %f", effVars[0], effVars[1], effVars[2], effVars[3], fEfficiencyCorrectionAssociated->GetBinContent(effVars));
2589 if(effvalue==0.) effvalue=1.;
2594 //-----------------------------------------------------------------------
2596 Int_t AliTwoParticlePIDCorr::ClassifyTrack(AliAODTrack* track,AliAODVertex* vertex,Float_t magfield)
2599 if(!track) return 0;
2600 Bool_t trackOK = track->TestFilterBit(fFilterBit);
2601 if(!trackOK) return 0;
2602 //select only primary traks(for data & reco MC tracks)
2603 if(fonlyprimarydatareco && track->GetType()!=AliAODTrack::kPrimary) return 0;
2604 if(track->Charge()==0) return 0;
2605 fHistQA[12]->Fill(track->GetTPCNcls());
2608 dz = track->ZAtDCA();
2609 fHistQA[6]->Fill(dxy);
2610 fHistQA[7]->Fill(dz);
2611 Float_t chi2ndf = track->Chi2perNDF();
2612 fHistQA[13]->Fill(chi2ndf);
2613 Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
2614 fHistQA[14]->Fill(nCrossedRowsTPC);
2615 //Float_t ratioCrossedRowsOverFindableClustersTPC = 1.0;
2616 if (track->GetTPCNclsF()>0) {
2617 Float_t ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
2618 fHistQA[15]->Fill(ratioCrossedRowsOverFindableClustersTPC);
2621 Float_t pt=track->Pt();
2622 if(pt< fminPt || pt> fmaxPt) return 0;
2623 if(TMath::Abs(track->Eta())> fmaxeta) return 0;
2624 if(track->Phi()<0. || track->Phi()>2*TMath::Pi()) return 0;
2625 //if (!HasTPCPID(track)) return 0;//trigger & associated particles must have TPC PID,Is it required
2627 if (fdcacut && fDCAXYCut)
2634 AliAODTrack* clone =(AliAODTrack*) track->Clone();
2635 Bool_t success = clone->PropagateToDCA(vertex, magfield, fdcacutvalue, pos, covar);
2640 // Printf("%f", ((AliAODTrack*)part)->DCA());
2641 // Printf("%f", pos[0]);
2642 if (TMath::Abs(pos[0]) > fDCAXYCut->Eval(track->Pt()))
2646 if (fSharedClusterCut >= 0)
2648 Double_t frac = Double_t(((AliAODTrack*)track)->GetTPCnclsS()) / Double_t(((AliAODTrack*)track)->GetTPCncls());
2649 if (frac > fSharedClusterCut)
2652 fHistQA[8]->Fill(pt);
2653 fHistQA[9]->Fill(track->Eta());
2654 fHistQA[10]->Fill(track->Phi());
2657 //________________________________________________________________________________
2658 void AliTwoParticlePIDCorr::CalculateNSigmas(AliAODTrack *track, Bool_t FIllQAHistos)
2660 //This function is called within the func GetParticle() for accepted tracks only i.e.after call of Classifytrack() & for those tracks which have proper TPC PID response . combined nsigma(circular) cut only for particles having pt upto 4.0 Gev/c and beyond that use the asymmetric nsigma cut around pion's mean position in TPC ( while filling the TObjArray for trig & asso )
2661 Float_t pt=track->Pt();
2663 //it is assumed that every track that passed the filterbit have proper TPC response(!!)
2664 Float_t nsigmaTPCkPion =fPID->NumberOfSigmasTPC(track, AliPID::kPion);
2665 Float_t nsigmaTPCkKaon =fPID->NumberOfSigmasTPC(track, AliPID::kKaon);
2666 Float_t nsigmaTPCkProton =fPID->NumberOfSigmasTPC(track, AliPID::kProton);
2668 Float_t nsigmaTOFkProton=999.,nsigmaTOFkKaon=999.,nsigmaTOFkPion=999.;
2669 Float_t nsigmaTPCTOFkProton=999.,nsigmaTPCTOFkKaon=999.,nsigmaTPCTOFkPion=999.;
2671 if(HasTOFPID(track) && pt>fPtTOFPIDmin)
2674 nsigmaTOFkPion =fPID->NumberOfSigmasTOF(track, AliPID::kPion);
2675 nsigmaTOFkKaon =fPID->NumberOfSigmasTOF(track, AliPID::kKaon);
2676 nsigmaTOFkProton =fPID->NumberOfSigmasTOF(track, AliPID::kProton);
2678 nsigmaTPCTOFkPion = TMath::Sqrt(nsigmaTPCkPion*nsigmaTPCkPion+nsigmaTOFkPion*nsigmaTOFkPion);
2679 nsigmaTPCTOFkKaon = TMath::Sqrt(nsigmaTPCkKaon*nsigmaTPCkKaon+nsigmaTOFkKaon*nsigmaTOFkKaon);
2680 nsigmaTPCTOFkProton = TMath::Sqrt(nsigmaTPCkProton*nsigmaTPCkProton+nsigmaTOFkProton*nsigmaTOFkProton);
2686 // if TOF is missing and below fPtTOFPID only the TPC information is used
2687 nsigmaTPCTOFkProton = TMath::Abs(nsigmaTPCkProton);
2688 nsigmaTPCTOFkKaon = TMath::Abs(nsigmaTPCkKaon);
2689 nsigmaTPCTOFkPion = TMath::Abs(nsigmaTPCkPion);
2693 //set data member fnsigmas
2694 fnsigmas[SpPion][NSigmaTPC]=nsigmaTPCkPion;
2695 fnsigmas[SpKaon][NSigmaTPC]=nsigmaTPCkKaon;
2696 fnsigmas[SpProton][NSigmaTPC]=nsigmaTPCkProton;
2698 //for all tracks below fPtTOFPIDmin and also for tracks above fPtTOFPIDmin without proper TOF response these TOF nsigma values will be 999.
2699 fnsigmas[SpPion][NSigmaTOF]=nsigmaTOFkPion;
2700 fnsigmas[SpKaon][NSigmaTOF]=nsigmaTOFkKaon;
2701 fnsigmas[SpProton][NSigmaTOF]=nsigmaTOFkProton;
2703 //for all tracks below fPtTOFPIDmin and also for tracks above fPtTOFPIDmin without proper TOF response these TPCTOF nsigma values will be TMath::Abs(TPC only nsigma)
2704 fnsigmas[SpPion][NSigmaTPCTOF]=nsigmaTPCTOFkPion;
2705 fnsigmas[SpKaon][NSigmaTPCTOF]=nsigmaTPCTOFkKaon;
2706 fnsigmas[SpProton][NSigmaTPCTOF]=nsigmaTPCTOFkProton;
2709 //Fill NSigma SeparationPlot
2710 for(Int_t ipart=0;ipart<NSpecies;ipart++){
2711 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
2712 if((ipid!=NSigmaTPC) && (!HasTOFPID(track)) && track->Pt()<fPtTOFPIDmin)continue;//not filling TOF and combined if no TOF PID
2713 TH2F *h=GetHistogram2D(Form("NSigma_%d_%d",ipart,ipid));
2714 h->Fill(track->Pt(),fnsigmas[ipart][ipid]);
2720 //----------------------------------------------------------------------------
2721 Int_t AliTwoParticlePIDCorr::FindMinNSigma(AliAODTrack *track,Bool_t FillQAHistos)
2723 //this function is always called after calling the function CalculateNSigmas(AliAODTrack *track)
2724 if(fRequestTOFPID && track->Pt()>fPtTOFPIDmin && track->Pt()<=fPtTOFPIDmax && (!HasTOFPID(track)) )return SpUndefined;//so any track having Pt>0.6 && Pt<=4.0 Gev withot having proper TOF response will be defined as SpUndefined
2725 //get the identity of the particle with the minimum Nsigma
2726 Float_t nsigmaPion=999., nsigmaKaon=999., nsigmaProton=999.;
2729 nsigmaProton = TMath::Abs(fnsigmas[SpProton][NSigmaTPC]);
2730 nsigmaKaon = TMath::Abs(fnsigmas[SpKaon][NSigmaTPC]) ;
2731 nsigmaPion = TMath::Abs(fnsigmas[SpPion][NSigmaTPC]) ;
2734 nsigmaProton = TMath::Abs(fnsigmas[SpProton][NSigmaTOF]);
2735 nsigmaKaon = TMath::Abs(fnsigmas[SpKaon][NSigmaTOF]) ;
2736 nsigmaPion = TMath::Abs(fnsigmas[SpPion][NSigmaTOF]) ;
2738 case NSigmaTPCTOF://In case of no TOF matching the combined nsigma is the TPC one
2739 nsigmaProton = TMath::Abs(fnsigmas[SpProton][NSigmaTPCTOF]);
2740 nsigmaKaon = TMath::Abs(fnsigmas[SpKaon][NSigmaTPCTOF]) ;
2741 nsigmaPion = TMath::Abs(fnsigmas[SpPion][NSigmaTPCTOF]) ;
2745 if(track->Pt()<=fPtTOFPIDmax) {
2746 // guess the particle based on the smaller nsigma (within fNSigmaPID)
2747 if( ( nsigmaKaon==nsigmaPion ) && ( nsigmaKaon==nsigmaProton )) return SpUndefined;//it is the default value for the three
2748 if( ( nsigmaKaon < nsigmaPion ) && ( nsigmaKaon < nsigmaProton ) && (nsigmaKaon < fNSigmaPID)){
2750 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
2751 if((ipid!=NSigmaTPC) && (!HasTOFPID(track)) && (track->Pt()<fPtTOFPIDmin))continue;//not filling TOF and combined if no TOF PID
2752 TH2F *h=GetHistogram2D(Form("NSigmaRec_%d_%d",SpKaon,ipid));
2753 h->Fill(track->Pt(),fnsigmas[SpKaon][ipid]);
2758 if( ( nsigmaPion < nsigmaKaon ) && ( nsigmaPion < nsigmaProton ) && (nsigmaPion < fNSigmaPID)) {
2760 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
2761 if((ipid!=NSigmaTPC) && (!HasTOFPID(track)) && (track->Pt()<fPtTOFPIDmin))continue;//not filling TOF and combined if no TOF PID
2762 TH2F *h=GetHistogram2D(Form("NSigmaRec_%d_%d",SpPion,ipid));
2763 h->Fill(track->Pt(),fnsigmas[SpPion][ipid]);
2768 if( ( nsigmaProton < nsigmaKaon ) && ( nsigmaProton < nsigmaPion ) && (nsigmaProton < fNSigmaPID)) {
2770 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
2771 if((ipid!=NSigmaTPC) && (!HasTOFPID(track)) && (track->Pt()<fPtTOFPIDmin))continue;//not filling TOF and combined if no TOF PID
2772 TH2F *h=GetHistogram2D(Form("NSigmaRec_%d_%d",SpProton,ipid));
2773 h->Fill(track->Pt(),fnsigmas[SpProton][ipid]);
2779 // else, return undefined
2782 else {//asymmetric nsigma cut around pion's mean position for tracks having Pt>4.0 Gev
2783 if(fminprotonsigmacut<fnsigmas[SpPion][NSigmaTPC] && fnsigmas[SpPion][NSigmaTPC]<fmaxprotonsigmacut) return SpProton;
2784 if(fminpionsigmacut<fnsigmas[SpPion][NSigmaTPC] && fnsigmas[SpPion][NSigmaTPC]<fmaxpionsigmacut) return SpPion;
2785 // else, return undefined(here we don't detect kaons)
2791 //------------------------------------------------------------------------------------------
2792 Bool_t* AliTwoParticlePIDCorr::GetDoubleCounting(AliAODTrack * trk,Bool_t FIllQAHistos){
2793 //this function is always called after calling the function CalculateNSigmas(AliAODTrack *track)
2795 //if a particle has double counting set fHasDoubleCounting[ipart]=kTRUE
2797 for(Int_t ipart=0;ipart<NSpecies;ipart++)fHasDoubleCounting[ipart]=kFALSE;//array with kTRUE for second (or third) identity of the track
2799 Int_t MinNSigma=FindMinNSigma(trk,kFALSE);//not filling the NSigmaRec histos
2802 if(MinNSigma==SpUndefined)return fHasDoubleCounting;//in case of undefined no Double counting
2804 Float_t nsigmaPion=999., nsigmaKaon=999., nsigmaProton=999.;
2807 nsigmaProton = TMath::Abs(fnsigmas[SpProton][NSigmaTPC]);
2808 nsigmaKaon = TMath::Abs(fnsigmas[SpKaon][NSigmaTPC]) ;
2809 nsigmaPion = TMath::Abs(fnsigmas[SpPion][NSigmaTPC]) ;
2812 nsigmaProton = TMath::Abs(fnsigmas[SpProton][NSigmaTOF]);
2813 nsigmaKaon = TMath::Abs(fnsigmas[SpKaon][NSigmaTOF]) ;
2814 nsigmaPion = TMath::Abs(fnsigmas[SpPion][NSigmaTOF]) ;
2816 case NSigmaTPCTOF://In case of no TOF matching the combined nsigma is the TPC one
2817 nsigmaProton = TMath::Abs(fnsigmas[SpProton][NSigmaTPCTOF]);
2818 nsigmaKaon = TMath::Abs(fnsigmas[SpKaon][NSigmaTPCTOF]) ;
2819 nsigmaPion = TMath::Abs(fnsigmas[SpPion][NSigmaTPCTOF]) ;
2823 //there is chance of overlapping only for particles having pt below 4.0 GEv
2825 if(nsigmaPion<fNSigmaPID && MinNSigma!=SpPion)fHasDoubleCounting[SpPion]=kTRUE;
2826 if(nsigmaKaon<fNSigmaPID && MinNSigma!=SpKaon)fHasDoubleCounting[SpKaon]=kTRUE;
2827 if(nsigmaProton<fNSigmaPID && MinNSigma!=SpProton)fHasDoubleCounting[SpProton]=kTRUE;
2832 //fill NSigma distr for double counting
2833 for(Int_t ipart=0;ipart<NSpecies;ipart++){
2834 if(fHasDoubleCounting[ipart]){
2835 for(Int_t ipid=0;ipid<=NSigmaPIDType;ipid++){
2836 if((ipid!=NSigmaTPC) && (!HasTOFPID(trk)) && (trk->Pt()<fPtTOFPIDmin))continue;//not filling TOF and combined if no TOF PID
2837 TH2F *h=GetHistogram2D(Form("NSigmaDC_%d_%d",ipart,ipid));
2838 h->Fill(trk->Pt(),fnsigmas[ipart][ipid]);
2845 return fHasDoubleCounting;
2848 //////////////////////////////////////////////////////////////////////////////////////////////////
2849 Int_t AliTwoParticlePIDCorr::GetParticle(AliAODTrack * trk, Bool_t FIllQAHistos){
2850 //return the specie according to the minimum nsigma value
2851 //no double counting, this has to be evaluated using CheckDoubleCounting()
2853 Int_t ID=SpUndefined;
2855 CalculateNSigmas(trk,FIllQAHistos);//fill the data member fnsigmas with the nsigmas value [ipart][iPID]
2857 ID=FindMinNSigma(trk,FIllQAHistos);
2859 if(fUseExclusiveNSigma){ //if one particle has double counting and exclusive nsigma is requested ID = kSpUndefined
2861 HasDC=GetDoubleCounting(trk,FIllQAHistos);
2862 for(Int_t ipart=0;ipart<NSpecies;ipart++){
2863 if(HasDC[ipart]==kTRUE) ID = SpUndefined;
2867 //Fill PID signal plot
2868 if(ID != SpUndefined){
2869 for(Int_t idet=0;idet<fNDetectors;idet++){
2870 TH2F *h=GetHistogram2D(Form("PID_%d_%d",idet,ID));
2871 if(idet==fITS)h->Fill(trk->P(),trk->GetITSsignal()*trk->Charge());
2872 if(idet==fTPC)h->Fill(trk->P(),trk->GetTPCsignal()*trk->Charge());
2873 if(idet==fTOF && HasTOFPID(trk))h->Fill(trk->P(),GetBeta(trk)*trk->Charge());
2876 //Fill PID signal plot without cuts
2877 for(Int_t idet=0;idet<fNDetectors;idet++){
2878 TH2F *h=GetHistogram2D(Form("PIDAll_%d",idet));
2879 if(idet==fITS)h->Fill(trk->P(),trk->GetITSsignal()*trk->Charge());
2880 if(idet==fTPC)h->Fill(trk->P(),trk->GetTPCsignal()*trk->Charge());
2881 if(idet==fTOF && HasTOFPID(trk))h->Fill(trk->P(),GetBeta(trk)*trk->Charge());
2887 //-------------------------------------------------------------------------------------
2889 AliTwoParticlePIDCorr::HasTPCPID(AliAODTrack *track) const
2892 AliPIDResponse::EDetPidStatus statustpc = fPID->CheckPIDStatus(AliPIDResponse::kTPC,track);
2893 if(statustpc!=AliPIDResponse::kDetPidOk) return kFALSE;
2894 //ULong_t status=track->GetStatus();
2895 //if (!( (status & AliAODTrack::kTPCpid ) == AliAODTrack::kTPCpid )) return kFALSE;//remove light nuclei
2896 //if (track->GetTPCsignal() <= 0.) return kFALSE;
2897 // if(track->GetTPCsignalN() < 60) return kFALSE;//tracks with TPCsignalN< 60 have questionable dEdx,cutting on TPCsignalN > 70 or > 60 shouldn't make too much difference in statistics,also it is IMO safe to use TPC also for MIPs.
2901 //___________________________________________________________
2904 AliTwoParticlePIDCorr::HasTOFPID(AliAODTrack *track) const
2906 // check TOF matched track
2907 //ULong_t status=track->GetStatus();
2908 //if (!( (status & AliAODTrack::kITSin ) == AliAODTrack::kITSin )) return kFALSE;
2909 AliPIDResponse::EDetPidStatus statustof = fPID->CheckPIDStatus(AliPIDResponse::kTOF,track);
2910 if(statustof!= AliPIDResponse::kDetPidOk) return kFALSE;
2911 if(track->Pt()<=fPtTOFPIDmin) return kFALSE;
2912 //if(!((status & AliAODTrack::kTOFpid ) == AliAODTrack::kTOFpid )) return kFALSE;
2913 //Float_t probMis = fPIDresponse->GetTOFMismatchProbability(track);
2914 // if (probMis > 0.01) return kFALSE;
2915 if(fRemoveTracksT0Fill)
2917 Int_t startTimeMask = fPID->GetTOFResponse().GetStartTimeMask(track->P());
2918 if (startTimeMask < 0)return kFALSE;
2923 //________________________________________________________________________
2924 Double_t AliTwoParticlePIDCorr :: GetBeta(AliAODTrack *track)
2926 //it is called only when TOF PID is available
2927 //TOF beta calculation
2928 Double_t tofTime=track->GetTOFsignal();
2930 Double_t c=TMath::C()*1.E-9;// m/ns
2931 Float_t startTime = fPID->GetTOFResponse().GetStartTime(((AliVTrack*)track)->P());//in ps
2932 Double_t length= fPID->GetTOFResponse().GetExpectedSignal(track,AliPID::kElectron)*1E-3*c;
2933 tofTime -= startTime; // subtract startTime to the signal
2934 Double_t tof= tofTime*1E-3; // ns, average T0 fill subtracted, no info from T0detector
2940 Double_t p = track->P();
2941 Double_t time=track->GetTOFsignal()-fPID->GetTOFResponse().GetStartTime(p);
2943 track->GetIntegratedTimes(timei);
2944 return timei[0]/time;
2947 //------------------------------------------------------------------------------------------------------
2949 Float_t AliTwoParticlePIDCorr::GetInvMassSquared(Float_t pt1, Float_t eta1, Float_t phi1, Float_t pt2, Float_t eta2, Float_t phi2, Float_t m0_1, Float_t m0_2)
2951 // calculate inv mass squared
2952 // same can be achieved, but with more computing time with
2953 /*TLorentzVector photon, p1, p2;
2954 p1.SetPtEtaPhiM(triggerParticle->Pt(), triggerEta, triggerParticle->Phi(), 0.510e-3);
2955 p2.SetPtEtaPhiM(particle->Pt(), eta[j], particle->Phi(), 0.510e-3);
2959 Float_t tantheta1 = 1e10;
2961 if (eta1 < -1e-10 || eta1 > 1e-10)
2962 tantheta1 = 2 * TMath::Exp(-eta1) / ( 1 - TMath::Exp(-2*eta1));
2964 Float_t tantheta2 = 1e10;
2965 if (eta2 < -1e-10 || eta2 > 1e-10)
2966 tantheta2 = 2 * TMath::Exp(-eta2) / ( 1 - TMath::Exp(-2*eta2));
2968 Float_t e1squ = m0_1 * m0_1 + pt1 * pt1 * (1.0 + 1.0 / tantheta1 / tantheta1);
2969 Float_t e2squ = m0_2 * m0_2 + pt2 * pt2 * (1.0 + 1.0 / tantheta2 / tantheta2);
2971 Float_t mass2 = m0_1 * m0_1 + m0_2 * m0_2 + 2 * ( TMath::Sqrt(e1squ * e2squ) - ( pt1 * pt2 * ( TMath::Cos(phi1 - phi2) + 1.0 / tantheta1 / tantheta2 ) ) );
2975 //---------------------------------------------------------------------------------
2977 Float_t AliTwoParticlePIDCorr::GetInvMassSquaredCheap(Float_t pt1, Float_t eta1, Float_t phi1, Float_t pt2, Float_t eta2, Float_t phi2, Float_t m0_1, Float_t m0_2)
2979 // calculate inv mass squared approximately
2981 Float_t tantheta1 = 1e10;
2983 if (eta1 < -1e-10 || eta1 > 1e-10)
2985 Float_t expTmp = 1.0-eta1+eta1*eta1/2-eta1*eta1*eta1/6+eta1*eta1*eta1*eta1/24;
2986 tantheta1 = 2.0 * expTmp / ( 1.0 - expTmp*expTmp);
2989 Float_t tantheta2 = 1e10;
2990 if (eta2 < -1e-10 || eta2 > 1e-10)
2992 Float_t expTmp = 1.0-eta2+eta2*eta2/2-eta2*eta2*eta2/6+eta2*eta2*eta2*eta2/24;
2993 tantheta2 = 2.0 * expTmp / ( 1.0 - expTmp*expTmp);
2996 Float_t e1squ = m0_1 * m0_1 + pt1 * pt1 * (1.0 + 1.0 / tantheta1 / tantheta1);
2997 Float_t e2squ = m0_2 * m0_2 + pt2 * pt2 * (1.0 + 1.0 / tantheta2 / tantheta2);
3000 Float_t deltaPhi = TMath::Abs(phi1 - phi2);
3001 while (deltaPhi > TMath::TwoPi())
3002 deltaPhi -= TMath::TwoPi();
3003 if (deltaPhi > TMath::Pi())
3004 deltaPhi = TMath::TwoPi() - deltaPhi;
3006 Float_t cosDeltaPhi = 0;
3007 if (deltaPhi < TMath::Pi()/3)
3008 cosDeltaPhi = 1.0 - deltaPhi*deltaPhi/2 + deltaPhi*deltaPhi*deltaPhi*deltaPhi/24;
3009 else if (deltaPhi < 2*TMath::Pi()/3)
3010 cosDeltaPhi = -(deltaPhi - TMath::Pi()/2) + 1.0/6 * TMath::Power((deltaPhi - TMath::Pi()/2), 3);
3012 cosDeltaPhi = -1.0 + 1.0/2.0*(deltaPhi - TMath::Pi())*(deltaPhi - TMath::Pi()) - 1.0/24.0 * TMath::Power(deltaPhi - TMath::Pi(), 4);
3014 Float_t mass2 = m0_1 * m0_1 + m0_2 * m0_2 + 2 * ( TMath::Sqrt(e1squ * e2squ) - ( pt1 * pt2 * ( cosDeltaPhi + 1.0 / tantheta1 / tantheta2 ) ) );
3016 // Printf(Form("%f %f %f %f %f %f %f %f %f", pt1, eta1, phi1, pt2, eta2, phi2, m0_1, m0_2, mass2));
3020 //--------------------------------------------------------------------------------
3021 Float_t AliTwoParticlePIDCorr::GetDPhiStar(Float_t phi1, Float_t pt1, Float_t charge1, Float_t phi2, Float_t pt2, Float_t charge2, Float_t radius, Float_t bSign)
3024 // calculates dphistar
3027 Float_t dphistar = phi1 - phi2 - charge1 * bSign * TMath::ASin(0.075 * radius / pt1) + charge2 * bSign * TMath::ASin(0.075 * radius / pt2);
3029 static const Double_t kPi = TMath::Pi();
3032 // if (dphistar > 2 * kPi)
3033 // dphistar -= 2 * kPi;
3034 // if (dphistar < -2 * kPi)
3035 // dphistar += 2 * kPi;
3038 dphistar = kPi * 2 - dphistar;
3039 if (dphistar < -kPi)
3040 dphistar = -kPi * 2 - dphistar;
3041 if (dphistar > kPi) // might look funny but is needed
3042 dphistar = kPi * 2 - dphistar;
3046 //_________________________________________________________________________
3047 void AliTwoParticlePIDCorr ::DefineEventPool()
3049 Int_t MaxNofEvents=1000;
3050 const Int_t NofVrtxBins=10+(1+10)*2;
3051 Double_t ZvrtxBins[NofVrtxBins+1]={ -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10,
3052 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
3053 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210
3055 if (fSampleType=="pp"){
3056 const Int_t NofCentBins=4;
3057 Double_t CentralityBins[NofCentBins+1]={0.,20., 40.,60.,200.1};//Is This binning is fine for pp, or we don't require them....
3058 fPoolMgr = new AliEventPoolManager(MaxNofEvents,fMaxNofMixingTracks,NofCentBins,CentralityBins,NofVrtxBins,ZvrtxBins);
3060 if (fSampleType=="pPb" || fSampleType=="PbPb")
3062 const Int_t NofCentBins=15;
3063 Double_t CentralityBins[NofCentBins+1]={0., 1., 2., 3., 4., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90., 100.1 };
3064 fPoolMgr = new AliEventPoolManager(MaxNofEvents,fMaxNofMixingTracks,NofCentBins,CentralityBins,NofVrtxBins,ZvrtxBins);
3066 fPoolMgr->SetTargetValues(fMaxNofMixingTracks, 0.1, 5);
3068 //if(!fPoolMgr) return kFALSE;
3072 //------------------------------------------------------------------------
3073 Double_t* AliTwoParticlePIDCorr::GetBinning(const char* configuration, const char* tag, Int_t& nBins)
3075 // This method is a copy from AliUEHist::GetBinning
3076 // takes the binning from <configuration> identified by <tag>
3077 // configuration syntax example:
3078 // eta: 2.4, -2.3, -2.2, -2.1, -2.0, -1.9, -1.8, -1.7, -1.6, -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, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4
3081 // returns bin edges which have to be deleted by the caller
3083 TString config(configuration);
3084 TObjArray* lines = config.Tokenize("\n");
3085 for (Int_t i=0; i<lines->GetEntriesFast(); i++)
3087 TString line(lines->At(i)->GetName());
3088 if (line.BeginsWith(TString(tag) + ":"))
3090 line.Remove(0, strlen(tag) + 1);
3091 line.ReplaceAll(" ", "");
3092 TObjArray* binning = line.Tokenize(",");
3093 Double_t* bins = new Double_t[binning->GetEntriesFast()];
3094 for (Int_t j=0; j<binning->GetEntriesFast(); j++)
3095 bins[j] = TString(binning->At(j)->GetName()).Atof();
3097 nBins = binning->GetEntriesFast() - 1;
3106 AliFatal(Form("Tag %s not found in %s", tag, configuration));
3109 //________________________________________________________________________
3110 void AliTwoParticlePIDCorr::Terminate(Option_t *)
3112 // Draw result to screen, or perform fitting, normalizations
3113 // Called once at the end of the query
3114 fOutput = dynamic_cast<TList*> (GetOutputData(1));
3115 if(!fOutput) { Printf("ERROR: could not retrieve TList fOutput"); return; }
3119 //------------------------------------------------------------------