]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
o macros and classes for Raa of 2010 data (Ionut)
authorwiechula <wiechula@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 10 May 2012 06:03:44 +0000 (06:03 +0000)
committerwiechula <wiechula@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 10 May 2012 06:03:44 +0000 (06:03 +0000)
PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AddTask_iarsene_dst.C [new file with mode: 0644]
PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliAnalysisTaskCorrelationTree.cxx [new file with mode: 0644]
PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliAnalysisTaskCorrelationTree.h [new file with mode: 0644]
PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliCorrelationReducedEvent.cxx [new file with mode: 0644]
PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliCorrelationReducedEvent.h [new file with mode: 0644]
PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/DstCommonMacros.C [new file with mode: 0644]
PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/RunDstPbPbJpsiAnalysis.C [new file with mode: 0644]

diff --git a/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AddTask_iarsene_dst.C b/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AddTask_iarsene_dst.C
new file mode 100644 (file)
index 0000000..4d9d19f
--- /dev/null
@@ -0,0 +1,1011 @@
+//__________________________________________________________________________________________
+AliAnalysisTask *AddTask_iarsene_dst(){
+  //get the current analysis manager
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) {
+    Error("AddTask_iarsene_dst", "No analysis manager found.");
+    return 0;
+  }
+
+  //Do we have an MC handler?
+  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);
+  
+  //Get the current train configuration
+  //TString trainConfig=gSystem->Getenv("CONFIG_FILE");
+  
+  gROOT->LoadMacro("AliCorrelationReducedEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTaskCorrelationTree.cxx+g");
+  
+  //create task and add it to the manager
+  AliAnalysisTaskCorrelationTree *task=new AliAnalysisTaskCorrelationTree("DSTTreeMaker");
+  //if(trainConfig.Contains("PbPb")) task->SetTriggerMask(AliVEvent::kMB+AliVEvent::kCentral+AliVEvent::kSemiCentral);
+  //if(trainConfig=="pp") task->SetRejectPileup();
+  if(!hasMC) task->UsePhysicsSelection(kFALSE);
+  mgr->AddTask(task);
+  
+  
+  task->SetEventFilter(CreateEventFilter());
+  task->SetTrackFilter(CreateGlobalTrackFilter());
+  task->SetFlowTrackFilter(CreateFlowTrackFilter());
+  task->SetK0sPionCuts(CreateK0sPionCuts());
+  task->SetLambdaProtonCuts(CreateLambdaProtonCuts());
+  task->SetLambdaPionCuts(CreateLambdaPionCuts());
+  task->SetK0sCuts(CreateK0sCuts());
+  task->SetK0sMassRange(0.44,0.55);
+  task->SetLambdaMassRange(1.090,1.14);
+  task->SetLambdaCuts(CreateLambdaCuts());
+  task->SetV0Histograms(CreateV0Histograms());
+  
+  task->AddDielectron(ConfigDielectron(0));   // J/psi -> e+e-
+  task->AddDielectron(ConfigDielectron(1));   // phi -> K+K-
+  
+  //create output container
+  AliAnalysisDataContainer *coutput1 =
+    mgr->CreateContainer("diele_defaultTree",
+                         TChain::Class(),
+                         AliAnalysisManager::kExchangeContainer,
+                         "diele_default");
+  
+  AliAnalysisDataContainer *cOutputHist1 =
+    mgr->CreateContainer("qaHistos",
+                         TList::Class(),
+                         AliAnalysisManager::kOutputContainer,
+                         "dst_qaHistos.root");
+
+  AliAnalysisDataContainer *cOutputHist2 =
+    mgr->CreateContainer("dstTree",
+                         TTree::Class(),
+                         AliAnalysisManager::kOutputContainer,
+                         "dstTree.root");
+  
+  AliAnalysisDataContainer *cOutputHist3 =
+    mgr->CreateContainer("friendTree",
+                         TTree::Class(),
+                         AliAnalysisManager::kOutputContainer,
+                         "dstTree_friend.root");
+  cout << "output containers: " << endl
+       << cOutputHist1 << endl
+       << cOutputHist2 << endl
+       << cOutputHist3 << endl;
+
+  mgr->ConnectInput(task,  0, mgr->GetCommonInputContainer());
+  mgr->ConnectOutput(task, 0, coutput1 );
+  mgr->ConnectOutput(task, 1, cOutputHist1);
+  //mgr->ConnectOutput(task, 2, cOutputHist2);
+  //mgr->ConnectOutput(task, 3, cOutputHist3);
+  mgr->ConnectOutput(task, 2, cOutputHist3);
+  
+  return task;
+}
+
+
+//_______________________________________________________________________________________________
+AliAnalysisCuts* CreateEventFilter() {
+  //
+  // Event wise cuts
+  //
+  AliDielectronEventCuts *eventCuts=new AliDielectronEventCuts("eventCuts","Vertex Track && |vtxZ|<10 && ncontrib>0");
+  //eventCuts->SetRequireVertex();
+  //eventCuts->SetMinVtxContributors(1);
+  //eventCuts->SetVertexZ(-10.,10.);
+  return eventCuts;
+}
+
+
+//_______________________________________________________________________________________________
+AliAnalysisCuts* CreateGlobalTrackFilter() {
+  //
+  // Cuts for tracks to be written in the dst
+  //
+  AliDielectronCutGroup* cuts = new AliDielectronCutGroup("cuts","cuts",AliDielectronCutGroup::kCompAND);
+  // general ESD cuts ---------------------------------
+  AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts;
+  // basic track quality cuts  (basicQ)
+  //esdTrackCuts->SetMaxDCAToVertexZ(10.0);
+  //esdTrackCuts->SetMaxDCAToVertexXY(3.0);
+  //esdTrackCuts->SetEtaRange( -0.9 , 0.9 );
+  //esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+  //  esdTrackCuts->SetRequireITSRefit(kTRUE);
+  //esdTrackCuts->SetRequireTPCRefit(kTRUE);
+  esdTrackCuts->SetPRange(.1,1e30);
+  //esdTrackCuts->SetMinNClustersTPC(60);
+  //esdTrackCuts->SetMaxChi2PerClusterTPC(4);
+  //  esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+  //  esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kFirst);
+  cuts->AddCut(esdTrackCuts);
+  
+  return cuts;
+}
+
+
+//_______________________________________________________________________________________________
+AliAnalysisCuts* CreateFlowTrackFilter() {
+  //
+  // Cuts for tracks to be used for the event plane q-vector
+  // These cuts are applied aditionally to the global track cuts
+  //
+  AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts;
+  esdTrackCuts->SetPtRange(0.2,2.0);
+  esdTrackCuts->SetEtaRange(-0.8, 0.8);
+  esdTrackCuts->SetMinNClustersTPC(70);
+  return esdTrackCuts;
+}
+
+
+//_______________________________________________________________________________________________
+AliAnalysisCuts* CreateK0sPionCuts() {
+  //
+  // Cuts on the K0s pions (tracking cuts, pid cuts, ...) 
+  //
+  AliESDtrackCuts *pionCuts = new AliESDtrackCuts;
+  pionCuts->SetPtRange(0.15,100.0);
+  return pionCuts;
+}
+
+
+//_______________________________________________________________________________________________
+AliAnalysisCuts* CreateLambdaPionCuts() {
+  //
+  // Cuts on the Lambda pions (tracking cuts, pid cuts, ...) 
+  //
+  AliESDtrackCuts *pionCuts = new AliESDtrackCuts;
+  pionCuts->SetPtRange(0.15,100.0);
+  return pionCuts;
+}
+
+
+//_______________________________________________________________________________________________
+AliAnalysisCuts* CreateLambdaProtonCuts() {
+  //
+  // Cuts on the Lambda protons (tracking cuts, pid cuts, ...) 
+  //
+  AliESDtrackCuts *protonCuts = new AliESDtrackCuts;
+  protonCuts->SetPtRange(0.15,100.0);
+  return protonCuts;
+}
+
+
+//______________________________________________________________________________________
+AliESDv0Cuts* CreateK0sCuts() {
+  //
+  // Cuts on the V0s with K0s hypothesis
+  //
+  
+  AliESDv0Cuts *cuts=new AliESDv0Cuts();
+  //cuts->SetMinDcaPosToVertex(-1);
+  //cuts->SetMinDcaNegToVertex(-1);
+  //cuts->SetMaxChi2(10);
+  //cuts->SetMaxDcaV0Daughters(0.3);
+  //cuts->SetMinRadius(3.0);
+  //cuts->SetMaxRadius(90.0);
+  //cuts->SetMinCosinePointingAngle(0.9);
+  //cuts->SetRequireOnFlyStatus(kTRUE);
+  //cuts->SetMaxDcaV0ToVertex(0.5);
+  //cuts->SetPRange(0.,1.0e10);
+  //cuts->SetPtRange(0.,1.0e10);
+  return cuts;
+}
+
+
+//______________________________________________________________________________________
+AliESDv0Cuts* CreateLambdaCuts() {
+  //
+  // Cuts on the V0s with Lambda hypothesis
+  //
+  
+  AliESDv0Cuts *cuts=new AliESDv0Cuts();
+  //cuts->SetMinDcaPosToVertex(-1);
+  //cuts->SetMinDcaNegToVertex(-1);
+  //cuts->SetMaxChi2(10);
+  //cuts->SetMaxDcaV0Daughters(0.3);
+  //cuts->SetMinRadius(3.0);
+  //cuts->SetMaxRadius(90.0);
+  //cuts->SetMinCosinePointingAngle(0.9);
+  //cuts->SetRequireOnFlyStatus(kTRUE);
+  //cuts->SetMaxDcaV0ToVertex(0.5);
+  //cuts->SetPRange(0.,1.0e10);
+  //cuts->SetPtRange(0.,1.0e10);
+  return cuts;
+}
+
+
+//______________________________________________________________________________________
+AliDielectronHistos* CreateV0Histograms()
+{
+  //
+  // Initialise the histograms
+  //
+  
+  //Setup histogram Manager
+  AliDielectronHistos *histos=new AliDielectronHistos("V0Histograms","");
+        
+  //add histograms to Track classes ---------------------------------------------------------------------------
+  histos->SetReservedWords("V0Track");
+  
+  //Track classes
+  histos->AddClass("V0Track_Pos"); histos->AddClass("V0Track_Neg"); 
+  
+  // kinematic acceptance histograms
+  histos->UserHistogram("V0Track","Pt","Pt;Pt (GeV/c);#tracks",400,0,20.,AliDielectronVarManager::kPt);
+  histos->UserHistogram("V0Track","Eta_P","Eta_P;#eta;P (GeV/c)",40, -1.0, +1.0, 200,0,10., AliDielectronVarManager::kEta, AliDielectronVarManager::kP);
+  histos->UserHistogram("V0Track","Eta_TRDPhi","Eta Phi Map; Eta; Phi;#tracks",
+                        40,-1,1,200,-3.15,3.15,AliDielectronVarManager::kEta,AliDielectronVarManager::kTRDphi);  
+
+  // DCA diagnostic histograms
+  histos->UserHistogram("V0Track","dXY","dXY;dXY (cm);#tracks",500,-1.,1.,AliDielectronVarManager::kImpactParXY);
+  histos->UserHistogram("V0Track","dZ","dZ;dZ (cm);#tracks",600,-3.,3.,AliDielectronVarManager::kImpactParZ);
+  histos->UserHistogram("V0Track","dZ_dXY","dZ_dXY;dZ (cm);dXY (cm)",600,-3.,3.,500,-1.,1.,AliDielectronVarManager::kImpactParZ, AliDielectronVarManager::kImpactParXY);
+  histos->UserHistogram("V0Track","P_dXY","P_dXY;P (GeV/c);dXY (cm)",200,0.,10.,500,-1.,1.,AliDielectronVarManager::kP, AliDielectronVarManager::kImpactParXY);
+  histos->UserHistogram("V0Track","P_dZ","P_dZ;P (GeV/c);dZ (cm)",200,0.,10.,600,-3.,3.,AliDielectronVarManager::kP, AliDielectronVarManager::kImpactParZ);
+
+  // ITS
+  histos->UserHistogram("V0Track","ITSsignal","ITS signal;ITS dE/dx",1000,0.0,1000.0, AliDielectronVarManager::kITSsignal);  
+  histos->UserHistogram("V0Track","ITSsignal_P","ITS signal vs P;P (GeV/c); ITS dE/dx",300, 0.0, 3.0, 200,0.0,1000.0, AliDielectronVarManager::kP, AliDielectronVarManager::kITSsignal);
+  
+  // TPC
+  histos->UserHistogram("V0Track","TPCchi2","#chi^{2}/cluster;#chi^{2}/cluster;#tracks",200,0.0,5.0, AliDielectronVarManager::kTPCchi2Cl);
+  histos->UserHistogram("V0Track","Pt_TPCchi2","#chi^{2}/cluster vs pt;p_{T} (GeV/c);#chi^{2}/cluster",400,0.,20., 200,0.0,5.0,
+                       AliDielectronVarManager::kPt,AliDielectronVarManager::kTPCchi2Cl);
+  histos->UserHistogram("V0Track","TPCnCls","Number of Clusters TPC;TPC number clusters;#tracks",160,-0.5,159.5, AliDielectronVarManager::kNclsTPC);
+  histos->UserHistogram("V0Track","Phi_TPCnCls","Number of Clusters TPC vs #phi;#phi (rad.);TPC number clusters",200,0,6.285, 160,-0.5,159.5,
+                       AliDielectronVarManager::kPhi,AliDielectronVarManager::kNclsTPC);
+  histos->UserHistogram("V0Track","Pin_TPCnCls","Number of Clusters TPC vs TPC inner param P;p (GeV/c);TPC number clusters",400,0,20., 160,-0.5,159.5,
+                       AliDielectronVarManager::kPIn, AliDielectronVarManager::kNclsTPC);
+  histos->UserHistogram("V0Track","TPCnCls_dEdx","Number of Clusters TPC vs dE/dx; TPC number clusters; dE/dx (arb.units)", 160,-0.5,159.5, 200,0,200.,
+                       AliDielectronVarManager::kNclsTPC, AliDielectronVarManager::kTPCsignal);
+  histos->UserHistogram("V0Track","dEdx_P","dEdx;P [GeV];TPC signal (arb units);#tracks",
+                        400,0.2,20.,200,0.,200.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCsignal);
+  histos->UserHistogram("V0Track","dEdx_Eta","dEdx;#eta;TPC signal (arb units);#tracks",
+                        110,-1.1,1.1,200,0.,200.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCsignal);
+  histos->UserHistogram("V0Track","TPCnSigmaEle_P","TPC number of sigmas Electrons;P [GeV];TPC number of sigmas Electrons;#tracks",
+                        400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaEle);
+  histos->UserHistogram("V0Track","TPCnSigmaEle_Eta","TPC number of sigmas Electrons;#eta;TPC number of sigmas Electrons;#tracks",
+                        110,-1.1,1.1,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaEle);  
+  histos->UserHistogram("V0Track","TPCnSigmaPio_P","TPC number of sigmas Pions;P [GeV];TPC number of sigmas Pions;#tracks",
+                       400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaPio);
+  histos->UserHistogram("V0Track","TPCnSigmaPio_Eta","TPC number of sigmas Pions;#eta;TPC number of sigmas Pions;#tracks",
+                        110,-1.1,1.1,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaPio);  
+  histos->UserHistogram("V0Track","TPCnSigmaKao_P","TPC number of sigmas Kaons;P [GeV];TPC number of sigmas Kaons;#tracks",
+                       400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaKao);
+  histos->UserHistogram("V0Track","TPCnSigmaKao_Eta","TPC number of sigmas Kaons;#eta;TPC number of sigmas Kaons;#tracks",
+                        110,-1.1,1.1,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaKao);  
+  histos->UserHistogram("V0Track","TPCnSigmaPro_P","TPC number of sigmas Protons;P [GeV];TPC number of sigmas Protons;#tracks",
+                       400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaPro);
+  histos->UserHistogram("V0Track","TPCnSigmaPro_Eta","TPC number of sigmas Protons;#eta;TPC number of sigmas Protons;#tracks",
+                        110,-1.1,1.1,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaPro);  
+  histos->UserHistogram("V0Track","POut","Track POut;P (GeV/c)",100,0.0,10.0, AliDielectronVarManager::kPOut);
+
+  // TOF
+  histos->UserHistogram("V0Track","Pin_TOFsignal","TOF signal vs TPC inner param P; P [GeV]; TOF signal",
+                       120,0.0,6.,1200,0.,120000.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFsignal);
+  histos->UserHistogram("V0Track","Pin_TOFbeta","TOF #beta vs TPC inner param P; P [GeV]; TOF #beta",
+                       120,0.0,6.,120,0.,1.2,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFbeta);
+  histos->UserHistogram("V0Track","TOFnSigmaPio_Pin","TOF number of sigmas Pions;P [GeV];TOF number of sigmas Pions;#tracks",
+                       400,0.2,20.,200,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFnSigmaPio);
+  histos->UserHistogram("V0Track","TOFnSigmaPio_eta","TOF number of sigmas Pions vs #eta;#eta;TOF number of sigmas Pions;#tracks",
+                       100,-1.2,1.2,200,-10.,10.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTOFnSigmaPio);
+  histos->UserHistogram("V0Track","TOFnSigmaKao_Pin","TOF number of sigmas Kaons;P [GeV];TOF number of sigmas Kaons;#tracks",
+                       400,0.2,20.,200,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFnSigmaKao);
+  histos->UserHistogram("V0Track","TOFnSigmaKao_eta","TOF number of sigmas Kaons vs #eta;#eta;TOF number of sigmas Kaons;#tracks",
+                       100,-1.2,1.2,200,-10.,10.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTOFnSigmaKao);
+  histos->UserHistogram("V0Track","TOFnSigmaPro_Pin","TOF number of sigmas Protons;P [GeV];TOF number of sigmas Protons;#tracks",
+                       400,0.2,20.,200,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFnSigmaPro);
+  histos->UserHistogram("V0Track","TOFnSigmaPro_eta","TOF number of sigmas Protons vs #eta;#eta;TOF number of sigmas Protons;#tracks",
+                       100,-1.2,1.2,200,-10.,10.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTOFnSigmaPro);
+  return histos;
+}
+
+
+//____________________________________________________________________________________________
+AliDielectron* ConfigDielectron(Int_t cutDefinition)
+{
+  //
+  // Setup the instance of an AliDielectron
+  //
+  const Char_t* dieleNames[2] = {"JpsiToEE", "PhiToKK"};
+    
+  AliDielectron *die =
+    new AliDielectron(dieleNames[cutDefinition],
+                      Form("Track cuts: %s", dieleNames));
+  //die->SetEstimatorFilename("$TRAIN_ROOT/util/dielectron/dielectron/estimators.root");
+  if(cutDefinition==0) {       // J/psi -> e+e-
+    die->SetLegPdg(11,11);
+    die->SetMotherPdg(443);
+  }
+  if(cutDefinition==1) {       // phi -> K+K-
+    die->SetLegPdg(321,321);
+    die->SetMotherPdg(333);
+  }
+  
+  // cut setup
+  SetupDielectronTrackCuts(die,cutDefinition);
+  SetupDielectronPairCuts(die,cutDefinition);
+
+  // Set MC signals
+  SetDielectronMCSignals(die);
+  
+  //
+  // histogram setup
+  // only if an AliDielectronHistos object is attached to the
+  // dielectron framework histograms will be filled
+  //
+  InitDielectronHistograms(die,cutDefinition);
+  //setup eta correction
+  SetEtaCorrection();
+
+  return die;
+}
+
+//______________________________________________________________________________________
+void SetupDielectronTrackCuts(AliDielectron *die, Int_t cutDefinition)
+{
+  //
+  // Setup the track cuts
+  //
+
+  AliDielectronCutGroup* cuts = new AliDielectronCutGroup("cuts","cuts",AliDielectronCutGroup::kCompAND);
+  die->GetTrackFilter().AddCuts(cuts);
+  //ESD quality cuts  
+  AliESDtrackCuts *esdTrackCuts = new AliESDtrackCuts;
+  // basic track quality cuts  (basicQ)
+  esdTrackCuts->SetMaxDCAToVertexZ(3.0);
+  esdTrackCuts->SetMaxDCAToVertexXY(1.0);
+  if(cutDefinition==1) {
+    esdTrackCuts->SetMaxDCAToVertexZ(0.3);
+    esdTrackCuts->SetMaxDCAToVertexXY(0.3);
+  }
+  if(cutDefinition==1) esdTrackCuts->SetEtaRange(-1.0,1.0);
+  if(cutDefinition==0) esdTrackCuts->SetEtaRange(-0.9,0.9);
+  esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+  //esdTrackCuts->SetRequireITSRefit(kTRUE);
+  if(cutDefinition==0) esdTrackCuts->SetRequireTPCRefit(kTRUE);
+  if(cutDefinition==0) esdTrackCuts->SetPRange(.9,1e30);   // for J/psi
+  if(cutDefinition==1) esdTrackCuts->SetPRange(.1,1e30);   // for phi
+  if(cutDefinition==0) esdTrackCuts->SetMinNClustersTPC(60);
+  if(cutDefinition==0) esdTrackCuts->SetMaxChi2PerClusterTPC(4);
+  //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+  cuts->AddCut(esdTrackCuts);
+    
+  Bool_t hasMC=(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler()!=0x0);
+
+  AliDielectronPID *pid = new AliDielectronPID("PID","PID cut");
+  if(cutDefinition==0) {   // J/psi->ee, phi->ee
+    pid->AddCut(AliDielectronPID::kTPC,AliPID::kElectron,-3.0, 4.5, 0.0, 0.0,  kFALSE, AliDielectronPID::kRequire); // TPC 3-sigma inclusion for electron
+    pid->AddCut(AliDielectronPID::kTPC,AliPID::kProton,  -100.0, 2.0, 0.0, 10.0, kTRUE,  AliDielectronPID::kRequire); // TPC 3.0-sigma exclusion for proton
+//    pid->AddCut(AliDielectronPID::kTPC,AliPID::kKaon,    -3.0, 3.0, 0.0, 10.0, kTRUE,  AliDielectronPID::kRequire); // TPC 3.0-sigma exclusion for kaon
+//    pid->AddCut(AliDielectronPID::kTPC,AliPID::kPion,    -3.0, 3.0, 0.0, 10.0, kTRUE,  AliDielectronPID::kRequire); // TPC 3.0-sigma exclusion for pion
+  }
+  if(cutDefinition==1) {     // phi -> KK
+    pid->AddCut(AliDielectronPID::kTOF,AliPID::kKaon,   -3.5, 3.5, 0.6, 100.0, kFALSE, AliDielectronPID::kRequire, AliDielectronVarManager::kPIn);  // TOF 3-sigma inclusion for kaon
+    pid->AddCut(AliDielectronPID::kTPC,AliPID::kKaon,   -3.0, 3.5, 0.3, 100.0, kFALSE, AliDielectronPID::kRequire, AliDielectronVarManager::kPIn);  // TPC 3-sigma inclusion for kaon
+    /*    pid->AddCut(AliDielectronPID::kTPC,AliPID::kProton, -2.0, 2.0, 0.0, 0.0, kTRUE,  AliDielectronPID::kRequire);  // TPC 2.0-sigma exclusion for  proton
+    pid->AddCut(AliDielectronPID::kTPC,AliPID::kPion,   -2.0, 2.0, 0.0, 0.0, kTRUE,  AliDielectronPID::kRequire);  // TPC 2.0-sigma exclusion for  pion
+    pid->AddCut(AliDielectronPID::kTOF,AliPID::kProton, -2.0, 2.0, 0.6, 3.0, kTRUE,  AliDielectronPID::kIfAvailable);  // TOF 2.0-sigma exclusion for  proton
+    pid->AddCut(AliDielectronPID::kTOF,AliPID::kPion,   -2.0, 2.0, 0.6, 3.0, kTRUE,  AliDielectronPID::kIfAvailable);  // TOF 2.0-sigma exclusion for  pion
+*/
+  }
+    
+  // ++++++++++++++++++++++++++++++++++++++++
+  // shifts for the nSigma electrons
+  TGraph* nSigmaCorrection = new TGraph();
+  // b period (LHC10f7a)
+  nSigmaCorrection->SetPoint(0, 114000., -0.23-(0.0));
+  nSigmaCorrection->SetPoint(1, 117222., -0.23-(0.0));
+  // c period (LHC10f7a)
+  nSigmaCorrection->SetPoint(2, 119000., -0.23-(0.0));
+  nSigmaCorrection->SetPoint(3, 120829., -0.23-(0.0));
+  // d period (LHC10f7a)
+  nSigmaCorrection->SetPoint(4, 121000., -0.353-(-0.111));
+  nSigmaCorrection->SetPoint(5, 127000., -0.353-(-0.111));
+  // e period (LHC10f7a)
+  nSigmaCorrection->SetPoint(6, 127500., -0.351-(-0.116));
+  nSigmaCorrection->SetPoint(7, 130900., -0.351-(-0.116));
+  // LHC11a period (LHC11b10b)
+  nSigmaCorrection->SetPoint(8, 146680., -0.70-(+0.381));   //
+  nSigmaCorrection->SetPoint(9, 146870., -0.70-(+0.381));   //
+  if(hasMC)
+    pid->SetCorrGraph(nSigmaCorrection);
+  
+  cuts->AddCut(pid);
+}
+
+//______________________________________________________________________________________
+void SetupDielectronPairCuts(AliDielectron *die, Int_t cutDefinition)
+{
+  //
+  // Setup the pair cuts
+  //
+  
+  //Invariant mass selection
+  AliDielectronVarCuts *cuts=new AliDielectronVarCuts("|y|<0.9","|Y|<.9");
+  if(cutDefinition==0) cuts->AddCut(AliDielectronVarManager::kY,-0.9,0.9);
+  if(cutDefinition==1) cuts->AddCut(AliDielectronVarManager::kY,-1.0,1.0);
+  if(cutDefinition==1) cuts->AddCut(AliDielectronVarManager::kM, 0.95,1.1);
+  die->GetPairFilter().AddCuts(cuts);
+
+  // Configure prefilter to remove conversions
+  AliDielectronVarCuts *gammaCut=new AliDielectronVarCuts("gammaCut","gammaCut");
+  gammaCut->AddCut(AliDielectronVarManager::kM,0.,.05);
+  if(cutDefinition==0) {
+    die->GetPairPreFilter().AddCuts(gammaCut);
+    die->SetPreFilterUnlikeOnly();
+  }  
+}
+
+//______________________________________________________________________________________
+void InitDielectronHistograms(AliDielectron *die, Int_t cutDefinition)
+{
+  //
+  // Initialise the histograms
+  //
+  
+  //Setup histogram Manager
+  AliDielectronHistos *histos=new AliDielectronHistos(die->GetName(),die->GetTitle());
+  
+  //Initialise histogram classes
+  histos->SetReservedWords("Track;Pair");
+  
+  //Track classes
+  //to fill also track info from 2nd event loop until 2
+  for (Int_t i=0; i<2; ++i){
+    histos->AddClass(Form("Track_%s",AliDielectron::TrackClassName(i)));
+  }
+  
+  //Pair classes
+  // to fill also mixed event histograms loop until 10
+  for (Int_t i=0; i<3; ++i){
+    histos->AddClass(Form("Pair_%s",AliDielectron::PairClassName(i)));
+  }
+  
+  //legs from pair
+  for (Int_t i=0; i<3; ++i){
+    histos->AddClass(Form("Track_Legs_%s",AliDielectron::PairClassName(i)));
+  }
+    
+  //add histograms to event class
+  if (cutDefinition==0) {
+    histos->AddClass("Event");
+    histos->UserHistogram("Event","VtxZ","Vertex Z;Z[cm]",500,-25.,25.,AliDielectronVarManager::kZvPrim);
+    histos->UserHistogram("Event","NTrk","NTrk",500,-0.5,499.5,AliDielectronVarManager::kNTrk);
+    histos->UserHistogram("Event","VtxZ_NaccTrcklts","VtxZ_NaccTrcklts;VtxZ;NaccTrcklts", 
+                         240,-12.,12.,200,-0.5,199.5,AliDielectronVarManager::kZvPrim, AliDielectronVarManager::kNaccTrcklts);
+    histos->UserHistogram("Event","MultV0A","VZERO mult",2000,0.,2000.,AliDielectronVarManager::kMultV0A);
+    histos->UserHistogram("Event","MultV0C","VZERO mult",2000,0.,2000.,AliDielectronVarManager::kMultV0C);
+    histos->UserHistogram("Event","MultV0","VZERO mult",2000,0.,2000.,AliDielectronVarManager::kMultV0);
+    histos->UserHistogram("Event","AdcV0A","VZERO adc",10000,0.,100000.,AliDielectronVarManager::kAdcV0A);
+    histos->UserHistogram("Event","AdcV0C","VZERO adc",10000,0.,100000.,AliDielectronVarManager::kAdcV0C);
+    histos->UserHistogram("Event","AdcV0","VZERO adc",10000,0.,100000.,AliDielectronVarManager::kAdcV0);
+    histos->UserHistogram("Event","MultV0A_MultV0C","MultV0A_MultV0C;MultV0A;MultV0C", 
+                         2000,0.0,2000.,2000,0.0,2000,AliDielectronVarManager::kMultV0A, AliDielectronVarManager::kMultV0C);
+    histos->UserHistogram("Event","AdcV0A_AdcV0C","AdcV0A_AdcV0C;AdcV0A;AdcV0C", 
+                         1000,0.0,20000.,1000,0.0,20000,AliDielectronVarManager::kAdcV0A, AliDielectronVarManager::kAdcV0C);
+    histos->UserHistogram("Event","MultV0A_AdcV0A","MultV0A_AdcV0A;MultV0A;AdcV0A", 
+                         2000,0.0,2000.,2000,0.0,20000,AliDielectronVarManager::kMultV0A, AliDielectronVarManager::kAdcV0A);
+    histos->UserHistogram("Event","MultV0C_AdcV0C","MultV0C_AdcV0C;MultV0C;AdcV0C", 
+                         2000,0.0,2000.,2000,0.0,20000,AliDielectronVarManager::kMultV0C, AliDielectronVarManager::kAdcV0C);
+  }
+    
+  //add histograms to Track classes ---------------------------------------------------------------------------
+  // kinematic acceptance histograms
+  histos->UserHistogram("Track","Pt","Pt;Pt (GeV/c);#tracks",400,0,20.,AliDielectronVarManager::kPt);
+  histos->UserHistogram("Track","Eta_P","Eta_P;#eta;P (GeV/c)",40, -1.0, +1.0, 200,0,10., AliDielectronVarManager::kEta, AliDielectronVarManager::kP);
+  histos->UserHistogram("Track","Eta_Phi","Eta Phi Map; Eta; Phi;#tracks",
+                        40,-1,1,200,0,6.285,AliDielectronVarManager::kEta,AliDielectronVarManager::kPhi);  
+
+  // DCA diagnostic histograms
+  histos->UserHistogram("Track","dXY","dXY;dXY (cm);#tracks",500,-1.,1.,AliDielectronVarManager::kImpactParXY);
+  histos->UserHistogram("Track","dZ","dZ;dZ (cm);#tracks",600,-3.,3.,AliDielectronVarManager::kImpactParZ);
+  histos->UserHistogram("Track","dZ_dXY","dZ_dXY;dZ (cm);dXY (cm)",600,-3.,3.,500,-1.,1.,AliDielectronVarManager::kImpactParZ, AliDielectronVarManager::kImpactParXY);
+  histos->UserHistogram("Track","P_dXY","P_dXY;P (GeV/c);dXY (cm)",200,0.,10.,500,-1.,1.,AliDielectronVarManager::kP, AliDielectronVarManager::kImpactParXY);
+  histos->UserHistogram("Track","P_dZ","P_dZ;P (GeV/c);dZ (cm)",200,0.,10.,600,-3.,3.,AliDielectronVarManager::kP, AliDielectronVarManager::kImpactParZ);
+
+    // ITS
+  histos->UserHistogram("Track","ITSsignal","ITS signal;ITS dE/dx",1000,0.0,1000.0, AliDielectronVarManager::kITSsignal);  
+  histos->UserHistogram("Track","ITSsignal_P","ITS signal vs P;P (GeV/c); ITS dE/dx",300, 0.0, 3.0, 400,0.0,1000.0, AliDielectronVarManager::kP, AliDielectronVarManager::kITSsignal);
+  
+  // TPC
+  histos->UserHistogram("Track","TPCchi2","#chi^{2}/cluster;#chi^{2}/cluster;#tracks",200,0.0,5.0, AliDielectronVarManager::kTPCchi2Cl);
+  histos->UserHistogram("Track","Pt_TPCchi2","#chi^{2}/cluster vs pt;p_{T} (GeV/c);#chi^{2}/cluster",400,0.,20., 200,0.0,5.0,
+                       AliDielectronVarManager::kPt,AliDielectronVarManager::kTPCchi2Cl);
+  histos->UserHistogram("Track","TPCnCls","Number of Clusters TPC;TPC number clusters;#tracks",160,-0.5,159.5, AliDielectronVarManager::kNclsTPC);
+  histos->UserHistogram("Track","Phi_TPCnCls","Number of Clusters TPC vs #phi;#phi (rad.);TPC number clusters",200,0,6.285, 160,-0.5,159.5,
+                       AliDielectronVarManager::kPhi,AliDielectronVarManager::kNclsTPC);
+  histos->UserHistogram("Track","Pin_TPCnCls","Number of Clusters TPC vs TPC inner param P;p (GeV/c);TPC number clusters",400,0,20., 160,-0.5,159.5,
+                       AliDielectronVarManager::kPIn, AliDielectronVarManager::kNclsTPC);
+  histos->UserHistogram("Track","TPCnCls_dEdx","Number of Clusters TPC vs dE/dx; TPC number clusters; dE/dx (arb.units)", 160,-0.5,159.5, 200,0,200.,
+                       AliDielectronVarManager::kNclsTPC, AliDielectronVarManager::kTPCsignal);
+  histos->UserHistogram("Track","dEdx_P","dEdx;P [GeV];TPC signal (arb units);#tracks",
+                        400,0.2,20.,200,0.,200.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCsignal);
+  histos->UserHistogram("Track","TPCnSigmaEle_P","TPC number of sigmas Electrons;P [GeV];TPC number of sigmas Electrons;#tracks",
+                        400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaEle);
+  histos->UserHistogram("Track","TPCnSigmaPio_P","TPC number of sigmas Pions;P [GeV];TPC number of sigmas Pions;#tracks",
+                       400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaPio);
+  histos->UserHistogram("Track","TPCnSigmaKao_P","TPC number of sigmas Kaons;P [GeV];TPC number of sigmas Kaons;#tracks",
+                       400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaKao);
+  histos->UserHistogram("Track","TPCnSigmaPro_P","TPC number of sigmas Protons;P [GeV];TPC number of sigmas Protons;#tracks",
+                       400,0.2,20.,200,-5.,5.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTPCnSigmaPro);
+  histos->UserHistogram("Track","dEdx_Eta","dEdx;#eta;TPC signal (arb units);#tracks",
+                        100,-1.0,1.0,200,0.,200.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCsignal);
+  histos->UserHistogram("Track","TPCnSigmaEle_Eta","TPC number of sigmas Electrons;#eta;TPC number of sigmas Electrons;#tracks",
+                        100,-1.0,1.0,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaEle);
+  histos->UserHistogram("Track","TPCnSigmaPio_Eta","TPC number of sigmas Pions;#eta;TPC number of sigmas Pions;#tracks",
+                       100,-1.0,1.0,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaPio);
+  histos->UserHistogram("Track","TPCnSigmaKao_Eta","TPC number of sigmas Kaons;#eta;TPC number of sigmas Kaons;#tracks",
+                       100,-1.0,1.0,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaKao);
+  histos->UserHistogram("Track","TPCnSigmaPro_Eta","TPC number of sigmas Protons;#eta;TPC number of sigmas Protons;#tracks",
+                       100,-1.0,1.0,200,-5.,5.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTPCnSigmaPro);
+
+  // TOF
+  histos->UserHistogram("Track","Pin_TOFsignal","TOF signal vs TPC inner param P; P [GeV]; TOF signal",
+                       120,0.0,6.,1200,0.,120000.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFsignal);
+  histos->UserHistogram("Track","Pin_TOFbeta","TOF #beta vs TPC inner param P; P [GeV]; TOF #beta",
+                       120,0.0,6.,120,0.,1.2,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFbeta);
+  histos->UserHistogram("Track","TOFnSigmaPio_Pin","TOF number of sigmas Pions;P [GeV];TOF number of sigmas Pions;#tracks",
+                       400,0.2,20.,200,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFnSigmaPio);
+  histos->UserHistogram("Track","TOFnSigmaPio_eta","TOF number of sigmas Pions vs #eta;#eta;TOF number of sigmas Pions;#tracks",
+                       100,-1.2,1.2,200,-10.,10.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTOFnSigmaPio);
+  histos->UserHistogram("Track","TOFnSigmaKao_Pin","TOF number of sigmas Kaons;P [GeV];TOF number of sigmas Kaons;#tracks",
+                       400,0.2,20.,200,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFnSigmaKao);
+  histos->UserHistogram("Track","TOFnSigmaKao_eta","TOF number of sigmas Kaons vs #eta;#eta;TOF number of sigmas Kaons;#tracks",
+                       100,-1.2,1.2,200,-10.,10.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTOFnSigmaKao);
+  histos->UserHistogram("Track","TOFnSigmaPro_Pin","TOF number of sigmas Protons;P [GeV];TOF number of sigmas Protons;#tracks",
+                       400,0.2,20.,200,-10.,10.,AliDielectronVarManager::kPIn,AliDielectronVarManager::kTOFnSigmaPro);
+  histos->UserHistogram("Track","TOFnSigmaPro_eta","TOF number of sigmas Protons vs #eta;#eta;TOF number of sigmas Protons;#tracks",
+                       100,-1.2,1.2,200,-10.,10.,AliDielectronVarManager::kEta,AliDielectronVarManager::kTOFnSigmaPro);
+
+  //add histograms to Pair classes
+  Int_t nMassBins = 10000;
+  Double_t massRange[2] = {-0.005, 100.005};
+  if(cutDefinition==1) {   // Phi -> K+K-
+    nMassBins = 4000;
+    massRange[0] = 0.8; massRange[1] = 1.2;
+  }
+  histos->UserHistogram("Pair","InvMass","Inv.Mass;Inv. Mass [GeV];#pairs",
+                       nMassBins, massRange[0], massRange[1], AliDielectronVarManager::kM);
+  histos->UserHistogram("Pair","InvMass_Pt","Inv.Mass vs pt;Inv. Mass [GeV]; pt (GeV/c);#pairs",
+                       nMassBins/10, massRange[0], massRange[1], 100, 0.0, 50.0, AliDielectronVarManager::kM, AliDielectronVarManager::kPt);
+  histos->UserHistogram("Pair","InvMass_Cent","Inv.Mass vs centrality;Inv. Mass [GeV]; centrality;#pairs",
+                       nMassBins/10, massRange[0], massRange[1], 20, 0.0, 100.0, AliDielectronVarManager::kM, AliDielectronVarManager::kCentrality);
+  histos->UserHistogram("Pair","InvMass_Rap","Inv.Mass vs rapidity;Inv. Mass [GeV]; rapidity;#pairs",
+                       nMassBins/10, massRange[0], massRange[1], 100, -1.0, 1.0, AliDielectronVarManager::kM, AliDielectronVarManager::kY);
+  histos->UserHistogram("Pair","InvMass_OpAngle","Inv.Mass vs opening angle;Inv. Mass [GeV]; op. angle (rad.);#pairs",
+                       nMassBins/10, massRange[0], massRange[1], 100, 0.0, 4.0, AliDielectronVarManager::kM, AliDielectronVarManager::kOpeningAngle);
+  histos->UserHistogram("Pair","InvMass_ThetaHE","Inv.Mass vs cos #theta^{*}_{HE};Inv. Mass [GeV]; cos #theta^{*}_{HE};#pairs",
+                       nMassBins/10, massRange[0], massRange[1], 100, -1.0, 1.0, AliDielectronVarManager::kM, AliDielectronVarManager::kThetaHE);
+  histos->UserHistogram("Pair","InvMass_ThetaCS","Inv.Mass vs cos #theta^{*}_{CS};Inv. Mass [GeV]; cos #theta^{*}_{CS};#pairs",
+                       nMassBins/10, massRange[0], massRange[1], 100, -1.0, 1.0, AliDielectronVarManager::kM, AliDielectronVarManager::kThetaCS);
+  histos->UserHistogram("Pair","Pt","Transverse momentum; P_{t} [GeV/c];#pairs",
+                       1000, 0.0, 50.0, AliDielectronVarManager::kPt);
+  histos->UserHistogram("Pair","Pt_Y","Transverse momentum vs rapidity; rapidity;  P_{t} [GeV/c];#pairs",
+                       100, -1.0, 1.0, 200, 0.0, 50.0, AliDielectronVarManager::kY, AliDielectronVarManager::kPt);
+  histos->UserHistogram("Pair","Pt_ThetaCS","Transverse momentum vs cos #theta^{*}_{CS}; cos #theta^{*}_{CS};  P_{t} [GeV/c];#pairs",
+                       100, -1.0, 1.0, 200, 0.0, 50.0, AliDielectronVarManager::kThetaCS, AliDielectronVarManager::kPt);
+  histos->UserHistogram("Pair","Pt_ThetaHE","Transverse momentum vs cos #theta^{*}_{HE}; cos #theta^{*}_{HE};  P_{t} [GeV/c];#pairs",
+                       100, -1.0, 1.0, 200, 0.0, 50.0, AliDielectronVarManager::kThetaHE, AliDielectronVarManager::kPt);
+  histos->UserHistogram("Pair","Pt_Phi","Transverse momentum vs phi; #phi (rad.);  P_{t} [GeV/c];#pairs",
+                       200, -6.3, 6.3, 200, 0.0, 50.0, AliDielectronVarManager::kPhi, AliDielectronVarManager::kPt);
+  histos->UserHistogram("Pair","Phi","#phi; #phi (rad.);#pairs",
+                       1000, -6.3, 6.3, AliDielectronVarManager::kPhi);
+  histos->UserHistogram("Pair","Rapidity","Rapidity;Rapidity;#pairs",
+                        100,-1.,1.,AliDielectronVarManager::kY);
+  histos->UserHistogram("Pair","Rapidity_OpAngle","Rapidity vs opening angle;Rapidity; Op.Angle (rad.);#pairs",
+                        100,-1.,1.,200, 0.0, 4.0, AliDielectronVarManager::kY, AliDielectronVarManager::kOpeningAngle);
+  histos->UserHistogram("Pair","Rapidity_ThetaCS","Rapidity vs cos #theta^{*}_{CS};Rapidity; cos #theta^{*}_{CS};#pairs",
+                        100,-1.,1.,200, -1.0, 1.0, AliDielectronVarManager::kY, AliDielectronVarManager::kThetaCS);
+  histos->UserHistogram("Pair","Rapidity_ThetaHE","Rapidity vs cos #theta^{*}_{HE};Rapidity; cos #theta^{*}_{HE};#pairs",
+                        100,-1.,1.,200, -1.0, 1.0, AliDielectronVarManager::kY, AliDielectronVarManager::kThetaHE);
+  histos->UserHistogram("Pair","OpeningAngle","Opening angle;angle",
+                        100,0.,3.15,AliDielectronVarManager::kOpeningAngle);
+  histos->UserHistogram("Pair","Radius","Radius;R[cm]",
+                        1000,0.,300.,AliDielectronVarManager::kR);
+  histos->UserHistogram("Pair","ThetaHE","cos #theta^{*}_{HE}; cos #theta^{*}_{HE}",
+                        220,-1.1,1.1,AliDielectronVarManager::kThetaHE);
+  histos->UserHistogram("Pair","PhiHE","#varphi^{*}_{HE};#varphi^{*}_{HE} (rad.)",
+                        160,-3.2,3.2,AliDielectronVarManager::kPhiHE);
+  histos->UserHistogram("Pair","ThetaCS","cos #theta^{*}_{CS}; cos #theta^{*}_{CS}",
+                        220,-1.1,1.1,AliDielectronVarManager::kThetaCS);
+  histos->UserHistogram("Pair","PhiCS","#varphi^{*}_{CS};#varphi^{*}_{CS} (rad.)",
+                        160,-3.2,3.2,AliDielectronVarManager::kPhiCS);
+  histos->UserHistogram("Pair","Lxy","Pseudo-proper time;Lxy (cm.)",
+                        1000,0.0,2.0,AliDielectronVarManager::kPseudoProperTime);
+  histos->UserHistogram("Pair","Chi2NDF","Pair #chi^{2}/NDF; #chi^{2}/NDF",
+                        1000,0.0,10.0,AliDielectronVarManager::kChi2NDF);
+  
+  
+  die->SetHistogramManager(histos);
+}
+
+
+//_____________________________________________________________________________________________
+void SetDielectronMCSignals(AliDielectron *die)
+{
+  // J/psi sources (direct + feed down from charm higher states)
+  // 0
+  AliDielectronSignalMC* promptJpsi = new AliDielectronSignalMC("promptJpsi","Prompt J/psi");   // prompt J/psi (not from beauty decays)
+  promptJpsi->SetLegPDGs(11,-11);
+  promptJpsi->SetMotherPDGs(443,443);
+  promptJpsi->SetGrandMotherPDGs(503,503,kTRUE,kTRUE);   // not from beauty hadrons
+  promptJpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  promptJpsi->SetFillPureMCStep(kTRUE);
+  promptJpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  promptJpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  promptJpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  promptJpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(promptJpsi);
+
+  // 1
+  AliDielectronSignalMC* beautyJpsi = new AliDielectronSignalMC("beautyJpsi","beauty hadron -> J/psi");  // J/psi->e+e- from beauty hadron decays
+  beautyJpsi->SetLegPDGs(11,-11);
+  beautyJpsi->SetMotherPDGs(443,443);
+  beautyJpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  beautyJpsi->SetGrandMotherPDGs(503,503);
+  beautyJpsi->SetFillPureMCStep(kTRUE);
+  beautyJpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  beautyJpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  beautyJpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  beautyJpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(beautyJpsi);
+
+  // 2
+  AliDielectronSignalMC* beautyMesonJpsi = new AliDielectronSignalMC("beautyMesonJpsi","beauty meson -> J/psi");  // J/psi->e+e- from beauty meson decays
+  beautyMesonJpsi->SetLegPDGs(11,-11);
+  beautyMesonJpsi->SetMotherPDGs(443,443);
+  beautyMesonJpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  beautyMesonJpsi->SetGrandMotherPDGs(500,500);
+  beautyMesonJpsi->SetFillPureMCStep(kTRUE);
+  beautyMesonJpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  beautyMesonJpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  beautyMesonJpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  beautyMesonJpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(beautyMesonJpsi);
+  
+  // 3
+  AliDielectronSignalMC* openBeautyMesonJpsi = new AliDielectronSignalMC("openBeautyMesonJpsi","open beauty meson -> J/psi");  // J/psi->e+e- from open beauty meson decays
+  openBeautyMesonJpsi->SetLegPDGs(11,-11);
+  openBeautyMesonJpsi->SetMotherPDGs(443,443);
+  openBeautyMesonJpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  openBeautyMesonJpsi->SetGrandMotherPDGs(501,501);
+  openBeautyMesonJpsi->SetFillPureMCStep(kTRUE);
+  openBeautyMesonJpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  openBeautyMesonJpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  openBeautyMesonJpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  openBeautyMesonJpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(openBeautyMesonJpsi);
+
+  // 4
+  AliDielectronSignalMC* chic0Jpsi = new AliDielectronSignalMC("chic0Jpsi","chic0 -> J/psi + X");  // J/psi->e+e- from chic0 decays
+  chic0Jpsi->SetLegPDGs(11,-11);
+  chic0Jpsi->SetMotherPDGs(443,443);
+  chic0Jpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  chic0Jpsi->SetGrandMotherPDGs(10441,10441);
+  chic0Jpsi->SetFillPureMCStep(kTRUE);
+  chic0Jpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  chic0Jpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  chic0Jpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  chic0Jpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(chic0Jpsi);
+  
+  // 5
+  AliDielectronSignalMC* chic1Jpsi = new AliDielectronSignalMC("chic1Jpsi","chic1 -> J/psi + X");  // J/psi->e+e- from chic1 decays
+  chic1Jpsi->SetLegPDGs(11,-11);
+  chic1Jpsi->SetMotherPDGs(443,443);
+  chic1Jpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  chic1Jpsi->SetGrandMotherPDGs(20443,20443);
+  chic1Jpsi->SetFillPureMCStep(kTRUE);
+  chic1Jpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  chic1Jpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  chic1Jpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  chic1Jpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(chic1Jpsi);
+  
+  // 6
+  AliDielectronSignalMC* chic2Jpsi = new AliDielectronSignalMC("chic2Jpsi","chic2 -> J/psi + X");  // J/psi->e+e- from chic2 decays
+  chic2Jpsi->SetLegPDGs(11,-11);
+  chic2Jpsi->SetMotherPDGs(443,443);
+  chic2Jpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  chic2Jpsi->SetGrandMotherPDGs(445,445);
+  chic2Jpsi->SetFillPureMCStep(kTRUE);
+  chic2Jpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  chic2Jpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  chic2Jpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  chic2Jpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(chic2Jpsi);
+  
+  // 7
+  AliDielectronSignalMC* psiPrimeJpsi = new AliDielectronSignalMC("psiPrimeJpsi","psi(2S) -> J/psi + X");  // J/psi->e+e- from psi(2S) decays
+  psiPrimeJpsi->SetLegPDGs(11,-11);
+  psiPrimeJpsi->SetMotherPDGs(443,443);
+  psiPrimeJpsi->SetMothersRelation(AliDielectronSignalMC::kSame);
+  psiPrimeJpsi->SetGrandMotherPDGs(445,445);
+  psiPrimeJpsi->SetFillPureMCStep(kTRUE);
+  psiPrimeJpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  psiPrimeJpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  psiPrimeJpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  psiPrimeJpsi->SetCheckBothChargesGrandMothers(kTRUE,kTRUE);
+  die->AddSignalMC(psiPrimeJpsi);
+
+  // physical backgrounds (electrons pairs from other sources and their combinatorics)
+  // 8
+  AliDielectronSignalMC* diEleContinuum = new AliDielectronSignalMC("diEleContinuum","di-electron continuum");     // all di-electrons originating in the collision
+  diEleContinuum->SetLegPDGs(11,-11);
+  diEleContinuum->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleContinuum->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleContinuum->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleContinuum);
+
+  // 9
+  AliDielectronSignalMC* diEleCharm = new AliDielectronSignalMC("diEleCharm","di-electrons from charm");  // dielectrons originating from charm hadrons (not neccessary from same mother)
+  diEleCharm->SetLegPDGs(11,-11);
+  diEleCharm->SetMotherPDGs(403,403);
+  diEleCharm->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleCharm->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleCharm->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleCharm->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleCharm);
+
+  // 10
+  AliDielectronSignalMC* diEleOpenCharm = new AliDielectronSignalMC("diEleOpenCharm","di-electrons from open charm");  // dielectrons originating from open charm hadrons
+  diEleOpenCharm->SetLegPDGs(11,-11);
+  diEleOpenCharm->SetMotherPDGs(402,402);
+  diEleOpenCharm->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleOpenCharm->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleOpenCharm->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleOpenCharm->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleOpenCharm);
+
+  // 11
+  AliDielectronSignalMC* diEleOpenCharmJpsi = new AliDielectronSignalMC("diEleOpenCharmJpsi","1 leg from open charm + 1 jpsi leg");  // 1 leg from open charm + 1 leg from jpsi
+  diEleOpenCharmJpsi->SetLegPDGs(11,-11);
+  diEleOpenCharmJpsi->SetMotherPDGs(402,443);
+  diEleOpenCharmJpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleOpenCharmJpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleOpenCharmJpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleOpenCharmJpsi->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleOpenCharmJpsi);
+  
+  // 12
+  AliDielectronSignalMC* diEleBeauty = new AliDielectronSignalMC("diEleBeauty","di-electrons from beauty");  // dielectrons originating from beauty hadrons (not neccessary from same mother)
+  diEleBeauty->SetLegPDGs(11,-11);
+  diEleBeauty->SetMotherPDGs(503,503);
+  diEleBeauty->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleBeauty->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleBeauty->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleBeauty->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleBeauty);
+
+  // 13
+  AliDielectronSignalMC* diEleOpenBeauty = new AliDielectronSignalMC("diEleOpenBeauty","di-electrons from open beauty");  // dielectrons originating from open beauty hadrons
+  diEleOpenBeauty->SetLegPDGs(11,-11);
+  diEleOpenBeauty->SetMotherPDGs(502,502);
+  diEleOpenBeauty->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleOpenBeauty->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleOpenBeauty->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleOpenBeauty->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleOpenBeauty);
+
+  // 14
+  AliDielectronSignalMC* diEleBeautyJpsi = new AliDielectronSignalMC("diEleBeautyJpsi","1 leg from beauty + 1 jpsi leg");  // 1 leg from beauty + 1 leg from jpsi
+  diEleBeautyJpsi->SetLegPDGs(11,-11);
+  diEleBeautyJpsi->SetMotherPDGs(503,443);
+  diEleBeautyJpsi->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleBeautyJpsi->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleBeautyJpsi->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleBeautyJpsi->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleBeautyJpsi);
+
+  // 15
+  AliDielectronSignalMC* diEleBeautyOpenCharm = new AliDielectronSignalMC("diEleBeautyOpenCharm","1 leg from beauty + 1 leg from open charm");  // 1 leg from open charm + 1 leg from beauty
+  diEleBeautyOpenCharm->SetLegPDGs(11,-11);
+  diEleBeautyOpenCharm->SetMotherPDGs(503,403);
+  diEleBeautyOpenCharm->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleBeautyOpenCharm->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleBeautyOpenCharm->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleBeautyOpenCharm->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleBeautyOpenCharm);
+  
+  // 16
+  AliDielectronSignalMC* diEleStrange = new AliDielectronSignalMC("diEleStrange","di-electrons from strange particles");  // dielectrons originating from strange hadrons (not neccessary from same mother)
+  diEleStrange->SetLegPDGs(11,-11);
+  diEleStrange->SetMotherPDGs(300,300);
+  diEleStrange->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleStrange->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleStrange->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleStrange->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleStrange);
+  
+  // 17
+  AliDielectronSignalMC* diEleStrangeCharm = new AliDielectronSignalMC("diEleStrangeCharm","1 leg from strange + 1 leg from charm");  // 1 leg from strange + 1 leg from charm
+  diEleStrangeCharm->SetLegPDGs(11,-11);
+  diEleStrangeCharm->SetMotherPDGs(300,403);
+  diEleStrangeCharm->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleStrangeCharm->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleStrangeCharm->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleStrangeCharm->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleStrangeCharm);
+  
+  // 18
+  AliDielectronSignalMC* diEleStrangeBeauty = new AliDielectronSignalMC("diEleStrangeBeauty","1 leg from strange + 1 leg from beauty");  // 1 leg from strange + 1 leg from beauty
+  diEleStrangeBeauty->SetLegPDGs(11,-11);
+  diEleStrangeBeauty->SetMotherPDGs(300,503);
+  diEleStrangeBeauty->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleStrangeBeauty->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleStrangeBeauty->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleStrangeBeauty->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleStrangeBeauty);
+  
+  // 19
+  AliDielectronSignalMC* diEleLight1 = new AliDielectronSignalMC("diEleLight1","1 leg from light particles + 1 leg from everything");  // 1 leg from light hadrons (100+ PYTHIA codes) + 1 leg from everything
+  diEleLight1->SetLegPDGs(11,-11);
+  diEleLight1->SetMotherPDGs(100,0);
+  diEleLight1->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleLight1->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleLight1->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleLight1->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleLight1);
+  
+  // 20
+  AliDielectronSignalMC* diEleLight1Charm = new AliDielectronSignalMC("diEleLight1Charm","1 leg from light particles + 1 leg from charm");  // 1 leg from light hadrons (100+ PYTHIA codes) + 1 leg from charm
+  diEleLight1Charm->SetLegPDGs(11,-11);
+  diEleLight1Charm->SetMotherPDGs(100,403);
+  diEleLight1Charm->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleLight1Charm->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleLight1Charm->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleLight1Charm->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleLight1Charm);
+  
+  // 21
+  AliDielectronSignalMC* diEleLight1Beauty = new AliDielectronSignalMC("diEleLight1Beauty","1 leg from light particles + 1 leg from beauty");  // 1 leg from light hadrons (100+ PYTHIA codes) + 1 leg from beauty
+  diEleLight1Beauty->SetLegPDGs(11,-11);
+  diEleLight1Beauty->SetMotherPDGs(100,503);
+  diEleLight1Beauty->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleLight1Beauty->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleLight1Beauty->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleLight1Beauty->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleLight1Beauty);
+  
+  // 22
+  AliDielectronSignalMC* diEleLight2 = new AliDielectronSignalMC("diEleLight2","1 leg from light particles + 1 leg from everything");  // 1 leg from light hadrons (200+ PYTHIA codes) + 1 leg from everything
+  diEleLight2->SetLegPDGs(11,-11);
+  diEleLight2->SetMotherPDGs(200,0);
+  diEleLight2->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleLight2->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleLight2->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleLight2->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleLight2);
+  
+  // 23
+  AliDielectronSignalMC* diEleLight2Charm = new AliDielectronSignalMC("diEleLight2Charm","1 leg from light particles + 1 leg from charm");  // 1 leg from light hadrons (200+ PYTHIA codes) + 1 leg from charm
+  diEleLight2Charm->SetLegPDGs(11,-11);
+  diEleLight2Charm->SetMotherPDGs(100,403);
+  diEleLight2Charm->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleLight2Charm->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleLight2Charm->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleLight2Charm->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleLight2Charm);
+  
+  // 24
+  AliDielectronSignalMC* diEleLight2Beauty = new AliDielectronSignalMC("diEleLight2Beauty","1 leg from light particles + 1 leg from beauty");  // 1 leg from light hadrons (100+ PYTHIA codes) + 1 leg from beauty
+  diEleLight2Beauty->SetLegPDGs(11,-11);
+  diEleLight2Beauty->SetMotherPDGs(100,503);
+  diEleLight2Beauty->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kFinalState);
+  diEleLight2Beauty->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  diEleLight2Beauty->SetCheckBothChargesMothers(kTRUE,kTRUE);
+  diEleLight2Beauty->SetFillPureMCStep(kTRUE);
+  die->AddSignalMC(diEleLight2Beauty);
+  
+  // background from secondary electrons
+  // 25
+  AliDielectronSignalMC* secondaryElectrons = new AliDielectronSignalMC("secondaryElectrons","Secondary electrons");   // all di-electrons from secondary electrons (interaction with detector)
+  secondaryElectrons->SetLegPDGs(11,-11);
+  secondaryElectrons->SetLegSources(AliDielectronSignalMC::kSecondary, AliDielectronSignalMC::kSecondary);
+  secondaryElectrons->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(secondaryElectrons);
+
+  // 26
+  AliDielectronSignalMC* primarySecElePairs = new AliDielectronSignalMC("primarySecElePairs","Primary+Secondary electron pairs");  // primary-secondary pairs
+  primarySecElePairs->SetLegPDGs(11,-11);
+  primarySecElePairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  primarySecElePairs->SetLegSources(AliDielectronSignalMC::kFinalState, AliDielectronSignalMC::kSecondary);
+  die->AddSignalMC(primarySecElePairs);
+
+  // 27
+  AliDielectronSignalMC* conversionElePairs = new AliDielectronSignalMC("conversionElePairs","conversion electron pairs");      // pairs made from conversion (may be also from 2 different conversions)
+  conversionElePairs->SetLegPDGs(11,-11);
+  conversionElePairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  conversionElePairs->SetLegSources(AliDielectronSignalMC::kSecondary, AliDielectronSignalMC::kSecondary);
+  conversionElePairs->SetMotherPDGs(22,22);
+  die->AddSignalMC(conversionElePairs);
+
+  // misidentification
+  // 28
+  AliDielectronSignalMC* allEleMisIdPairs = new AliDielectronSignalMC("allEleMisIdPairs","all electron+misid. pairs");  // one true electron + a mis-id electron (all sources included)
+  allEleMisIdPairs->SetLegPDGs(11,11,kFALSE,kTRUE);
+  allEleMisIdPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(allEleMisIdPairs);
+
+  // 29
+  AliDielectronSignalMC* allMisIdMisIdPairs = new AliDielectronSignalMC("allMisIdMisIdPairs","all misid.+misid. pairs");  // mis-id + mis-id
+  allMisIdMisIdPairs->SetLegPDGs(11,11,kTRUE,kTRUE);
+  allMisIdMisIdPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(allMisIdMisIdPairs);
+
+  // 30
+  AliDielectronSignalMC* elePionPairs = new AliDielectronSignalMC("elePionPairs","electron+pion pairs");    // true electron + mis-id pion
+  elePionPairs->SetLegPDGs(11,211);
+  elePionPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(elePionPairs);
+
+  // 31
+  AliDielectronSignalMC* eleProtonPairs = new AliDielectronSignalMC("eleProtonPairs","Electron+proton pairs");  // true electron + mis-id proton
+  eleProtonPairs->SetLegPDGs(11,2212);
+  eleProtonPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(eleProtonPairs);
+  
+  // 32
+  AliDielectronSignalMC* eleKaonPairs = new AliDielectronSignalMC("eleKaonPairs","electron+kaon pairs");   // true electron + mis-id kaon
+  eleKaonPairs->SetLegPDGs(11,321);
+  eleKaonPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(eleKaonPairs);
+
+  // 33
+  AliDielectronSignalMC* eleProtonPairs = new AliDielectronSignalMC("eleProtonPairs","Electron+proton pairs");  // true electron + mis-id proton
+  eleProtonPairs->SetLegPDGs(11,2212);
+  eleProtonPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(eleProtonPairs);
+
+  // 34
+  AliDielectronSignalMC* piPiPairs = new AliDielectronSignalMC("piPiPairs","pion+pion pairs");    // mis-id pion + mis-id pion
+  piPiPairs->SetLegPDGs(211,211);
+  piPiPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(piPiPairs);
+
+  // 35
+  AliDielectronSignalMC* piKaonPairs = new AliDielectronSignalMC("piKaonPairs","pion+kaon pairs");  // mis-id pion + mis-id kaon
+  piKaonPairs->SetLegPDGs(211,321);
+  piKaonPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(piKaonPairs);
+
+  // 36
+  AliDielectronSignalMC* piProtonPairs = new AliDielectronSignalMC("piProtonPairs","pion+proton pairs");  // mis-id pion + mis-id proton
+  piProtonPairs->SetLegPDGs(211,2212);
+  piProtonPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(piProtonPairs);
+
+  // 37
+  AliDielectronSignalMC* kaonKaonPairs = new AliDielectronSignalMC("kaonKaonPairs","kaon+kaon pairs");  // mis-id kaon + mis-id kaon
+  kaonKaonPairs->SetLegPDGs(321,321);
+  kaonKaonPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(kaonKaonPairs);
+
+  // 38
+  AliDielectronSignalMC* muonAllPairs = new AliDielectronSignalMC("muonAllPairs","muon+everything pairs");        // mis-id muon + something else (electron, pion, kaon, proton)
+  muonAllPairs->SetLegPDGs(13,13,kFALSE,kTRUE);
+  muonAllPairs->SetCheckBothChargesLegs(kTRUE,kTRUE);
+  die->AddSignalMC(muonAllPairs);
+}
+
+//______________________________________________________________________________________
+void SetEtaCorrection()
+{
+//
+// Eta equalization for the TPC response
+//
+  if (AliDielectronPID::GetEtaCorrFunction()) return;
+
+  TString list=gSystem->Getenv("LIST");
+
+  TFile f("$TRAIN_ROOT/jpsi_JPSI/EtaCorrMaps.root");
+  if (!f.IsOpen()) return;
+  TList *keys=f.GetListOfKeys();
+
+  for (Int_t i=0; i<keys->GetEntries(); ++i){
+    TString kName=keys->At(i)->GetName();
+    TPRegexp reg(kName);
+    if (reg.MatchB(list)){
+      printf("Using Eta Correction Function: %s\n",kName.Data());
+      AliDielectronPID::SetEtaCorrFunction((TF1*)f.Get(kName.Data()));
+    }
+  }
+}
diff --git a/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliAnalysisTaskCorrelationTree.cxx b/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliAnalysisTaskCorrelationTree.cxx
new file mode 100644 (file)
index 0000000..04587d5
--- /dev/null
@@ -0,0 +1,711 @@
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+//    Analysis task for creating a reduced data tree                     //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+#include <iostream>
+using namespace std;
+
+#include <TChain.h>
+#include <TH1D.h>
+#include <TFile.h>
+
+#include <AliCFContainer.h>
+#include <AliInputEventHandler.h>
+#include <AliESDInputHandler.h>
+#include <AliAODInputHandler.h>
+#include <AliAnalysisManager.h>
+#include <AliVEvent.h>
+#include <AliESDEvent.h>
+#include <AliAODEvent.h>
+#include <AliAODTrack.h>
+#include <AliTriggerAnalysis.h>
+#include <AliESDtrackCuts.h>
+#include <AliVZDC.h>
+#include <AliESDv0.h>
+#include <AliESDv0Cuts.h>
+#include <AliVCluster.h>
+#include "AliDielectron.h"
+#include "AliDielectronHistos.h"
+#include "AliDielectronMC.h"
+#include "AliDielectronVarManager.h"
+#include "AliFlowTrackCuts.h"
+#include "AliFlowBayesianPID.h"
+
+#include "AliCorrelationReducedEvent.h"
+#include "AliAnalysisTaskCorrelationTree.h"
+
+ClassImp(AliAnalysisTaskCorrelationTree)
+
+
+//_________________________________________________________________________________
+AliAnalysisTaskCorrelationTree::AliAnalysisTaskCorrelationTree() :
+  AliAnalysisTaskSE(),
+  fListDielectron(),
+  fListHistos(),
+  fSelectPhysics(kFALSE),
+  fTriggerMask(AliVEvent::kAny),
+  fRejectPileup(kFALSE),
+  fEventFilter(0x0),
+  fTrackFilter(0x0),
+  fFlowTrackFilter(0x0),
+  fK0sCuts(0x0),
+  fLambdaCuts(0x0),
+  fK0sPionCuts(0x0),
+  fLambdaProtonCuts(0x0),
+  fLambdaPionCuts(0x0),
+  fK0sMassRange(),
+  fLambdaMassRange(),
+  fV0Histos(0x0),
+  fTreeFile(0x0),
+  fTree(0x0),
+  fFriendTreeFile(0x0),
+  fFriendTree(0x0),
+  fReducedEvent(0x0),
+  fReducedEventFriend(0x0),
+  fFlowTrackCuts(0x0)
+{
+  //
+  // Constructor
+  //
+}
+
+//_________________________________________________________________________________
+AliAnalysisTaskCorrelationTree::AliAnalysisTaskCorrelationTree(const char *name) :
+  AliAnalysisTaskSE(name),
+  fListDielectron(),
+  fListHistos(),
+  fSelectPhysics(kFALSE),
+  fTriggerMask(AliVEvent::kAny),
+  fRejectPileup(kFALSE),
+  fEventFilter(0x0),
+  fTrackFilter(0x0),
+  fFlowTrackFilter(0x0),
+  fK0sCuts(0x0),
+  fLambdaCuts(0x0),
+  fK0sPionCuts(0x0),
+  fLambdaProtonCuts(0x0),
+  fLambdaPionCuts(0x0),
+  fK0sMassRange(),
+  fLambdaMassRange(),
+  fV0Histos(0x0),
+  fTreeFile(0x0),
+  fTree(0x0),
+  fFriendTreeFile(0x0),
+  fFriendTree(0x0),
+  fReducedEvent(0x0),
+  fReducedEventFriend(0x0),
+  fFlowTrackCuts(0x0)
+{
+  //
+  // Constructor
+  //
+  fK0sMassRange[0] = 0.4; fK0sMassRange[1] = 0.6;
+  fLambdaMassRange[0] = 1.08; fLambdaMassRange[1] = 1.15;
+  
+  DefineInput(0,TChain::Class());
+  DefineOutput(1, TList::Class());   // QA histograms
+  //DefineOutput(2, TTree::Class());   // reduced information tree
+  //DefineOutput(3, TTree::Class());   // reduced information tree with friends
+  DefineOutput(2, TTree::Class());   // reduced information tree with friends
+  
+  fListHistos.SetName("QAhistograms");
+  fListDielectron.SetOwner();
+  fListHistos.SetOwner(kFALSE);
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::UserCreateOutputObjects()
+{
+  //
+  // Add all histogram manager histogram lists to the output TList
+  //
+
+  if (!fListHistos.IsEmpty() || fTree || fFriendTree) return; //already initialised
+
+  TIter nextDie(&fListDielectron);
+  AliDielectron *die=0;
+  while ( (die=static_cast<AliDielectron*>(nextDie())) ){
+    die->Init();
+    if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
+  }  
+  if(fV0Histos) fListHistos.Add(const_cast<THashList*>(fV0Histos->GetHistogramList()));
+
+  fFriendTree = new TTree("DstFriendTree","Reduced ESD information");
+  fReducedEventFriend = new AliCorrelationReducedEventFriend();
+  fFriendTree->Branch("Event",&fReducedEventFriend,16000,99);
+  
+  fTreeFile = new TFile("dstTree.root", "RECREATE");
+  fTree = new TTree("DstTree","Reduced ESD information");
+  fReducedEvent = new AliCorrelationReducedEvent();
+  fTree->Branch("Event",&fReducedEvent,16000,99);
+    
+  fFlowTrackCuts = new AliFlowTrackCuts("flow cuts");
+  fFlowTrackCuts->SetPID(AliPID::kPion, AliFlowTrackCuts::kTOFbayesian);
+  
+  PostData(1, &fListHistos);
+  //PostData(2, fTree);
+  //PostData(3, fFriendTree);
+  PostData(2, fFriendTree);
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::UserExec(Option_t *option)
+{
+  //
+  // Main loop. Called for every event
+  //  
+  //cout << "Event" << endl;
+  option = option;
+  AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
+  Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
+  Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
+  
+  AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
+  if (!inputHandler) return;
+  
+  if ( inputHandler->GetPIDResponse() ){
+    AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
+  } else {
+    AliFatal("This task needs the PID response attached to the input event handler!");
+  }
+  
+  fFlowTrackCuts->SetEvent(InputEvent());
+  
+  // Was event selected ?
+  UInt_t isSelected = AliVEvent::kAny;
+  if(fSelectPhysics && inputHandler){
+    if((isESD && inputHandler->GetEventSelection()) || isAOD){
+      isSelected = inputHandler->IsEventSelected();
+      isSelected&=fTriggerMask;
+    }
+  }
+
+  if(isSelected==0) {
+    return;
+  }
+
+  // fill event histograms before event filter
+  Double_t values[AliDielectronVarManager::kNMaxValues]={0};
+  AliDielectronVarManager::Fill(InputEvent(),values);
+  
+  TIter nextDie(&fListDielectron);
+  AliDielectron *die=0;
+  while ( (die=static_cast<AliDielectron*>(nextDie())) ){
+    AliDielectronHistos *h=die->GetHistoManager();
+    if (h){
+      if (h->GetHistogramList()->FindObject("Event_noCuts"))
+        h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
+    }
+  }
+  nextDie.Reset();
+
+  //event filter
+  if (fEventFilter) {
+    if (!fEventFilter->IsSelected(InputEvent())) return;
+  }
+  
+  //pileup
+  if (fRejectPileup){
+    if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
+  }
+
+  //cout << "Event selected" << endl;
+  //bz for AliKF
+  Double_t bz = InputEvent()->GetMagneticField();
+  AliKFParticle::SetField( bz );
+
+  //Process event in all AliDielectron instances
+  fReducedEvent->ClearEvent();
+  fReducedEventFriend->ClearEvent();
+  FillEventInfo();
+  FillV0PairInfo();
+  
+  Short_t idie=0;
+  while((die=static_cast<AliDielectron*>(nextDie()))){
+    die->Process(InputEvent());
+    FillDielectronPairInfo(die, idie);
+    ++idie;
+  }
+  nextDie.Reset();
+  
+  FillTrackInfo();
+  FillFriendEventInfo();              // Q-vector calculation
+  
+  fTree->Fill();
+  fFriendTree->Fill();
+      
+  // if there are candidate pairs, add the information to the reduced tree
+  PostData(1, &fListHistos);
+  //PostData(2, fTree);
+  //PostData(3, fFriendTree);
+  PostData(2, fFriendTree);
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::FillEventInfo() 
+{
+  //
+  // fill reduced event information
+  //
+  AliVEvent* event = InputEvent();
+  // Was event selected ?
+  AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
+  Bool_t isESD = (event->IsA()==AliESDEvent::Class());
+  Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
+  
+  AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
+  UInt_t isSelected = AliVEvent::kAny;
+  if(inputHandler){
+    if((isESD && inputHandler->GetEventSelection()) || isAOD){
+      isSelected = inputHandler->IsEventSelected();
+      isSelected&=fTriggerMask;
+    }
+  }
+
+  Double_t values[AliDielectronVarManager::kNMaxValues];
+  AliDielectronVarManager::Fill(event, values);
+  
+  fReducedEvent->fRunNo       = event->GetRunNumber();
+  fReducedEvent->fBC          = event->GetBunchCrossNumber();
+  fReducedEvent->fTriggerMask = event->GetTriggerMask();
+  fReducedEvent->fIsPhysicsSelection = (isSelected!=0 ? kTRUE : kFALSE);
+  AliVVertex* eventVtx = 0x0;
+  if(isESD) eventVtx = const_cast<AliESDVertex*>((static_cast<AliESDEvent*>(event))->GetPrimaryVertexTracks());
+  if(isAOD) eventVtx = const_cast<AliAODVertex*>((static_cast<AliAODEvent*>(event))->GetPrimaryVertex());
+  if(eventVtx) {
+    fReducedEvent->fVtx[0] = (isESD ? ((AliESDVertex*)eventVtx)->GetXv() : ((AliAODVertex*)eventVtx)->GetX());
+    fReducedEvent->fVtx[1] = (isESD ? ((AliESDVertex*)eventVtx)->GetYv() : ((AliAODVertex*)eventVtx)->GetY());
+    fReducedEvent->fVtx[2] = (isESD ? ((AliESDVertex*)eventVtx)->GetZv() : ((AliAODVertex*)eventVtx)->GetZ());
+    fReducedEvent->fNVtxContributors = eventVtx->GetNContributors();
+  }
+  if(isESD) {
+    eventVtx = const_cast<AliESDVertex*>((static_cast<AliESDEvent*>(event))->GetPrimaryVertexTPC());
+    if(eventVtx) {
+      fReducedEvent->fVtxTPC[0] = ((AliESDVertex*)eventVtx)->GetXv();
+      fReducedEvent->fVtxTPC[1] = ((AliESDVertex*)eventVtx)->GetYv();
+      fReducedEvent->fVtxTPC[2] = ((AliESDVertex*)eventVtx)->GetZv();
+      fReducedEvent->fNVtxTPCContributors = eventVtx->GetNContributors();
+    }
+  }
+  
+  AliCentrality *centrality = event->GetCentrality();
+  if(centrality) {
+    fReducedEvent->fCentrality[0] = centrality->GetCentralityPercentile("V0M");
+    fReducedEvent->fCentrality[1] = centrality->GetCentralityPercentile("CL1");
+    fReducedEvent->fCentrality[2] = centrality->GetCentralityPercentile("TRK");
+    fReducedEvent->fCentrality[3] = centrality->GetCentralityPercentile("ZEMvsZDC");    
+    fReducedEvent->fCentQuality   = centrality->GetQuality();
+  }
+  
+  fReducedEvent->fNtracks[0] = event->GetNumberOfTracks();
+  fReducedEvent->fSPDntracklets = values[AliDielectronVarManager::kNaccTrckltsEsd10Corr];
+
+  AliVVZERO* vzero = event->GetVZEROData();
+  for(Int_t i=0;i<64;++i) 
+    fReducedEvent->fVZEROMult[i] = vzero->GetMultiplicity(i);  
+
+  AliESDZDC* zdc = (isESD ? (static_cast<AliESDEvent*>(event))->GetESDZDC() : 0x0);
+  if(zdc) {
+    for(Int_t i=0; i<4; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN1TowerEnergy()[i];
+    for(Int_t i=4; i<8; ++i)  fReducedEvent->fZDCnEnergy[i]   = zdc->GetZN2TowerEnergy()[i-5];
+  }
+  
+  // EMCAL/PHOS clusters
+  FillCaloClusters();
+  
+  // TODO FMD multiplicities
+  
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::FillCaloClusters() {
+  //
+  // Fill info about the calorimeter clusters
+  //
+  AliVEvent* event = InputEvent();
+  Int_t nclusters = event->GetNumberOfCaloClusters();
+
+  fReducedEvent->fNCaloClusters = 0;
+  for(Int_t iclus=0; iclus<nclusters; ++iclus) {
+    AliVCluster* cluster = event->GetCaloCluster(iclus);
+    
+    TClonesArray& clusters = *(fReducedEvent->fCaloClusters);
+    AliCorrelationReducedCaloCluster *reducedCluster=new(clusters[fReducedEvent->fNCaloClusters]) AliCorrelationReducedCaloCluster();
+    
+    reducedCluster->fType    = (cluster->IsEMCAL() ? AliCorrelationReducedCaloCluster::kEMCAL : AliCorrelationReducedCaloCluster::kPHOS);
+    reducedCluster->fEnergy  = cluster->E();
+    reducedCluster->fTrackDx = cluster->GetTrackDx();
+    reducedCluster->fTrackDz = cluster->GetTrackDz();
+    fReducedEvent->fNCaloClusters += 1;
+  }  // end loop over clusters
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::FillFriendEventInfo() {
+  //
+  // Fill event info into the friend tree
+  //
+  // Add here calculated Q-vector components from all detectors
+  for(Int_t idet=0; idet<AliCorrelationReducedEventFriend::kNdetectors; ++idet) {
+    fReducedEvent->GetQvector(fReducedEventFriend->fQvector[idet], idet);
+    for(Int_t ih=0; ih<fgkNMaxHarmonics; ++ih)
+      fReducedEventFriend->fEventPlaneStatus[idet][ih] = AliCorrelationReducedEventFriend::kRaw;
+  }
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::FillTrackInfo() 
+{
+  //
+  // fill reduced track information
+  //
+  AliVEvent* event = InputEvent();
+  Bool_t isESD = (event->IsA()==AliESDEvent::Class());
+  Bool_t isAOD = (event->IsA()==AliAODEvent::Class());
+
+  Int_t ntracks=event->GetNumberOfTracks();
+  for(Int_t itrack=0; itrack<ntracks; ++itrack){
+    AliVParticle *particle=event->GetTrack(itrack);
+    //apply track cuts
+    if(fTrackFilter && !fTrackFilter->IsSelected(particle)) continue;
+    
+    TClonesArray& tracks = *(fReducedEvent->fTracks);
+    AliCorrelationReducedTrack *reducedParticle=new(tracks[fReducedEvent->fNtracks[1]]) AliCorrelationReducedTrack();
+        
+    Double_t values[AliDielectronVarManager::kNMaxValues];
+    AliDielectronVarManager::Fill(particle, values);
+    reducedParticle->fStatus        = (ULong_t)values[AliDielectronVarManager::kTrackStatus];
+    reducedParticle->fGlobalPhi     = values[AliDielectronVarManager::kPhi];
+    reducedParticle->fGlobalPt      = values[AliDielectronVarManager::kPt]*values[AliDielectronVarManager::kCharge];
+    reducedParticle->fGlobalEta     = values[AliDielectronVarManager::kEta];    
+    reducedParticle->fMomentumInner = values[AliDielectronVarManager::kPIn];
+    reducedParticle->fDCA[0]        = values[AliDielectronVarManager::kImpactParXY];
+    reducedParticle->fDCA[1]        = values[AliDielectronVarManager::kImpactParZ];
+    
+    reducedParticle->fITSclusterMap = values[AliDielectronVarManager::kITSclusterMap];
+    reducedParticle->fITSsignal     = values[AliDielectronVarManager::kITSsignal];
+    
+    reducedParticle->fTPCNcls      = (UChar_t)values[AliDielectronVarManager::kNclsTPC];
+    reducedParticle->fTPCNclsF     = (UChar_t)values[AliDielectronVarManager::kNFclsTPC];
+    reducedParticle->fTPCNclsIter1 = (UChar_t)values[AliDielectronVarManager::kNclsTPCiter1];
+    reducedParticle->fTPCsignal    = values[AliDielectronVarManager::kTPCsignal];
+    reducedParticle->fTPCnSig[0]   = values[AliDielectronVarManager::kTPCnSigmaEle];
+    reducedParticle->fTPCnSig[1]   = values[AliDielectronVarManager::kTPCnSigmaPio];
+    reducedParticle->fTPCnSig[2]   = values[AliDielectronVarManager::kTPCnSigmaKao];
+    reducedParticle->fTPCnSig[3]   = values[AliDielectronVarManager::kTPCnSigmaPro];
+    
+    reducedParticle->fTOFbeta      = values[AliDielectronVarManager::kTOFbeta];
+    reducedParticle->fTOFnSig[0]   = values[AliDielectronVarManager::kTOFnSigmaEle];
+    reducedParticle->fTOFnSig[1]   = values[AliDielectronVarManager::kTOFnSigmaPio];
+    reducedParticle->fTOFnSig[2]   = values[AliDielectronVarManager::kTOFnSigmaKao];
+    reducedParticle->fTOFnSig[3]   = values[AliDielectronVarManager::kTOFnSigmaPro];
+
+    reducedParticle->fTRDpid[0]    = values[AliDielectronVarManager::kTRDprobEle];
+    reducedParticle->fTRDpid[1]    = values[AliDielectronVarManager::kTRDprobPio];
+    
+    if(fFlowTrackFilter) {
+      // switch on the first bit if this particle should be used for the event plane
+      if(fFlowTrackFilter->IsSelected(particle)) reducedParticle->fFlags |= (1<<0);
+    }
+    
+    if(isESD){
+      AliESDtrack *track=static_cast<AliESDtrack*>(particle);
+      reducedParticle->fTrackId          = (UShort_t)track->GetID();
+      reducedParticle->fTPCCrossedRows   = (UChar_t)track->GetTPCCrossedRows();
+      reducedParticle->fTPCClusterMap    = EncodeTPCClusterMap(track);
+      const AliExternalTrackParam* tpcInner = track->GetTPCInnerParam();
+      reducedParticle->fTPCPhi        = (tpcInner ? tpcInner->Phi() : 0.0);
+      reducedParticle->fTPCPt         = (tpcInner ? tpcInner->Pt() : 0.0);
+      reducedParticle->fTPCEta        = (tpcInner ? tpcInner->Eta() : 0.0);
+      reducedParticle->fTRDntracklets[0] = track->GetTRDntracklets();
+      reducedParticle->fTRDntracklets[1] = track->GetTRDntrackletsPID();
+      fFlowTrackCuts->IsSelected(track);
+      AliFlowBayesianPID* bayesResponse = fFlowTrackCuts->GetBayesianResponse();
+      reducedParticle->fBayesPID[0] = bayesResponse->GetProb()[AliPID::kPion];
+      reducedParticle->fBayesPID[1] = bayesResponse->GetProb()[AliPID::kKaon];
+      reducedParticle->fBayesPID[2] = bayesResponse->GetProb()[AliPID::kProton];
+      if(track->IsEMCAL()) reducedParticle->fCaloClusterId = track->GetEMCALcluster();
+      if(track->IsPHOS()) reducedParticle->fCaloClusterId = track->GetPHOScluster();
+    }
+    if(isAOD) {
+      AliAODTrack *track=static_cast<AliAODTrack*>(particle);
+      reducedParticle->fTrackId = track->GetID(); 
+      if(track->IsEMCAL()) reducedParticle->fCaloClusterId = track->GetEMCALcluster();
+      if(track->IsPHOS()) reducedParticle->fCaloClusterId = track->GetPHOScluster();
+    }
+
+    fReducedEvent->fNtracks[1] += 1;
+  }
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::FillDielectronPairInfo(AliDielectron* die, Short_t iDie) 
+{
+  //
+  // fill reduced pair information
+  //
+  Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
+
+  for(Int_t iType=0; iType<3; ++iType) {
+    
+    const TObjArray* array = die->GetPairArray(iType);
+    if(!array || array->GetEntriesFast()==0) continue;
+    cout << "dielectron tracks (idie/type/n): " << iDie << " / 0 / " << die->GetTrackArray(0)->GetEntriesFast() << endl;
+    cout << "dielectron tracks (idie/type/n): " << iDie << " / 1 / " << die->GetTrackArray(1)->GetEntriesFast() << endl;
+
+    cout << "diele idie/type/n-candidates: " << iDie << " / " << iType << " / " << array->GetEntriesFast() << endl;
+    for(Int_t iCandidate=0; iCandidate<array->GetEntriesFast(); ++iCandidate) {
+      if(iCandidate%100==0) cout << "iCandidate = " << iCandidate << endl;
+      AliDielectronPair* pair = (AliDielectronPair*)array->At(iCandidate);
+      Double_t values[AliDielectronVarManager::kNMaxValues];
+      AliDielectronVarManager::Fill(pair, values);
+      
+      TClonesArray& tracks = *(fReducedEvent->fCandidates);
+      AliCorrelationReducedPair *reducedParticle= 
+         new (tracks[fReducedEvent->fNV0candidates[1]+fReducedEvent->fNDielectronCandidates]) AliCorrelationReducedPair();
+      // !!! hardcoded flag for dielectron id 
+      reducedParticle->fCandidateId  = (iDie==0 ? AliCorrelationReducedPair::kJpsiToEE : AliCorrelationReducedPair::kPhiToKK);
+      reducedParticle->fPairType     = values[AliDielectronVarManager::kPairType];
+      reducedParticle->fLegIds[0]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetFirstDaughter()))->GetID();
+      reducedParticle->fLegIds[1]    = (UShort_t)(static_cast<AliVTrack*>(pair->GetSecondDaughter()))->GetID();
+      reducedParticle->fMass[0]      = values[AliDielectronVarManager::kM];
+      reducedParticle->fMass[1]      = -999.;
+      reducedParticle->fMass[2]      = -999.;
+      reducedParticle->fPhi          = values[AliDielectronVarManager::kPhi];  // in the [-pi,pi] interval
+      if(reducedParticle->fPhi<0.0) reducedParticle->fPhi = 2.0*TMath::Pi() + reducedParticle->fPhi;  // converted to [0,2pi]
+      reducedParticle->fPt           = values[AliDielectronVarManager::kPt];
+      reducedParticle->fEta          = values[AliDielectronVarManager::kEta];
+      reducedParticle->fLxy          = values[AliDielectronVarManager::kPseudoProperTime];
+      reducedParticle->fOpeningAngle = values[AliDielectronVarManager::kOpeningAngle];     
+     
+      reducedParticle->fMCid         = 0;
+      if(hasMC) {
+       AliDielectronMC::Instance()->ConnectMCEvent();
+       const TObjArray* mcSignals = die->GetMCSignals();
+       for(Int_t iSig=0; iSig<mcSignals->GetEntries(); ++iSig) {
+         if(iSig>31) break;
+         AliDielectronMC *mc=AliDielectronMC::Instance();
+         if(mc->IsMCTruth(pair, (AliDielectronSignalMC*)mcSignals->At(iSig))) {
+           reducedParticle->fMCid = reducedParticle->fMCid | (1<<iSig);
+         }
+       }
+      }   // end if has MC
+      fReducedEvent->fNDielectronCandidates += 1;
+    }    // end loop over candidates
+  }    // end loop over pair type
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::FillV0PairInfo() 
+{
+  //
+  // fill reduced pair information
+  //
+  AliESDEvent* esd = (AliESDEvent*)InputEvent();
+  const AliESDVertex *primaryVertex = esd->GetPrimaryVertex();
+  AliKFVertex primaryVertexKF(*primaryVertex);
+  
+  fReducedEvent->fNV0candidates[0] = InputEvent()->GetNumberOfV0s();
+  
+  Double_t valuesPos[AliDielectronVarManager::kNMaxValues];
+  Double_t valuesNeg[AliDielectronVarManager::kNMaxValues];
+   
+  cout << "n total V0s: " << InputEvent()->GetNumberOfV0s() << endl;
+  for(Int_t iV0=0; iV0<InputEvent()->GetNumberOfV0s(); ++iV0) {   // loop over V0s
+    if(iV0%1000==0) cout << "iV0 = " << iV0 << endl;
+    AliESDv0 *v0 = esd->GetV0(iV0);
+       
+    AliESDtrack* legPos = esd->GetTrack(v0->GetPindex());
+    AliESDtrack* legNeg = esd->GetTrack(v0->GetNindex());
+    if(legPos->GetSign() == legNeg->GetSign()) {
+      //cout << "V0 rejected: same sign legs" << endl;
+      continue;
+    }
+
+    Bool_t v0ChargesAreCorrect = (legPos->GetSign()==+1 ? kTRUE : kFALSE);
+    legPos = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetNindex()) : legPos);
+    legNeg = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetPindex()) : legNeg); 
+    
+    // apply the K0s filter
+    Bool_t goodK0s = kTRUE;
+    if(fK0sPionCuts && (!fK0sPionCuts->IsSelected(legPos) || !fK0sPionCuts->IsSelected(legNeg))) goodK0s = kFALSE;
+    if(fK0sCuts) {
+      TList k0sList;
+      k0sList.Add(v0);
+      k0sList.Add(legPos); k0sList.Add(legNeg);
+      k0sList.Add(const_cast<AliESDVertex*>(primaryVertex));
+      if(!fK0sCuts->IsSelected(&k0sList)) goodK0s = kFALSE;
+    }
+    
+    // apply the lambda filter
+    Bool_t goodLambda = kTRUE;
+    if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legPos)) goodLambda = kFALSE;
+    if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legNeg)) goodLambda = kFALSE;
+    Bool_t goodALambda = kTRUE;
+    if(fLambdaProtonCuts && !fLambdaProtonCuts->IsSelected(legNeg)) goodALambda = kFALSE;
+    if(fLambdaPionCuts && !fLambdaPionCuts->IsSelected(legPos)) goodALambda = kFALSE;
+    if(fLambdaCuts) {
+      TList lambdaList;
+      lambdaList.Add(v0);
+      lambdaList.Add(legPos); lambdaList.Add(legNeg);
+      lambdaList.Add(const_cast<AliESDVertex*>(primaryVertex));
+      if(!fLambdaCuts->IsSelected(&lambdaList)) {goodLambda = kFALSE; goodALambda = kFALSE;}
+    }
+    
+    if(!(goodK0s || goodLambda || goodALambda)) continue;
+    
+    // Fill the V0 information into the tree for 3 hypothesis: K0s, Lambda, Anti-Lambda
+    AliCorrelationReducedPair* k0sReducedPair     = FillV0PairInfo(v0, AliCorrelationReducedPair::kK0sToPiPi,     legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
+    AliCorrelationReducedPair* lambdaReducedPair  = FillV0PairInfo(v0, AliCorrelationReducedPair::kLambda0ToPPi,  legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
+    AliCorrelationReducedPair* alambdaReducedPair = FillV0PairInfo(v0, AliCorrelationReducedPair::kALambda0ToPPi, legPos, legNeg, &primaryVertexKF, v0ChargesAreCorrect);
+
+    if(goodK0s && k0sReducedPair->fMass[0]>fK0sMassRange[0] && k0sReducedPair->fMass[0]<fK0sMassRange[1]) {
+      TClonesArray& tracks = *(fReducedEvent->fCandidates);
+      AliCorrelationReducedPair *goodK0sPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliCorrelationReducedPair(*k0sReducedPair);
+      goodK0sPair->fMass[0] = k0sReducedPair->fMass[0];
+      goodK0sPair->fMass[1] = lambdaReducedPair->fMass[0];
+      goodK0sPair->fMass[2] = alambdaReducedPair->fMass[0];
+      fReducedEvent->fNV0candidates[1] += 1;
+    } else {goodK0s=kFALSE;}
+    if(goodLambda && lambdaReducedPair->fMass[0]>fLambdaMassRange[0] && lambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
+      TClonesArray& tracks = *(fReducedEvent->fCandidates);
+      AliCorrelationReducedPair *goodLambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliCorrelationReducedPair(*lambdaReducedPair);
+      fReducedEvent->fNV0candidates[1] += 1;
+      goodLambdaPair->fMass[0] = k0sReducedPair->fMass[0];
+      goodLambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
+      goodLambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
+    } else {goodLambda=kFALSE;}
+    if(goodALambda && alambdaReducedPair->fMass[0]>fLambdaMassRange[0] && alambdaReducedPair->fMass[0]<fLambdaMassRange[1]) {
+      TClonesArray& tracks = *(fReducedEvent->fCandidates);
+      AliCorrelationReducedPair *goodALambdaPair = new (tracks[fReducedEvent->fNV0candidates[1]]) AliCorrelationReducedPair(*alambdaReducedPair);
+      fReducedEvent->fNV0candidates[1] += 1;  
+      goodALambdaPair->fMass[0] = k0sReducedPair->fMass[0];
+      goodALambdaPair->fMass[1] = lambdaReducedPair->fMass[0];
+      goodALambdaPair->fMass[2] = alambdaReducedPair->fMass[0];
+    } else {goodALambda = kFALSE;}
+    delete k0sReducedPair;
+    delete lambdaReducedPair;
+    delete alambdaReducedPair;
+
+    if(!(goodK0s || goodLambda || goodALambda)) continue;
+    
+    //  Fill histograms and the CF container
+    AliDielectronVarManager::Fill(legPos, valuesPos);
+    AliDielectronVarManager::Fill(legNeg, valuesNeg);
+    
+    if(fV0Histos && fV0Histos->GetHistogramList()->FindObject("V0Track_Pos"))
+      fV0Histos->FillClass("V0Track_Pos", AliDielectronVarManager::kNMaxValues, valuesPos);
+    if(fV0Histos && fV0Histos->GetHistogramList()->FindObject("V0Track_Neg"))
+      fV0Histos->FillClass("V0Track_Neg", AliDielectronVarManager::kNMaxValues, valuesNeg);    
+  }   // end loop over V0s
+}
+
+
+//_________________________________________________________________________________
+AliCorrelationReducedPair* AliAnalysisTaskCorrelationTree::FillV0PairInfo(AliESDv0* v0, Int_t id, 
+                                                   AliESDtrack* legPos, AliESDtrack* legNeg,
+                                                   AliKFVertex* vtxKF, Bool_t chargesAreCorrect) {
+  //
+  // Create a reduced V0 object and fill it
+  //
+  AliCorrelationReducedPair* reducedPair=new AliCorrelationReducedPair();  
+  reducedPair->fCandidateId = id;
+  reducedPair->fPairType    = v0->GetOnFlyStatus();    // on the fly status
+  //reducedPair->fOnTheFly    = v0->GetOnFlyStatus();
+  reducedPair->fLegIds[0]   = legPos->GetID();
+  reducedPair->fLegIds[1]   = legNeg->GetID();
+  if(!reducedPair->fPairType) {    // offline
+    UInt_t pidPos = AliPID::kPion;
+    if(id==AliCorrelationReducedPair::kLambda0ToPPi) pidPos = AliPID::kProton;
+    UInt_t pidNeg = AliPID::kPion;
+    if(id==AliCorrelationReducedPair::kALambda0ToPPi) pidNeg = AliPID::kProton;
+    reducedPair->fMass[0]      = v0->GetEffMass(pidPos, pidNeg);
+    reducedPair->fPhi          = v0->Phi();
+    if(reducedPair->fPhi<0.0) reducedPair->fPhi = 2.0*TMath::Pi() + reducedPair->fPhi;  // converted to [0,2pi]
+    reducedPair->fPt           = v0->Pt();
+    reducedPair->fEta          = v0->Eta();
+    reducedPair->fLxy          = 0.0;           //TODO
+    reducedPair->fOpeningAngle = 0.0;
+  }
+  else {
+    const AliExternalTrackParam *negHelix=v0->GetParamN();
+    const AliExternalTrackParam *posHelix=v0->GetParamP();
+    if(!chargesAreCorrect) {
+      negHelix = v0->GetParamP();
+      posHelix = v0->GetParamN();
+    }
+    AliKFParticle negKF(*(negHelix),(id==AliCorrelationReducedPair::kALambda0ToPPi ? -2212 : -211));
+    AliKFParticle posKF(*(posHelix),(id==AliCorrelationReducedPair::kLambda0ToPPi ? +2212 : +211));
+    AliKFParticle v0Refit;
+    v0Refit += negKF;
+    v0Refit += posKF;
+    Double_t massFit=0.0, massErrFit=0.0;
+    v0Refit.GetMass(massFit,massErrFit);
+    reducedPair->fMass[0] = massFit;
+    reducedPair->fPhi          = v0Refit.GetPhi();
+    if(reducedPair->fPhi<0.0) reducedPair->fPhi = 2.0*TMath::Pi() + reducedPair->fPhi;  // converted to [0,2pi]
+    reducedPair->fPt           = v0Refit.GetPt();
+    reducedPair->fEta          = v0Refit.GetEta();
+    reducedPair->fLxy          = v0Refit.GetPseudoProperDecayTime(*vtxKF, massFit);
+    reducedPair->fOpeningAngle = negKF.GetAngle(posKF);
+  }
+  return reducedPair;
+}
+
+
+//_________________________________________________________________________________
+UChar_t AliAnalysisTaskCorrelationTree::EncodeTPCClusterMap(AliESDtrack* track) {
+  //
+  // Encode the TPC cluster map into an UChar_t
+  // Divide the 159 bits from the bit map into 8 groups of adiacent clusters
+  // For each group enable its corresponding bit if in that group there are more clusters compared to
+  // a threshold.
+  //
+  const UChar_t threshold=5;
+  TBits tpcClusterMap = track->GetTPCClusterMap();
+  UChar_t map=0;
+  UChar_t n=0;
+  UChar_t j=0;
+  for(UChar_t i=0; i<8; ++i) {
+    n=0;
+    for(j=i*20; j<(i+1)*20 && j<159; ++j) n+=tpcClusterMap.TestBitNumber(j);
+    if(n>=threshold) map |= (1<<i);
+  }
+  return map;
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskCorrelationTree::FinishTaskOutput()
+{
+  //
+  // Finish Task 
+  //
+  fTreeFile->Write();
+  fTreeFile->Close();
+}
diff --git a/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliAnalysisTaskCorrelationTree.h b/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliAnalysisTaskCorrelationTree.h
new file mode 100644 (file)
index 0000000..edcb203
--- /dev/null
@@ -0,0 +1,104 @@
+#ifndef ALIANALYSISTASKCORRELATIONTREE_H
+#define ALIANALYSISTASKCORRELATIONTREE_H
+
+// Analysis task for creating a reduced tree containing event, track and resonance candidate information
+// Author: Ionut-Cristian Arsene (i.c.arsene@gsi.de)
+
+#include "TList.h"
+
+#include "AliAnalysisTaskSE.h"
+
+class AliAnalysisCuts;
+class TTree;
+class TFile;
+class AliESDv0Cuts;
+class AliKFVertex;
+class AliCorrelationReducedEvent;
+class AliCorrelationReducedEventFriend;
+class AliCorrelationReducedPair;
+class AliDielectron;
+class AliFlowTrackCuts;
+
+//_________________________________________________________________________
+class AliAnalysisTaskCorrelationTree : public AliAnalysisTaskSE {
+  
+public:
+  AliAnalysisTaskCorrelationTree();
+  AliAnalysisTaskCorrelationTree(const char *name);
+  virtual ~AliAnalysisTaskCorrelationTree(){  }
+
+  virtual void UserExec(Option_t *option);
+  virtual void UserCreateOutputObjects();
+  virtual void FinishTaskOutput();
+  
+  void UsePhysicsSelection(Bool_t phy=kTRUE) {fSelectPhysics=phy;}
+  void SetTriggerMask(UInt_t mask) {fTriggerMask=mask;}
+  UInt_t GetTriggerMask() const { return fTriggerMask; }
+  void SetRejectPileup(Bool_t pileup=kTRUE)     { fRejectPileup=pileup;     }
+  
+  // Cuts for selection of event to be written to tree
+  void SetEventFilter(AliAnalysisCuts * const filter) {fEventFilter=filter;}
+  // Cuts for selecting tracks included in the tree
+  void SetTrackFilter(AliAnalysisCuts * const filter) {fTrackFilter=filter;}
+  // Cuts for selecting tracks to be used for Q vector calculation
+  void SetFlowTrackFilter(AliAnalysisCuts * const filter) {fFlowTrackFilter = filter;}
+  
+  // Cuts for selecting V0s
+  void SetK0sPionCuts(AliAnalysisCuts * const filter) {fK0sPionCuts=filter;}
+  void SetLambdaProtonCuts(AliAnalysisCuts * const filter) {fLambdaProtonCuts=filter;}
+  void SetLambdaPionCuts(AliAnalysisCuts * const filter) {fLambdaPionCuts=filter;}
+  void SetK0sCuts(AliESDv0Cuts* const cuts) {fK0sCuts = cuts;}
+  void SetLambdaCuts(AliESDv0Cuts* const cuts) {fLambdaCuts = cuts;}
+  void SetK0sMassRange(Double_t min=0.4, Double_t max=0.6) {fK0sMassRange[0]=min; fK0sMassRange[1]=max;}
+  void SetLambdaMassRange(Double_t min=1.08, Double_t max=1.15) {fLambdaMassRange[0]=min; fLambdaMassRange[1]=max;}
+  void SetV0Histograms(AliDielectronHistos * const histos) {fV0Histos=histos;}
+  
+  // Add dielectron objects to the list. These contain cuts and histogram definitions
+  void AddDielectron(AliDielectron * const die) { fListDielectron.Add(die); }
+ private:
+
+  TList fListDielectron;             // List of dielectron framework instances
+  TList fListHistos;                 //! List of histogram managers in the dielectron framework classes
+  
+  Bool_t fSelectPhysics;             // Whether to use physics selection
+  UInt_t fTriggerMask;               // Event trigger mask
+  Bool_t fRejectPileup;              // pileup rejection wanted
+
+  AliAnalysisCuts *fEventFilter;     // event filter
+  AliAnalysisCuts *fTrackFilter;     // filter for the hadrons to be correlated with the dielectrons
+  AliAnalysisCuts *fFlowTrackFilter; // filter for the barrel tracks to be used for the Q-vector
+  
+  AliESDv0Cuts *fK0sCuts;            // v0 standard filter for K0s->pi+pi-
+  AliESDv0Cuts *fLambdaCuts;         // v0 standard filter for Lambda0->p + pi
+  AliAnalysisCuts *fK0sPionCuts;     // filter for pions from K0s
+  AliAnalysisCuts *fLambdaProtonCuts;// filter for protons from Lambda
+  AliAnalysisCuts *fLambdaPionCuts;  // filter for pions from Lambda
+  Double_t fK0sMassRange[2];           // mass range for allowed K0s pairs
+  Double_t fLambdaMassRange[2];        // mass range for allowed Lambda pairs
+  AliDielectronHistos* fV0Histos;    // histogram manager for V0s
+
+  TFile *fTreeFile;                  // output file containing the tree
+  TTree *fTree;                      //! Reduced event tree
+  TTree *fFriendTreeFile;            // output file containing the friend tree
+  TTree *fFriendTree;                //! Reduced event tree with friend info (event plane, etc.)
+  AliCorrelationReducedEvent *fReducedEvent;    // reduced event wise information
+  AliCorrelationReducedEventFriend *fReducedEventFriend;    // friend reduced event wise information
+  
+  AliFlowTrackCuts* fFlowTrackCuts;   // flow track cuts object
+  
+  void FillEventInfo();                     // fill reduced event information
+  void FillFriendEventInfo();               // fill reduced event friend information
+  void FillTrackInfo();                     // fill reduced track information
+  void FillDielectronPairInfo(AliDielectron* die, Short_t iDie);  // fill dielectron reduced pair information
+  void FillV0PairInfo();                    // fill V0 reduced pair information
+  AliCorrelationReducedPair* FillV0PairInfo(AliESDv0* v0, Int_t id, AliESDtrack* legPos, AliESDtrack* legNeg, AliKFVertex* vtxKF, Bool_t chargesAreCorrect);
+  UChar_t EncodeTPCClusterMap(AliESDtrack* track);
+  void FillCaloClusters();
+  
+  AliAnalysisTaskCorrelationTree(const AliAnalysisTaskCorrelationTree &c);
+  AliAnalysisTaskCorrelationTree& operator= (const AliAnalysisTaskCorrelationTree &c);
+
+  ClassDef(AliAnalysisTaskCorrelationTree, 1); //Analysis Task for creating a reduced event information tree 
+};
+#endif
diff --git a/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliCorrelationReducedEvent.cxx b/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliCorrelationReducedEvent.cxx
new file mode 100644 (file)
index 0000000..dc6295a
--- /dev/null
@@ -0,0 +1,502 @@
+#ifndef ALICORRELATIONREDUCEDEVENT_H
+#include "AliCorrelationReducedEvent.h"
+#endif
+
+#include <TMath.h>
+#include <TClonesArray.h>
+
+ClassImp(AliCorrelationReducedTrack)
+ClassImp(AliCorrelationReducedPair)
+ClassImp(AliCorrelationReducedEvent)
+ClassImp(AliCorrelationReducedEventFriend)
+ClassImp(AliCorrelationReducedCaloCluster)
+
+TClonesArray* AliCorrelationReducedEvent::fgTracks = 0;
+TClonesArray* AliCorrelationReducedEvent::fgCandidates = 0;
+TClonesArray* AliCorrelationReducedEvent::fgCaloClusters = 0;
+
+//_______________________________________________________________________________
+AliCorrelationReducedTrack::AliCorrelationReducedTrack() :
+  fTrackId(-1),
+  fStatus(0),
+  fGlobalPhi(0.0),
+  fGlobalPt(0.0),
+  fGlobalEta(0.0),
+  fTPCPhi(0.0),
+  fTPCPt(0.0),
+  fTPCEta(0.0),
+  fMomentumInner(0.0),
+  fDCA(),
+  fITSclusterMap(0),
+  fITSsignal(0.0),
+  fTPCNcls(0),
+  fTPCCrossedRows(0),
+  fTPCNclsF(0),
+  fTPCNclsIter1(0),
+  fTPCClusterMap(0),
+  fTPCsignal(0),
+  fTPCnSig(),
+  fTOFbeta(0.0),
+  fTOFnSig(),
+  fTRDntracklets(),
+  fTRDpid(),
+  fCaloClusterId(-999),
+  fBayesPID(),
+  fFlags(0)
+{
+  //
+  // Constructor
+  //
+  fDCA[0] = 0.0; fDCA[1]=0.0;
+  for(Int_t i=0; i<4; ++i) {fTPCnSig[i]=-999.; fTOFnSig[i]=-999.;} 
+  for(Int_t i=0; i<3; ++i) {fBayesPID[i]=-999.;}
+  fTRDpid[0]=-999.; fTRDpid[1]=-999.;
+}
+
+
+//_______________________________________________________________________________
+AliCorrelationReducedTrack::~AliCorrelationReducedTrack()
+{
+  //
+  // De-Constructor
+  //
+}
+
+
+//_______________________________________________________________________________
+AliCorrelationReducedPair::AliCorrelationReducedPair() :
+  fCandidateId(-1),
+  fPairType(-1), 
+  fLegIds(),
+  fMass(),
+  fPhi(0.0),
+  fPt(0.0),
+  fEta(0.0),
+  fLxy(0.0),
+  fOpeningAngle(-1.0),
+  //fOnTheFly(kFALSE),
+  fMCid(0)
+{
+  //
+  // Constructor
+  //
+  fLegIds[0] = -1; fLegIds[1] = -1;
+  fMass[0]=-999.; fMass[1]=-999.; fMass[2]=-999.;
+}
+
+
+//_______________________________________________________________________________
+AliCorrelationReducedPair::AliCorrelationReducedPair(const AliCorrelationReducedPair &c) :
+  TObject(c),
+  fCandidateId(c.CandidateId()),
+  fPairType(c.PairType()),
+  fLegIds(),
+  fMass(),
+  fPhi(c.Phi()),
+  fPt(c.Pt()),
+  fEta(c.Eta()),
+  fLxy(c.Lxy()),
+  fOpeningAngle(c.OpeningAngle()),
+  //fOnTheFly(c.IsOnTheFly()),
+  fMCid(c.MCid())
+{
+  //
+  // copy constructor
+  //
+  fLegIds[0] = c.LegId(0);
+  fLegIds[1] = c.LegId(1);
+  fMass[0] = c.Mass(0); fMass[1] = c.Mass(1); fMass[2] = c.Mass(2);
+}
+
+
+//_______________________________________________________________________________
+AliCorrelationReducedPair::~AliCorrelationReducedPair() {
+  //
+  // destructor
+  //
+}
+
+//____________________________________________________________________________
+AliCorrelationReducedEvent::AliCorrelationReducedEvent() :
+  fRunNo(0),
+  fBC(0),
+  fTriggerMask(0),
+  fIsPhysicsSelection(kTRUE),
+  fVtx(),
+  fNVtxContributors(0),
+  fVtxTPC(),
+  fNVtxTPCContributors(0),
+  fCentrality(),
+  fCentQuality(0),
+  fNV0candidates(),
+  fNDielectronCandidates(0),
+  fNtracks(),
+  fSPDntracklets(0),
+  fVZEROMult(),
+  fZDCnEnergy(),
+  fNCaloClusters(0)
+//fFMDMult()
+{
+  //
+  // Constructor
+  //
+  for(Int_t i=0; i<3; ++i) {fVtx[i]=-999.; fVtxTPC[i]=-999.;}
+  for(Int_t i=0; i<4; ++i) fCentrality[i]=-1.;
+  fNV0candidates[0]=0; fNV0candidates[1]=0;
+  fNtracks[0]=0; fNtracks[1]=0;
+  for(Int_t i=0; i<64; ++i) fVZEROMult[i] = 0.0;
+  for(Int_t i=0; i<8; ++i) fZDCnEnergy[i]=0.0;
+  
+  if(!fgTracks) fgTracks = new TClonesArray("AliCorrelationReducedTrack", 100000);
+  fTracks = fgTracks;
+  if(!fgCandidates) fgCandidates = new TClonesArray("AliCorrelationReducedPair", 100000);
+  fCandidates = fgCandidates;
+  if(!fgCaloClusters) fgCaloClusters = new TClonesArray("AliCorrelationReducedCaloCluster", 50000);
+  fCaloClusters = fgCaloClusters;
+}
+
+
+//____________________________________________________________________________
+AliCorrelationReducedEvent::~AliCorrelationReducedEvent()
+{
+  //
+  // De-Constructor
+  //
+  ClearEvent();
+}
+
+
+//____________________________________________________________________________
+Float_t AliCorrelationReducedEvent::MultVZEROA() const
+{
+  //
+  // Total VZERO multiplicity in A side
+  //
+  Float_t mult=0.0;
+  for(Int_t i=32;i<64;++i)
+    mult += fVZEROMult[i];
+  return mult;
+}
+
+
+//____________________________________________________________________________
+Float_t AliCorrelationReducedEvent::MultVZEROC() const
+{
+  //
+  // Total VZERO multiplicity in C side
+  //
+  Float_t mult=0.0;
+  for(Int_t i=0;i<32;++i)
+    mult += fVZEROMult[i];
+  return mult;
+}
+
+
+//____________________________________________________________________________
+Float_t AliCorrelationReducedEvent::MultVZERO() const
+{
+  //
+  // Total VZERO multiplicity
+  //
+  return MultVZEROA()+MultVZEROC();
+}
+
+
+//____________________________________________________________________________
+Float_t AliCorrelationReducedEvent::MultRingVZEROA(Int_t ring) const 
+{
+  //
+  //  VZERO multiplicity in a given ring on A side
+  //
+  if(ring<0 || ring>3) return -1.0;
+
+  Float_t mult=0.0;
+  for(Int_t i=32+8*ring; i<32+8*(ring+1); ++i)
+    mult += fVZEROMult[i];
+  return mult;
+}
+
+
+//____________________________________________________________________________
+Float_t AliCorrelationReducedEvent::MultRingVZEROC(Int_t ring) const 
+{
+  //
+  //  VZERO multiplicity in a given ring on C side
+  //
+  if(ring<0 || ring>3) return -1.0;
+
+  Float_t mult=0.0;
+  for(Int_t i=8*ring; i<8*(ring+1); ++i)
+    mult += fVZEROMult[i];
+  return mult;
+}
+
+//_____________________________________________________________________________
+void AliCorrelationReducedEvent::ClearEvent() {
+  //
+  // clear the event
+  //
+  fTracks->Clear("C");
+  fCandidates->Clear("C");
+  fCaloClusters->Clear("C");
+  fRunNo = 0;
+  fBC = 0;
+  fTriggerMask = 0;
+  fIsPhysicsSelection = kTRUE;
+  fCentQuality = 0;
+  fNV0candidates[0] = 0; fNV0candidates[1] = 0;
+  fNDielectronCandidates = 0;
+  fNtracks[0] = 0; fNtracks[1] = 0;
+  for(Int_t i=0; i<3; ++i) {fVtx[i]=-999.; fVtxTPC[i]=-999.; fCentrality[i]=-1.;}
+  for(Int_t i=0; i<64; ++i) fVZEROMult[i] = 0.0;
+  for(Int_t i=0; i<8; ++i) fZDCnEnergy[i]=0.0;
+}
+
+
+//_______________________________________________________________________________
+AliCorrelationReducedEventFriend::AliCorrelationReducedEventFriend() :
+ fQvector(),
+ fEventPlaneStatus()
+{
+  //
+  // default constructor
+  //
+  for(Int_t idet=0; idet<kNdetectors; ++idet) {
+    for(Int_t ih=0; ih<fgkNMaxHarmonics; ++ih) {
+      fEventPlaneStatus[idet][ih] = 0;
+      for(Int_t ic=0; ic<2; ++ic)
+       fQvector[idet][ih][ic] = 0.0;
+    }
+  }
+}
+
+
+//____________________________________________________________________________
+AliCorrelationReducedEventFriend::~AliCorrelationReducedEventFriend()
+{
+  //
+  // De-Constructor
+  //
+  ClearEvent();
+}
+
+
+//_____________________________________________________________________________
+void AliCorrelationReducedEventFriend::ClearEvent() {
+  //
+  // clear the event
+  //
+  for(Int_t idet=0; idet<kNdetectors; ++idet) {
+    for(Int_t ih=0; ih<fgkNMaxHarmonics; ++ih) {
+      fEventPlaneStatus[idet][ih] = 0;
+      for(Int_t ic=0; ic<2; ++ic)
+       fQvector[idet][ih][ic] = 0.0;
+    }
+  }
+}
+
+
+//____________________________________________________________________________
+void AliCorrelationReducedEventFriend::CopyEvent(AliCorrelationReducedEventFriend* event) {
+  //
+  // copy information from another event to this one
+  //
+  for(Int_t idet=0; idet<kNdetectors; ++idet) {
+    for(Int_t ih=0; ih<fgkNMaxHarmonics; ++ih) {
+      fQvector[idet][ih][0] = event->Qx(idet, ih+1);
+      fQvector[idet][ih][1] = event->Qy(idet, ih+1);
+      fEventPlaneStatus[idet][ih] = event->GetEventPlaneStatus(idet, ih+1);
+    }
+  }
+}
+
+
+//_____________________________________________________________________________
+AliCorrelationReducedCaloCluster::AliCorrelationReducedCaloCluster() :
+ fType(kUndefined),
+ fEnergy(-999.),
+ fTrackDx(-999.),
+ fTrackDz(-999.)
+{
+  //
+  // default constructor
+  //
+}
+
+
+//_____________________________________________________________________________
+AliCorrelationReducedCaloCluster::~AliCorrelationReducedCaloCluster()
+{
+  //
+  // destructor
+  //
+}
+
+
+//_______________________________________________________________________________
+void AliCorrelationReducedEvent::GetQvector(Double_t Qvec[][2], Int_t det) {
+  //
+  // Get the event plane for a specified detector
+  //
+  if(det==AliCorrelationReducedEventFriend::kTPC || 
+     det==AliCorrelationReducedEventFriend::kTPCptWeights ||
+     det==AliCorrelationReducedEventFriend::kTPCpos ||
+     det==AliCorrelationReducedEventFriend::kTPCneg) {
+    GetTPCQvector(Qvec, det);
+    return;
+  }
+  if(det==AliCorrelationReducedEventFriend::kVZEROA ||
+     det==AliCorrelationReducedEventFriend::kVZEROC) {
+    GetVZEROQvector(Qvec, det);   
+    return;
+  }
+  if(det==AliCorrelationReducedEventFriend::kZDCA ||
+     det==AliCorrelationReducedEventFriend::kZDCC) {
+    GetZDCQvector(Qvec, det);
+    return;
+  }
+  if(det==AliCorrelationReducedEventFriend::kFMD) {
+    //TODO implementation
+    return;
+  }
+  return;
+}
+
+
+//_________________________________________________________________
+void AliCorrelationReducedEvent::GetTPCQvector(Double_t Qvec[][2], Int_t det) {
+  //
+  // Construct the event plane using tracks in the barrel
+  //
+  if(!(det==AliCorrelationReducedEventFriend::kTPC ||
+       det==AliCorrelationReducedEventFriend::kTPCpos ||
+       det==AliCorrelationReducedEventFriend::kTPCneg))
+    return;
+  AliCorrelationReducedTrack* track=0x0;
+  Double_t pt=0.0; Double_t x=0.0; Double_t y=0.0; 
+  Short_t charge=0;
+  TIter nextTrack(fTracks);
+  while((track=static_cast<AliCorrelationReducedTrack*>(nextTrack()))) {
+    if(!track->UsedForQvector()) continue;
+    charge = track->Charge();
+    if(det==AliCorrelationReducedEventFriend::kTPCpos && charge<0) continue;
+    if(det==AliCorrelationReducedEventFriend::kTPCneg && charge>0) continue;
+    pt = 1.0;
+    if(det==AliCorrelationReducedEventFriend::kTPCptWeights) {
+      pt = track->Pt();
+      if(pt>2.0) pt = 2.0;    // pt is the weight used for the event plane
+    }
+    x = TMath::Cos(track->Phi());
+    y = TMath::Sin(track->Phi());
+    //  1st harmonic  
+    Qvec[0][0] += pt*x;
+    Qvec[0][1] += pt*y;
+    //  2nd harmonic
+    Qvec[1][0] += pt*(2.0*TMath::Power(x,2.0)-1);
+    Qvec[1][1] += pt*(2.0*x*y);
+    //  3rd harmonic
+    Qvec[2][0] += pt*(4.0*TMath::Power(x,3.0)-3.0*x);
+    Qvec[2][1] += pt*(3.0*y-4.0*TMath::Power(y,3.0));
+    //  4th harmonic
+    Qvec[3][0] += pt*(1.0-8.0*TMath::Power(x*y,2.0));
+    Qvec[3][1] += pt*(4.0*x*y-8.0*x*TMath::Power(y,3.0));
+    //  5th harmonic
+    Qvec[4][0] += pt*(16.0*TMath::Power(x,5.0)-20.0*TMath::Power(x, 3.0)+5.0*x);
+    Qvec[4][1] += pt*(16.0*TMath::Power(y,5.0)-20.0*TMath::Power(y, 3.0)+5.0*y);
+    //  6th harmonic
+    Qvec[5][0] += pt*(32.0*TMath::Power(x,6.0)-48.0*TMath::Power(x, 4.0)+18.0*TMath::Power(x, 2.0)-1.0);
+    Qvec[5][1] += pt*(x*y*(32.0*TMath::Power(y,4.0)-32.0*TMath::Power(y, 2.0)+6.0)); 
+  }
+}
+
+
+//_________________________________________________________________
+void AliCorrelationReducedEvent::GetVZEROQvector(Double_t Qvec[][2], Int_t det) {
+  //
+  // Get the reaction plane from the VZERO detector for a given harmonic
+  //
+  GetVZEROQvector(Qvec, det, fVZEROMult);
+}
+
+
+//_________________________________________________________________
+void AliCorrelationReducedEvent::GetVZEROQvector(Double_t Qvec[][2], Int_t det, Float_t* vzeroMult) {
+  //
+  // Get the reaction plane from the VZERO detector for a given harmonic
+  //
+  //  Q{x,y} = SUM_i mult(i) * {cos(n*phi_i), sin(n*phi_i)} 
+  //  phi_i - phi angle of the VZERO sector i
+  //          Each sector covers 45 degrees(8 sectors per ring). Middle of sector 0 is at 45/2
+  //        channel 0: 22.5
+  //                1: 22.5+45
+  //                2: 22.5+45*2
+  //               ...
+  //        at the next ring continues the same
+  //        channel 8: 22.5
+  //        channel 9: 22.5 + 45
+  //       
+  if(!(det==AliCorrelationReducedEventFriend::kVZEROA ||
+       det==AliCorrelationReducedEventFriend::kVZEROC))
+    return; 
+  
+  const Double_t kX[8] = {0.92388, 0.38268, -0.38268, -0.92388, -0.92388, -0.38268, 0.38268, 0.92388};    // cosines of the angles of the VZERO sectors (8 per ring)
+  const Double_t kY[8] = {0.38268, 0.92388, 0.92388, 0.38268, -0.38268, -0.92388, -0.92388, -0.38268};    // sines     -- " --
+  Int_t phi;
+  
+  for(Int_t iChannel=0; iChannel<64; ++iChannel) {
+    if(iChannel<32 && det==AliCorrelationReducedEventFriend::kVZEROA) continue;
+    if(iChannel>=32 && det==AliCorrelationReducedEventFriend::kVZEROC) continue;
+    phi=iChannel%8;
+    //  1st harmonic  
+    Qvec[0][0] += vzeroMult[iChannel]*kX[phi];
+    Qvec[0][1] += vzeroMult[iChannel]*kY[phi];
+    //  2nd harmonic
+    Qvec[1][0] += vzeroMult[iChannel]*(2.0*TMath::Power(kX[phi],2.0)-1);
+    Qvec[1][1] += vzeroMult[iChannel]*(2.0*kX[phi]*kY[phi]);
+    //  3rd harmonic
+    Qvec[2][0] += vzeroMult[iChannel]*(4.0*TMath::Power(kX[phi],3.0)-3.0*kX[phi]);
+    Qvec[2][1] += vzeroMult[iChannel]*(3.0*kY[phi]-4.0*TMath::Power(kY[phi],3.0));
+    //  4th harmonic
+    Qvec[3][0] += vzeroMult[iChannel]*(1.0-8.0*TMath::Power(kX[phi]*kY[phi],2.0));
+    Qvec[3][1] += vzeroMult[iChannel]*(4.0*kX[phi]*kY[phi]-8.0*kX[phi]*TMath::Power(kY[phi],3.0));
+    //  5th harmonic
+    Qvec[4][0] += vzeroMult[iChannel]*(16.0*TMath::Power(kX[phi],5.0)-20.0*TMath::Power(kX[phi], 3.0)+5.0*kX[phi]);
+    Qvec[4][1] += vzeroMult[iChannel]*(16.0*TMath::Power(kY[phi],5.0)-20.0*TMath::Power(kY[phi], 3.0)+5.0*kY[phi]);
+    //  6th harmonic
+    Qvec[5][0] += vzeroMult[iChannel]*(32.0*TMath::Power(kX[phi],6.0)-48.0*TMath::Power(kX[phi], 4.0)+18.0*TMath::Power(kX[phi], 2.0)-1.0);
+    Qvec[5][1] += vzeroMult[iChannel]*(kX[phi]*kY[phi]*(32.0*TMath::Power(kY[phi],4.0)-32.0*TMath::Power(kY[phi], 2.0)+6.0));
+  }    // end loop over channels 
+}
+
+
+//_________________________________________________________________
+void AliCorrelationReducedEvent::GetZDCQvector(Double_t Qvec[][2], Int_t det) {
+  //
+  // Construct the event plane using the ZDC
+  // ZDC has 2 side (A and C) with 4 calorimeters on each side  
+  // The XY position of each calorimeter is specified by the 
+  // zdcNTowerCenters_x and zdcNTowerCenters_y arrays
+  if(!(det==AliCorrelationReducedEventFriend::kZDCA || 
+       det==AliCorrelationReducedEventFriend::kZDCC)) return;       // bad detector option
+  const Float_t zdcTowerCenter = 1.75;
+  const Float_t zdcNTowerCenters_x[4] = {-zdcTowerCenter,  zdcTowerCenter, -zdcTowerCenter, zdcTowerCenter};
+  const Float_t zdcNTowerCenters_y[4] = {-zdcTowerCenter, -zdcTowerCenter,  zdcTowerCenter, zdcTowerCenter};
+
+  Qvec[0][0] = 0.0; Qvec[0][1] = 0.0;   // first harmonic Q-vector
+  Float_t zdcNCentroidSum = 0;
+  Float_t zdcN_alpha = 0.5;
+    
+  for(Int_t i=0; i<4; ++i) {
+    if(fZDCnEnergy[i+(det==AliCorrelationReducedEventFriend::kZDCA ? 4 : 0)]>0.0) {
+      Float_t zdcNenergy_alpha = TMath::Power(fZDCnEnergy[i+(det==AliCorrelationReducedEventFriend::kZDCA ? 4 : 0)], zdcN_alpha);
+      Qvec[0][0] += zdcNTowerCenters_x[i-1]*zdcNenergy_alpha;
+      Qvec[0][1] += zdcNTowerCenters_y[i-1]*zdcNenergy_alpha;
+      zdcNCentroidSum += zdcNenergy_alpha;
+    }
+  }   // end loop over channels
+  
+  if(zdcNCentroidSum>0.0) {
+    Qvec[0][0] /= zdcNCentroidSum;
+    Qvec[0][1] /= zdcNCentroidSum;
+  }
+}
diff --git a/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliCorrelationReducedEvent.h b/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/AliCorrelationReducedEvent.h
new file mode 100644 (file)
index 0000000..bae2517
--- /dev/null
@@ -0,0 +1,458 @@
+// Classes used for creating a reduced information tree
+// Author: Ionut-Cristian Arsene (i.c.arsene@gsi.de)
+// 
+//  Basic structure:
+//  1. Event wise information
+//  2. List of tracks in the event
+//  3. List of resonance candidates
+
+#ifndef ALICORRELATIONREDUCEDEVENT_H
+#define ALICORRELATIONREDUCEDEVENT_H
+
+#include <TClonesArray.h>
+#include <TBits.h>
+#include <TMath.h>
+
+
+const Int_t fgkNMaxHarmonics = 10;
+/*class AliCorrelationReducedTrack;
+class AliCorrelationReducedPair;
+class AliCorrelationReducedEventFriend;
+class AliCorrelationReducedEvent;
+class AliCorrelationReducedCaloCluster;*/
+
+//_____________________________________________________________________
+class AliCorrelationReducedTrack : public TObject {
+
+  friend class AliAnalysisTaskCorrelationTree;
+
+ public:
+  AliCorrelationReducedTrack();
+  ~AliCorrelationReducedTrack();
+
+  // getters
+  UShort_t TrackId()                     const {return fTrackId;}
+  ULong_t  Status()                      const {return fStatus;}
+  Bool_t   CheckTrackStatus(UInt_t flag) const {return (flag<8*sizeof(ULong_t) ? (fStatus&(1<<flag)) : kFALSE);}
+  Int_t    Charge()                      const {return (fGlobalPt>0.0 ? +1 : -1);}
+  Float_t  Px()                          const {return TMath::Abs(fGlobalPt)*TMath::Cos(fGlobalPhi);}
+  Float_t  Py()                          const {return TMath::Abs(fGlobalPt)*TMath::Sin(fGlobalPhi);}
+  Float_t  Pz()                          const {return TMath::Abs(fGlobalPt)*TMath::SinH(fGlobalEta);}
+  Float_t  P()                           const {return TMath::Abs(fGlobalPt)*TMath::CosH(fGlobalEta);};
+  Float_t  Phi()                         const {return fGlobalPhi;}
+  Float_t  Pt()                          const {return TMath::Abs(fGlobalPt);}
+  Float_t  Eta()                         const {return fGlobalEta;}
+  Float_t  Theta()                       const {return TMath::ACos(TMath::TanH(fGlobalEta));}
+  Float_t  PxTPC()                       const {return fTPCPt*TMath::Cos(fTPCPhi);}
+  Float_t  PyTPC()                       const {return fTPCPt*TMath::Sin(fTPCPhi);}
+  Float_t  PzTPC()                       const {return fTPCPt*TMath::SinH(fTPCEta);}
+  Float_t  PTPC()                        const {return fTPCPt*TMath::CosH(fTPCEta);};
+  Float_t  PhiTPC()                      const {return fTPCPhi;}
+  Float_t  PtTPC()                       const {return fTPCPt;}
+  Float_t  EtaTPC()                      const {return fTPCEta;}
+  Float_t  ThetaTPC()                    const {return TMath::ACos(TMath::TanH(fTPCEta));}
+  Float_t  Pin()                         const {return fMomentumInner;}
+  Float_t  DCAxy()                       const {return fDCA[0];}
+  Float_t  DCAz()                        const {return fDCA[1];}
+  
+  UShort_t ITSncls()                const;
+  UChar_t  ITSclusterMap()          const {return fITSclusterMap;}
+  Bool_t   ITSLayerHit(Int_t layer) const {return (layer>=0 && layer<6 ? (fITSclusterMap&(1<<layer)) : kFALSE);};
+  Float_t  ITSsignal()              const {return fITSsignal;}
+  
+  UChar_t TPCncls()                        const {return fTPCNcls;}
+  UChar_t TPCFindableNcls()                const {return fTPCNclsF;}
+  UChar_t TPCCrossedRows()                 const {return fTPCCrossedRows;}
+  UChar_t TPCnclsIter1()                   const {return fTPCNclsIter1;}
+  UChar_t TPCClusterMap()                  const {return fTPCClusterMap;}
+  Int_t   TPCClusterMapBitsFired()         const;
+  Bool_t  TPCClusterMapBitFired(Int_t bit) const {return (bit>=0 && bit<8 ? (fTPCClusterMap&(1<<bit)) : kFALSE);};
+  Float_t TPCsignal()                      const {return fTPCsignal;}
+  Float_t TPCnSig(Int_t specie)            const {return (specie>=0 && specie<=3 ? fTPCnSig[specie] : -999.);}
+  
+  Float_t  TOFbeta()             const {return fTOFbeta;}    
+  Float_t  TOFnSig(Int_t specie) const {return (specie>=0 && specie<=3 ? fTOFnSig[specie] : -999.);}
+  
+  Int_t    TRDntracklets(Int_t type)  const {return (type==0 || type==1 ? fTRDntracklets[type] : -1);}
+  Float_t  TRDpid(Int_t specie)       const {return (specie>=0 && specie<=1 ? fTRDpid[specie] : -999.);}
+  
+  Int_t    CaloClusterId() const {return fCaloClusterId;}
+  //Float_t  CaloEnergy(AliCorrelationReducedEvent* event) const {if(fCaloClusterId>0) return event->GetCaloCluster(fCaloClusterId)->Energy();}
+  //Float_t  CaloDx(AliCorrelationReducedEvent* event) const {if(fCaloClusterId>0) return event->GetCaloCluster(fCaloClusterId)->Dx();}
+  //Float_t  CaloDz(AliCorrelationReducedEvent* event) const {if(fCaloClusterId>0) return event->GetCaloCluster(fCaloClusterId)->Dz();}
+  
+  Float_t  BayesPID(Int_t specie) const {return (specie>=0 && specie<=2 ? fBayesPID[specie] : -999.);}
+  Bool_t   UsedForQvector()       const {return fFlags&(1<<0);}
+  
+ private:
+  UShort_t fTrackId;            // track id 
+  ULong_t fStatus;              // tracking status
+  Float_t fGlobalPhi;           // phi at the vertex from global track, in the [0,2pi) interval
+  Float_t fGlobalPt;            // pt*charge at the vertex from global track
+  Float_t fGlobalEta;           // eta at the vertex from global track
+  Float_t fTPCPhi;              // phi at the vertex from TPC alone tracking , in the [0,2pi) interval
+  Float_t fTPCPt;               // pt at the vertex from TPC alone tracking  
+  Float_t fTPCEta;              // eta at the vertex from TPC alone tracking 
+  Float_t fMomentumInner;       // inner param momentum (only the magnitude)
+  Float_t fDCA[2];              // DCA xy,z
+  
+  // ITS
+  UChar_t  fITSclusterMap;      // ITS cluster map
+  Float_t  fITSsignal;          // ITS signal
+  
+  // TPC
+  UChar_t fTPCNcls;            // TPC ncls                          
+  UChar_t fTPCCrossedRows;     // TPC crossed rows                  
+  UChar_t fTPCNclsF;           // TPC findable ncls                 
+  UChar_t fTPCNclsIter1;       // TPC no clusters after first iteration
+  UChar_t fTPCClusterMap;      // TPC cluster distribution map
+  Float_t fTPCsignal;          // TPC de/dx
+  Float_t fTPCnSig[4];         // 0-electron; 1-pion; 2-kaon; 3-proton
+    
+  // TOF
+  Float_t fTOFbeta;             // TOF pid info
+  Float_t fTOFnSig[4];          // TOF n-sigma deviation from expected signal
+  
+  // TRD
+  UChar_t fTRDntracklets[2];       // 0 - AliESDtrack::GetTRDntracklets(); 1 - AliESDtrack::GetTRDntrackletsPID()   TODO: use only 1 char
+  Float_t fTRDpid[2];              // TRD pid probabilities, [0]-electron, [1]-pion
+  
+  // EMCAL/PHOS
+  Int_t  fCaloClusterId;          // ID for the calorimeter cluster (if any)
+  
+  // Bayesian PID
+  Float_t fBayesPID[3];            // Combined Bayesian PID   pi/K/p
+  
+  UShort_t fFlags;                // BIT0 toggled if track used for TPC event plane   TODO combine with other posible flags, use for MC pid?
+  // TODO flag for which TPC part used for pid  --> Char_t  used in 2011 data
+  
+  AliCorrelationReducedTrack(const AliCorrelationReducedTrack &c);
+  AliCorrelationReducedTrack& operator= (const AliCorrelationReducedTrack &c);
+
+  ClassDef(AliCorrelationReducedTrack, 2);
+};
+
+
+//_____________________________________________________________________
+class AliCorrelationReducedPair : public TObject {
+
+  friend class AliAnalysisTaskCorrelationTree;
+
+ public:
+  enum CandidateType {
+    kK0sToPiPi=0,
+    kPhiToKK,
+    kLambda0ToPPi,
+    kALambda0ToPPi,
+    kJpsiToEE,
+    kNMaxCandidateTypes
+  };
+  AliCorrelationReducedPair();
+  AliCorrelationReducedPair(const AliCorrelationReducedPair &c);
+  ~AliCorrelationReducedPair();
+
+  // getters
+  Char_t   CandidateId()         const {return fCandidateId;}
+  Char_t   PairType()            const {return fPairType;}
+  Int_t    LegId(Int_t leg)      const {return (leg==0 || leg==1 ? fLegIds[leg] : -1);}
+  Float_t  Mass(Int_t idx=0)     const {return (idx>=0 && idx<3 ? fMass[idx] : -999.);}
+  Float_t  Px()                  const {return fPt*TMath::Cos(fPhi);}
+  Float_t  Py()                  const {return fPt*TMath::Sin(fPhi);}
+  Float_t  Pz()                  const {return fPt*TMath::SinH(fEta);}
+  Float_t  P()                   const {return fPt*TMath::CosH(fEta);}
+  Float_t  Phi()                 const {return fPhi;}
+  Float_t  Pt()                  const {return fPt;}
+  Float_t  Eta()                 const {return fEta;}
+  Float_t  Energy()              const;
+  Float_t  Rapidity()            const;
+  Float_t  Theta()               const {return TMath::ACos(TMath::TanH(fEta));}
+  Float_t  Lxy()                 const {return fLxy;}
+  Float_t  OpeningAngle()        const {return fOpeningAngle;}
+  Bool_t   IsOnTheFly()          const {return fPairType;}
+  UInt_t   MCid()                const {return fMCid;}
+  Bool_t   CheckMC(const Int_t flag) const {return (flag<32 ? (fMCid&(1<<flag)) : kFALSE);}
+  
+ private:
+  Char_t  fCandidateId;         // candidate type (K0s, Lambda, J/psi, phi, etc)
+  Char_t  fPairType;            // 0 ++; 1 +-; 2 -- for dielectron pairs; 0- offline, 1- on the fly for V0 candidates
+  UShort_t fLegIds[2];          // leg ids 
+  Float_t fMass[3];             // invariant mass for pairs (2 extra mass values for other V0 pid assumptions)
+                                // idx=0 -> K0s assumption; idx=1 -> Lambda; idx=2 -> anti-Lambda
+  Float_t fPhi;                 // pair phi in the [0,2*pi) interval
+  Float_t fPt;                  // pair pt
+  Float_t fEta;                 // pair eta 
+  Float_t fLxy;                 // pseudo-proper decay length
+  Float_t fOpeningAngle;        // opening angle                TODO remove   ???
+  UInt_t  fMCid;                // Bit map with Monte Carlo info about the pair
+
+  AliCorrelationReducedPair& operator= (const AliCorrelationReducedPair &c);
+
+  ClassDef(AliCorrelationReducedPair, 1);
+};
+
+
+//_________________________________________________________________________
+class AliCorrelationReducedEventFriend : public TObject {
+  
+  friend class AliAnalysisTaskCorrelationTree;
+  
+ public: 
+  enum EventPlaneStatus {
+    kRaw=0,
+    kCalibrated,
+    kRecentered,
+    kShifted,
+    kNMaxFlowFlags
+  };
+  enum EventPlaneDetector {
+    kTPC=0,       
+    kTPCptWeights,
+    kTPCpos,
+    kTPCneg,
+    kVZEROA,
+    kVZEROC,
+    kFMD,
+    kZDCA,
+    kZDCC,
+    kNdetectors
+  };
+  
+  AliCorrelationReducedEventFriend();
+  ~AliCorrelationReducedEventFriend();
+  
+  Double_t Qx(Int_t det, Int_t harmonic)  const {return (det>=0 && det<kNdetectors && harmonic>0 && harmonic<=fgkNMaxHarmonics ? fQvector[det][harmonic-1][0] : -999.);}
+  Double_t Qy(Int_t det, Int_t harmonic)  const {return (det>=0 && det<kNdetectors && harmonic>0 && harmonic<=fgkNMaxHarmonics ? fQvector[det][harmonic-1][1] : -999.);}
+  Double_t EventPlane(Int_t det, Int_t h) const;
+  UChar_t GetEventPlaneStatus(Int_t det, Int_t h) const {return (det>=0 && det<kNdetectors && h>0 && h<=fgkNMaxHarmonics ? fEventPlaneStatus[det][h] : -999.);} 
+  Bool_t  CheckEventPlaneStatus(Int_t det, Int_t h, EventPlaneStatus flag) const;
+  void    CopyEvent(AliCorrelationReducedEventFriend* event);
+
+  void SetQx(Int_t det, Int_t harmonic, Float_t qx) { if(det>=0 && det<kNdetectors && harmonic>0 && harmonic<=fgkNMaxHarmonics) fQvector[det][harmonic-1][0]=qx;}
+  void SetQy(Int_t det, Int_t harmonic, Float_t qy) { if(det>=0 && det<kNdetectors && harmonic>0 && harmonic<=fgkNMaxHarmonics) fQvector[det][harmonic-1][1]=qy;}
+  void SetEventPlaneStatus(Int_t det, Int_t harmonic, EventPlaneStatus status) { 
+    if(det>=0 && det<kNdetectors && harmonic>0 && harmonic<=fgkNMaxHarmonics) 
+      fEventPlaneStatus[det][harmonic-1] |= (1<<status);
+  }
+  
+ private:
+  // Q-vectors for the first 10 harmonics from TPC, VZERO, FMD and ZDC detectors
+  Double_t fQvector[kNdetectors][fgkNMaxHarmonics][2];     // Q vector components for all detectors and 6 harmonics
+  UChar_t fEventPlaneStatus[kNdetectors][fgkNMaxHarmonics];  // Bit maps for the event plane status (1 char per detector and per harmonic)
+   
+  void ClearEvent();
+  AliCorrelationReducedEventFriend(const AliCorrelationReducedEventFriend &c);
+  AliCorrelationReducedEventFriend& operator= (const AliCorrelationReducedEventFriend &c);
+
+  ClassDef(AliCorrelationReducedEventFriend, 1);
+};
+
+
+//_________________________________________________________________________
+class AliCorrelationReducedCaloCluster : public TObject {
+  
+  friend class AliAnalysisTaskCorrelationTree;
+  
+ public:
+  enum ClusterType {
+    kUndefined=0, kEMCAL, kPHOS  
+  };
+   
+  AliCorrelationReducedCaloCluster();
+  ~AliCorrelationReducedCaloCluster();
+  
+  Bool_t  IsEMCAL() const {return (fType==kEMCAL ? kTRUE : kFALSE);}
+  Bool_t  IsPHOS()  const {return (fType==kPHOS ? kTRUE : kFALSE);}
+  Float_t Energy()  const {return fEnergy;}
+  Float_t Dx()      const {return fTrackDx;}
+  Float_t Dz()      const {return fTrackDz;}
+  
+ private:
+  Char_t  fType;         // cluster type (EMCAL/PHOS)
+  Float_t fEnergy;       // cluster energy
+  Float_t fTrackDx;      // distance to closest track in phi
+  Float_t fTrackDz;      // distance to closest track in z
+  
+  AliCorrelationReducedCaloCluster(const AliCorrelationReducedCaloCluster &c);
+  AliCorrelationReducedCaloCluster& operator= (const AliCorrelationReducedCaloCluster &c);
+
+  ClassDef(AliCorrelationReducedCaloCluster, 1);
+};
+
+
+//_________________________________________________________________________
+class AliCorrelationReducedEvent : public TObject {
+
+  friend class AliAnalysisTaskCorrelationTree;
+
+ public:
+  AliCorrelationReducedEvent();
+  ~AliCorrelationReducedEvent();
+
+  // getters
+  Int_t     RunNo()                           const {return fRunNo;}
+  UShort_t  BC()                              const {return fBC;}
+  ULong64_t TriggerMask()                     const {return fTriggerMask;}
+  Bool_t    IsPhysicsSelection()              const {return fIsPhysicsSelection;}
+  Float_t   Vertex(Int_t axis)                const {return (axis>=0 && axis<=2 ? fVtx[axis] : 0);}
+  Int_t     VertexNContributors()             const {return fNVtxContributors;}
+  Float_t   VertexTPC(Int_t axis)             const {return (axis>=0 && axis<=2 ? fVtxTPC[axis] : 0);}
+  Int_t     VertexTPCContributors()           const {return fNVtxTPCContributors;}
+  Float_t   CentralityVZERO()                 const {return fCentrality[0];}
+  Float_t   CentralitySPD()                   const {return fCentrality[1];}
+  Float_t   CentralityTPC()                   const {return fCentrality[2];}
+  Float_t   CentralityZEMvsZDC()              const {return fCentrality[3];}
+  Int_t     CentralityQuality()               const {return fCentQuality;}
+  Int_t     NV0CandidatesTotal()              const {return fNV0candidates[0];}
+  Int_t     NV0Candidates()                   const {return fNV0candidates[1];}
+  Int_t     NDielectrons()                    const {return fNDielectronCandidates;}
+  Int_t     NTracksTotal()                    const {return fNtracks[0];}
+  Int_t     NTracks()                         const {return fNtracks[1];}
+  Int_t     SPDntracklets()                   const {return fSPDntracklets;}
+  
+  Float_t   MultChannelVZERO(Int_t channel)   const {return (channel>=0 && channel<=63 ? fVZEROMult[channel] : -999.);}
+  Float_t   MultVZEROA()                      const;
+  Float_t   MultVZEROC()                      const;
+  Float_t   MultVZERO()                       const;
+  Float_t   MultRingVZEROA(Int_t ring)        const;
+  Float_t   MultRingVZEROC(Int_t ring)        const;
+  
+  Float_t   EnergyZDC(Int_t channel)   const {return (channel>=0 && channel<8 ? fZDCnEnergy[channel] : -999.);}
+  Float_t   EnergyZDCnA(Int_t channel) const {return (channel>=0 && channel<4 ? fZDCnEnergy[channel+4] : -999.);}
+  Float_t   EnergyZDCnC(Int_t channel) const {return (channel>=0 && channel<4 ? fZDCnEnergy[channel] : -999.);}
+  
+  AliCorrelationReducedTrack* GetTrack(Int_t i)         const {return (i<fNtracks[1] ? (AliCorrelationReducedTrack*)fTracks->At(i) : 0x0);}
+  AliCorrelationReducedPair* GetV0Pair(Int_t i)         const {return (i>=0 && i<fNV0candidates[1] ? (AliCorrelationReducedPair*)fCandidates->At(i) : 0x0);}
+  AliCorrelationReducedPair* GetDielectronPair(Int_t i) const {return (i>=0 && i<fNDielectronCandidates ? (AliCorrelationReducedPair*)fCandidates->At(i+fNV0candidates[1]) : 0x0);}
+  TClonesArray* GetPairs()                              const {return fCandidates;}
+  TClonesArray* GetTracks()                             const {return fTracks;}
+
+  Int_t GetNCaloClusters() const {return fNCaloClusters;}
+  AliCorrelationReducedCaloCluster* GetCaloCluster(Int_t i) const {return (i>=0 && i<fNCaloClusters ? (AliCorrelationReducedCaloCluster*)fCaloClusters->At(i) : 0x0);}
+  
+  void GetQvector(Double_t Qvec[][2], Int_t det);
+  void GetTPCQvector(Double_t Qvec[][2], Int_t det);
+  void GetVZEROQvector(Double_t Qvec[][2], Int_t det);
+  void GetVZEROQvector(Double_t Qvec[][2], Int_t det, Float_t* vzeroMult);
+  void GetZDCQvector(Double_t Qvec[][2], Int_t det);
+
+ private:
+  Int_t     fRunNo;                 // run number
+  UShort_t  fBC;                    // bunch crossing
+  ULong64_t fTriggerMask;           // trigger mask
+  Bool_t    fIsPhysicsSelection;    // PhysicsSelection passed event
+  Float_t   fVtx[3];                // global event vertex vector in cm
+  Int_t     fNVtxContributors;      // global event vertex contributors
+  Float_t   fVtxTPC[3];             // TPC only event vertex           
+  Int_t     fNVtxTPCContributors;   // TPC only event vertex contributors
+  Float_t   fCentrality[4];         // centrality; 0-VZERO, 1-SPD, 2-TPC, 3-ZEMvsZDC 
+  Int_t     fCentQuality;           // quality flag for the centrality 
+  Int_t     fNV0candidates[2];      // number of V0 candidates, [0]-total, [1]-selected for the tree
+  Int_t     fNDielectronCandidates; // number of pairs selected as dielectrons
+  Int_t     fNtracks[2];            // number of tracks, [0]-total, [1]-selected for the tree
+  Int_t     fSPDntracklets;         // number of SPD tracklets in |eta|<1.0 
+
+  Float_t   fVZEROMult[64];         // VZERO multiplicity in all 64 channels
+  Float_t   fZDCnEnergy[8];         // neutron ZDC energy in all 8 channels
+    
+  TClonesArray* fTracks;            //->   array containing global tracks
+  static TClonesArray* fgTracks;
+  
+  TClonesArray* fCandidates;        //->   array containing pair candidates
+  static TClonesArray* fgCandidates;
+  
+  Int_t     fNCaloClusters;         // number of calorimeter clusters  
+  TClonesArray* fCaloClusters;        //->   array containing calorimeter clusters
+  static TClonesArray* fgCaloClusters;
+  
+  void ClearEvent();
+  AliCorrelationReducedEvent(const AliCorrelationReducedEvent &c);
+  AliCorrelationReducedEvent& operator= (const AliCorrelationReducedEvent &c);
+
+  ClassDef(AliCorrelationReducedEvent, 2);
+};
+
+//_______________________________________________________________________________
+inline UShort_t AliCorrelationReducedTrack::ITSncls() const
+{
+  //
+  // ITS number of clusters from the cluster map
+  //
+  UShort_t ncls=0;
+  for(Int_t i=0; i<6; ++i) ncls += (ITSLayerHit(i) ? 1 : 0);
+  return ncls;
+}
+
+
+//_______________________________________________________________________________
+inline Int_t AliCorrelationReducedTrack::TPCClusterMapBitsFired()  const
+{
+  //
+  // Count the number of bits fired in the TPC cluster map
+  //
+  Int_t nbits=0;
+  for(Int_t i=0; i<8; ++i) nbits += (TPCClusterMapBitFired(i) ? 1 : 0);
+  return nbits;
+}
+
+
+//_______________________________________________________________________________
+inline Float_t AliCorrelationReducedPair::Energy() const 
+{
+  //
+  // Return the energy
+  //
+  Float_t mass=fMass[0];
+  switch (fCandidateId) {
+    case kK0sToPiPi:
+      mass = fMass[0];
+      break;
+    case kLambda0ToPPi:
+      mass = fMass[1];
+      break;
+    case kALambda0ToPPi:
+      mass = fMass[2];
+      break;
+    default:
+      mass = fMass[0];
+      break;    
+  }
+  Float_t p = P();
+  return TMath::Sqrt(mass*mass+p*p);
+}
+
+
+//_______________________________________________________________________________
+inline Float_t AliCorrelationReducedPair::Rapidity() const
+{
+  //
+  // return rapidity
+  //
+  Float_t e = Energy();
+  Float_t pz = Pz();
+  if(e-TMath::Abs(pz)>1.0e-10)
+    return 0.5*TMath::Log((e+pz)/(e-pz));
+  else 
+    return -999.;
+}
+
+
+//_______________________________________________________________________________
+inline Double_t AliCorrelationReducedEventFriend::EventPlane(Int_t det, Int_t harmonic) const
+{
+  //
+  // Event plane from detector "det" and harmonic "harmonic"
+  //
+  if(det<0 || det>=kNdetectors || harmonic<1 || harmonic>fgkNMaxHarmonics) return -999.;
+  return TMath::ATan2(fQvector[det][harmonic-1][1], fQvector[det][harmonic-1][0])/Double_t(harmonic);
+}
+
+//_______________________________________________________________________________
+inline Bool_t AliCorrelationReducedEventFriend::CheckEventPlaneStatus(Int_t det, Int_t h, EventPlaneStatus flag) const {
+  //
+  // Check the status of the event plane for a given detector and harmonic
+  //
+  if(det<0 || det>=kNdetectors || h<1 || h>fgkNMaxHarmonics) return kFALSE;
+  return (flag<kNMaxFlowFlags ? (fEventPlaneStatus[det][h]&(1<<flag)) : kFALSE);
+}
+
+#endif
diff --git a/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/DstCommonMacros.C b/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/DstCommonMacros.C
new file mode 100644 (file)
index 0000000..40015e2
--- /dev/null
@@ -0,0 +1,1302 @@
+//
+// Common macros used to analyze dst trees
+// Author: Ionut-Cristian Arsene, 2012/03/04
+// email: i.c.arsene@gsi.de
+//
+#include <iostream>
+#include <fstream>
+using namespace std;
+
+#include <TObjArray.h>
+#include <TChain.h>
+#include <TMath.h>
+#include <TFile.h>
+#include <TDirectory.h>
+#include <THashList.h>
+#include <TH1F.h>
+#include <TH2F.h>
+#include <TH3F.h>
+#include <TProfile.h>
+#include <TProfile2D.h>
+#include <TIterator.h>
+#include <TKey.h>
+#include <TDirectory.h>
+#include <TAxis.h>
+
+#ifndef ALICORRELATIONREDUCEDEVENT_H
+#include "AliCorrelationReducedEvent.h"
+#endif
+
+namespace DstCommonMacros {
+
+  enum ParticleId {
+    kUnknown = -1,
+    kElectron = 0,
+    kPion,
+    kKaon,
+    kProton
+  };
+
+  enum Variables {
+    kNothing = -1,
+    // Event wise variables
+    kRunNo = 0,         // run number
+    kBC,                // bunch crossing
+    kTriggerMask,       // trigger mask
+    kOfflineTrigger,    // offline trigger
+    kOfflineTriggerFired,  // offline trigger fired
+    kOfflineTriggerFired2,  // offline trigger if fired, -1 if not fired
+    kIsPhysicsSelection,    // physics selection
+    kVtxX,              // vtx X
+    kVtxY,              // vtx Y
+    kVtxZ,              // vtx Z
+    kVtxXtpc,           // vtx X from tpc
+    kVtxYtpc,           // vtx Y from tpc
+    kVtxZtpc,           // vtx Z from tpc
+    kCentVZERO,         // centrality from VZERO
+    kCentSPD,           // centrality from SPD
+    kCentTPC,           // centrality from TPC
+    kCentZDC,           // centrality from ZDC
+    kCentQuality,       // centrality quality
+    kNV0total,          // total number of V0s in the esd
+    kNV0selected,       // number of V0s selected
+    kNdielectrons,      // number of dielectron pairs
+    kNpairsSelected,    // number of selected dielectron pairs per event
+    kNtracksTotal,      // total number of tracks
+    kNtracksSelected,   // number of selected tracks
+    kSPDntracklets,     // SPD number of tracklets in |eta|<1.0
+    kEventMixingId,     // Id of the event mixing category
+    // VZERO event plane related variables
+    kVZEROAemptyChannels,  // Number of empty VZERO channels in A side
+    kVZEROCemptyChannels,  // Number of empty VZERO channels in C side
+    kVZEROChannelMult,                        // VZERO multiplicity per channel
+    kVZEROChannelEta = kVZEROChannelMult+64,  // pseudo-rapidity of a VZERO channel
+    kVZEROQvecX      = kVZEROChannelEta+64,   // Q-vector components for harmonics 1-6 and 
+    kVZEROQvecY      = kVZEROQvecX+6*3,        //  6- n-harmonics; 3- A,C and A&C options
+    kVZERORP         = kVZEROQvecY+6*3,           // VZERO reaction plane from A,C and A&C sides (harmonics 1-6)
+    kVZERORPres      = kVZERORP+6*3,     // VZERO reaction plane resolution (sqrt(n*(RPa-RPc)))
+    kVZEROXaXc       = kVZERORPres+6,           // correlations for the components of the Q vector
+    kVZEROXaYa       = kVZEROXaXc+6,
+    kVZEROXaYc       = kVZEROXaYa+6,
+    kVZEROYaXc       = kVZEROXaYc+6,
+    kVZEROYaYc       = kVZEROYaXc+6,
+    kVZEROXcYc       = kVZEROYaYc+6,
+    kVZEROdeltaRPac  = kVZEROXcYc+6,         // Psi_VZEROA-Psi_VZEROC
+    kVZEROdeltaRPa   = kVZEROdeltaRPac+6,      // Psi_VZEROA6-Psi_VZEROA5, Psi_VZEROA7-Psi_VZEROA5, Psi_VZEROA6-Psi_VZEROA5 
+    kVZEROdeltaRPc   = kVZEROdeltaRPa+6*2,     // Psi_VZEROA2-Psi_VZEROA1, Psi_VZEROA3-Psi_VZEROA1, Psi_VZEROA4-Psi_VZEROA1
+    kVZEROflowV2TPC  = kVZEROdeltaRPc+6*2,     // vzero v2 using TPC event plane
+    // TPC event plane variables
+    kTPCQvecX = kVZEROflowV2TPC+64,   // TPC Q-vector components for harmonics 1-6
+    kTPCQvecY = kTPCQvecX+6,
+    kTPCRP    = kTPCQvecY+6,                // Event plane using TPC
+    kTPCRPres = kTPCRP+6,                // Event plane resolution variables sqrt(n*(RPtpc-RPvzeroa)),sqrt(n*(RPtpc-RPvzeroc))
+    // Correlations between TPC and VZERO event planes
+    kRPXtpcXvzeroa    = kTPCRPres+6*2,        
+    kRPXtpcXvzeroc    = kRPXtpcXvzeroa+6,
+    kRPYtpcYvzeroa    = kRPXtpcXvzeroc+6,
+    kRPYtpcYvzeroc    = kRPYtpcYvzeroa+6,
+    kRPXtpcYvzeroa    = kRPYtpcYvzeroc+6,
+    kRPXtpcYvzeroc    = kRPXtpcYvzeroa+6,
+    kRPYtpcXvzeroa    = kRPXtpcYvzeroc+6,
+    kRPYtpcXvzeroc    = kRPYtpcXvzeroa+6,
+    kRPdeltaVZEROAtpc = kRPYtpcXvzeroc+6,
+    kRPdeltaVZEROCtpc = kRPdeltaVZEROAtpc+6,
+    kNEventVars       = kRPdeltaVZEROCtpc+6,           // number of event variables
+    // Pair variables --------------------------------------
+    kMass=kNEventVars,
+    kCandidateId,
+    kPairType,                          // 0 ++; 1 +-; 2 --
+    kPairPt,
+    kPairPx,
+    kPairPy,
+    kPairPz,
+    kPairP,
+    kPairRap,
+    kPairEta,
+    kPairTheta,
+    kPairPhi,
+    kPairLxy,
+    kPairOpeningAngle,
+    kPairCosNPhi,                                                // cos (n*phi)
+    kPairSinNPhi             = kPairCosNPhi+6,                   // sin (n*phi)
+    kPairDeltaPhiVZEROFlowVn = kPairSinNPhi+6,                   // phi - Psi_{VZERO}
+    kPairDeltaPhiTPCFlowVn   = kPairDeltaPhiVZEROFlowVn+6*3,     // phi - Psi_{TPC}
+    kPairVZEROFlowVn         = kPairDeltaPhiTPCFlowVn+6,         // vn{Psi_{n,VZERO}}
+    kPairTPCFlowVn           = kPairVZEROFlowVn+6*3,             // vn{Psi_{n,TPC}}
+    kPairVZEROFlowV3Psi2     = kPairTPCFlowVn+6,                 // v3{Psi_{2,VZERO}}
+    kPairTPCFlowV3Psi2       = kPairVZEROFlowV3Psi2+3,           // v3{Psi_{2,TPC}}
+    // Track variables -------------------------------------
+    kPt=kPairTPCFlowV3Psi2+1,
+    kP,
+    kTheta,
+    kPhi,
+    kEta,
+    kRap,
+    kPtTPC,
+    kPhiTPC,
+    kEtaTPC,
+    kPin,
+    kTrackDeltaPhiVZEROFlowVn,
+    kTrackVZEROFlowVn = kTrackDeltaPhiVZEROFlowVn+6*2,
+    kDcaXY            = kTrackVZEROFlowVn+6*2,
+    kDcaZ,
+    kITSncls,
+    kITSsignal,
+    kTPCncls,
+    kTPCcrossedRows,
+    kTPCnclsIter1,
+    kTPCnclsF,
+    kTPCnclsRatio,
+    kTPCsignal,
+    kTPCnSig,
+    kTOFbeta=kTPCnSig+4,
+    kTOFnSig,
+    kTRDntracklets=kTOFnSig+4,
+    kTRDntrackletsPID,
+    kTRDpidProbabilities,
+    kEMCALmatchedEnergy=kTRDpidProbabilities+2,
+    kEMCALmatchedEOverP,
+    // Calorimeter cluster variables --------------------------------------
+    kEMCALclusterEnergy,
+    kEMCALclusterDx,
+    kEMCALclusterDz,
+    kEMCALdetector,         // 0 - EMCAL; 1 - PHOS
+    // Tracking flags -----------------------------------------------------
+    kTrackingFlag,
+    // Correlation variables ----------------------------------------------
+    kDeltaPhi,
+    kDeltaTheta,
+    kDeltaEta,
+    kNVars
+  };
+
+
+  Bool_t gUsedVars[kNVars] = {kFALSE};
+
+  // tracking flags as in AliESDtrack.h
+  // NOTE: check consistency with aliroot
+  enum TrackingFlags {
+    kITSin=0, 
+    kITSout,
+    kITSrefit,
+    kITSpid,
+    kTPCin,
+    kTPCout,
+    kTPCrefit,
+    kTPCpid,
+    kTRDin,
+    kTRDout, 
+    kTRDrefit,
+    kTRDpid,
+    kTOFin,
+    kTOFout,
+    kTOFrefit,
+    kTOFpid,
+    kTOFmismatch,
+    kHMPIDout,
+    kHMPIDpid,
+    kEMCALmatch,
+    kPHOSmatch,
+    kTRDbackup,
+    kTRDStop,
+    kESDpid,
+    kTIME,
+    kGlobalMerge,
+    kITSpureSA,
+    kMultInV0,
+    kMultSec,
+    kTRDnPlanes,
+    kEMCALNoMatch,
+    kNTrackingFlags
+  };
+
+  const Char_t* gkTrackingFlagNames[kNTrackingFlags] = {
+    "kITSin", "kITSout", "kITSrefit", "kITSpid",
+    "kTPCin", "kTPCout", "kTPCrefit", "kTPCpid",
+    "kTRDin", "kTRDout", "kTRDrefit", "kTRDpid",
+    "kTOFin", "kTOFout", "kTOFrefit", "kTOFpid", "kTOFmismatch",
+    "kHMPIDout", "kHMPIDpid", 
+    "kEMCALmatch", "kPHOSmatch", 
+    "kTRDbackup", "kTRDStop",
+    "kESDpid", "kTIME", "kGlobalMerge",
+    "kITSpureSA", 
+    "kMultInV0",
+    "kMultSec",
+    "kTRDnPlanes",
+    "kEMCALNoMatch"
+  };
+
+  // offline triggers as defined in AliVEvent.h
+  // NOTE: Check consistency with updates in aliroot!!!
+  enum EOfflineTriggerTypes { 
+    kMB           = BIT(0), // Minimum bias trigger, i.e. interaction trigger, offline SPD or V0 selection
+    kINT7         = BIT(1), // V0AND trigger, offline V0 selection
+    kMUON         = BIT(2), // Muon trigger, offline SPD or V0 selection
+    kHighMult     = BIT(3), // High-multiplicity trigger (threshold defined online), offline SPD or V0 selection
+    kEMC1         = BIT(4), // EMCAL trigger
+    kCINT5        = BIT(5), // Minimum bias trigger without SPD. i.e. interaction trigger, offline V0 selection
+    kCMUS5        = BIT(6), // Muon trigger, offline V0 selection
+    kMUSPB        = BIT(6), // idem for PbPb
+    kMUSH7        = BIT(7), // Muon trigger: high pt, single muon, offline V0 selection, CINT7 suite
+    kMUSHPB       = BIT(7), // idem for PbPb
+    kMUL7         = BIT(8), // Muon trigger: like sign dimuon, offline V0 selection, CINT7 suite
+    kMuonLikePB   = BIT(8), // idem for PbPb
+    kMUU7         = BIT(9), // Muon trigger, unlike sign dimuon, offline V0 selection, CINT7 suite
+    kMuonUnlikePB = BIT(9), // idem for PbPb
+    kEMC7         = BIT(10), // EMCAL trigger, CINT7 suite
+    kMUS7         = BIT(11), // Muon trigger: low pt, single muon, offline V0 selection, CINT7 suite
+    kPHI1         = BIT(12), // PHOS trigger, CINT1 suite
+    kPHI7         = BIT(13), // PHOS trigger, CINT7 suite
+    kPHOSPb       = BIT(13), // idem for PbPb
+    kEMCEJE       = BIT(14), // EMCAL jet patch trigger
+    kEMCEGA       = BIT(15), // EMCAL gamma trigger
+    kCentral      = BIT(16), // PbPb central collision trigger
+    kSemiCentral  = BIT(17), // PbPb semicentral collision trigger
+    kDG5          = BIT(18), // Double gap diffractive
+    kZED          = BIT(19), // ZDC electromagnetic dissociation
+    kUserDefined  = BIT(27), // Set when custom trigger classes are set in AliPhysicsSelection, offline SPD or V0 selection
+    // Bits 28 and above are reserved for FLAGS
+    kFastOnly     = BIT(30), // The fast cluster fired. This bit is set in to addition another trigger bit, e.g. kMB
+    kAny          = 0xffffffff, // to accept any trigger
+    kAnyINT       = kMB | kINT7 | kCINT5 // to accept any interaction (aka minimum bias) trigger
+  };
+
+  const Char_t* gkOfflineTriggerNames[64] = {
+    "MB",              "INT7",              "MUON", "HighMult",    "EMC1", "CINT5",       "CMUS5/MUSPB", "MUSH7/MUSHPB",
+    "MUL7/MuonLikePB", "MUU7/MuonUnlikePB", "EMC7", "MUS7",        "PHI1", "PHI7/PHOSPb", "EMCEJE",      "EMCEGA",
+    "Central",         "SemiCentral",       "DG5",  "ZED",         "N/A",  "N/A",         "N/A",         "N/A",  
+    "N/A",             "N/A",               "N/A",  "UserDefined", "N/A",  "N/A",         "FastOnly",    "N/A",
+    "N/A",             "N/A",               "N/A",  "N/A",         "N/A",  "N/A",         "N/A",         "N/A",
+    "N/A",             "N/A",               "N/A",  "N/A",         "N/A",  "N/A",         "N/A",         "N/A",
+    "N/A",             "N/A",               "N/A",  "N/A",         "N/A",  "N/A",         "N/A",         "N/A",
+    "N/A",             "N/A",               "N/A",  "N/A",         "N/A",  "N/A",         "N/A",         "N/A"
+  };
+
+  enum ITSLayerMap {
+    kITSfirst  =  1,
+    kITSsecond =  2,
+    kITSthird  =  4,
+    kITSfourth =  8,
+    kITSfifth  = 16,
+    kITSsixth  = 32
+  };
+
+  // radii of VZERO channels centers (in cm)
+  const Double_t gkVZEROChannelRadii[64] = {6.0567, 6.0567, 6.0567, 6.0567, 6.0567, 6.0567, 6.0567, 6.0567,
+                                           9.6977, 9.6977, 9.6977, 9.6977, 9.6977, 9.6977, 9.6977, 9.6977,
+                                          15.9504, 15.9504, 15.9504, 15.9504, 15.9504, 15.9504, 15.9504, 15.9504,
+                                          26.4031, 26.4031, 26.4031, 26.4031, 26.4031, 26.4031, 26.4031, 26.4031,
+                                           5.9347, 5.9347, 5.9347, 5.9347, 5.9347, 5.9347, 5.9347, 5.9347,
+                                          10.685, 10.685, 10.685, 10.685, 10.685, 10.685, 10.685, 10.685,
+                                          18.116, 18.116, 18.116, 18.116, 18.116, 18.116, 18.116, 18.116,
+                                          31.84, 31.84, 31.84, 31.84, 31.84, 31.84, 31.84, 31.84};
+  const Double_t gkVZEROAz = 340.0;   // cm
+  const Double_t gkVZEROCz = 90.0;    // cm
+  const Double_t gkVZEROminMult = 0.5;   // minimum VZERO channel multiplicity
+
+  // Pointer to the current event
+  AliCorrelationReducedEvent*       gCurrentEvent       = 0x0;
+  AliCorrelationReducedEventFriend* gCurrentEventFriend = 0x0;
+
+  // Event mixing variables
+  Int_t gEMCategories=0;
+  TString* gEMCategoryNames;
+
+  TObjArray* gHistLists=0x0;   // main histogram list for the current running process
+  TDirectoryFile* gHistListsOld=0x0;  // main directory for a standard tree analysis output (used for calibration, plotting etc.)
+  TFile* gHistFile = 0x0;      // pointer to a TFile opened for reading
+
+  TProfile2D* gVzeroAvMult[64] = {0x0};   // pointer to the array of average VZERO multiplicity per channel
+  TProfile2D* gQvecCentering[AliCorrelationReducedEventFriend::kNdetectors][fgkNMaxHarmonics][2] = {{{0x0}}};  // pointer to the array of Qvec centering histograms
+
+  // pt range for J/psi's
+  const Float_t gkJpsiPtCut[2] = {0.0, 20.0};
+
+  // Function prototypes
+  void WriteOutput(TFile* saveFile);
+  //void DefineHistograms(const Char_t* histClasses);
+  TChain* GetChain(const Char_t* filename, Int_t howMany, Int_t offset, Long64_t& entries, TChain* friendChain=0x0, const Char_t* friendChainFile=0x0);
+  void FillEventInfo(AliCorrelationReducedEvent* event, Float_t* values, AliCorrelationReducedEventFriend* eventF=0x0);
+  void FillEventOfflineTriggers(UShort_t triggerBit, Float_t* values);
+  void FillTrackingFlag(AliCorrelationReducedTrack* track, UShort_t flag, Float_t* values);
+  void FillTrackInfo(AliCorrelationReducedTrack* p, Float_t* values);
+  void FillPairInfo(AliCorrelationReducedPair* p, Float_t* values);
+  void FillPairInfo(AliCorrelationReducedTrack* t1, AliCorrelationReducedTrack* t2, Int_t type, Float_t* values);
+  void FillCorrelationInfo(AliCorrelationReducedPair* p, AliCorrelationReducedTrack* t, Float_t* values);
+  void FillCaloClusterInfo(AliCorrelationReducedCaloCluster* cl, Float_t* values);
+  void FillHistClass(const Char_t* className, Float_t* values);
+  void DoEventMixing(TList* list1, TList* list2, Float_t* values, Int_t mixingType, const Char_t* histClass);
+  void EventMixingPairTracks(TList* pairs, TList* tracks, Float_t* values);
+  void EventMixingResonanceLegs(TList* posLegs, TList* negLegs, Float_t* values, Int_t type, const Char_t* histClass);
+  Double_t DeltaPhi(Double_t phi1, Double_t phi2);  // calculate delta phi in the (-pi,+pi) interval
+  Bool_t IsPairSelectedEM(Float_t* values);        // pair selection used in the mixed event
+  void AddHistClass(const Char_t* histClass);
+  Int_t ValidateHistogramName(THashList* hList, const Char_t* name);
+  void AddHistogram(const Char_t* histClass,
+                   const Char_t* name, const Char_t* title, Bool_t isProfile,
+                    Int_t nXbins, Double_t xmin, Double_t xmax, Int_t varX,
+                   Int_t nYbins=0, Double_t ymin=0, Double_t ymax=0, Int_t varY=kNothing,
+                   Int_t nZbins=0, Double_t zmin=0, Double_t zmax=0, Int_t varZ=kNothing,
+                   const Char_t* xLabels="", const Char_t* yLabels="", const Char_t* zLabels="");
+  void AddHistogram(const Char_t* histClass,
+                   const Char_t* name, const Char_t* title, Bool_t isProfile,
+                    Int_t nXbins, Double_t* xbins, Int_t varX,
+                   Int_t nYbins=0, Double_t* ybins=0x0, Int_t varY=kNothing,
+                   Int_t nZbins=0, Double_t* zbins=0x0, Int_t varZ=kNothing,
+                   const Char_t* xLabels="", const Char_t* yLabels="", const Char_t* zLabels="");
+  void MakeAxisLabels(TAxis* ax, const Char_t* labels);
+  void InitFile(const Char_t* filename);    // open an old output filename
+  void CloseFile();
+  TObject* GetHistogram(const Char_t* listname, const Char_t* hname);  // get a histogram from an old output
+
+}  // end declarations for namespace DstCommonMacros
+
+//__________________________________________________________________
+void DstCommonMacros::FillEventInfo(AliCorrelationReducedEvent* event, Float_t* values, AliCorrelationReducedEventFriend* eventF/*=0x0*/) {
+  //
+  // fill event wise info
+  //
+  values[kRunNo]       = event->RunNo();
+  values[kBC]          = event->BC();
+  values[kTriggerMask] = event->TriggerMask();
+  values[kIsPhysicsSelection] = (event->IsPhysicsSelection() ? 1.0 : 0.0);
+  values[kVtxX]        = event->Vertex(0);
+  values[kVtxY]        = event->Vertex(1);
+  values[kVtxZ]        = event->Vertex(2);
+  values[kVtxXtpc]     = event->VertexTPC(0);
+  values[kVtxYtpc]     = event->VertexTPC(1);
+  values[kVtxZtpc]     = event->VertexTPC(2);
+  values[kCentVZERO]   = event->CentralityVZERO();
+  values[kCentSPD]     = event->CentralitySPD();
+  values[kCentTPC]     = event->CentralityTPC();
+  values[kCentZDC]     = event->CentralityZEMvsZDC();
+  values[kCentQuality] = event->CentralityQuality();
+  values[kNV0total]        = event->NV0CandidatesTotal();
+  values[kNV0selected]     = event->NV0Candidates();
+  values[kNdielectrons]    = event->NDielectrons();
+  values[kNtracksTotal]    = event->NTracksTotal();
+  values[kNtracksSelected] = event->NTracks();
+  values[kSPDntracklets]   = event->SPDntracklets();
+  values[kVZEROAemptyChannels] = 0;
+  values[kVZEROCemptyChannels] = 0;
+  for(Int_t ich=0;ich<64;++ich) gUsedVars[kVZEROChannelMult+ich] = kTRUE; 
+  Float_t theta=0.0;
+  for(Int_t ich=0;ich<64;++ich) {
+    if(gUsedVars[kVZEROChannelMult+ich]) {
+      values[kVZEROChannelMult+ich] = event->MultChannelVZERO(ich);
+      if(!gVzeroAvMult[0] && values[kVZEROChannelMult+ich]<gkVZEROminMult) {
+        gUsedVars[kVZEROChannelMult+ich] = kFALSE;   // will not be filled in histograms by the histogram manager
+        if(ich<32) values[kVZEROCemptyChannels] += 1;
+        else values[kVZEROAemptyChannels] += 1;
+      }
+    }
+    if(gUsedVars[kVZEROChannelEta+ich]) {
+      if(ich<32) theta = TMath::ATan(gkVZEROChannelRadii[ich]/(gkVZEROCz-values[kVtxZ]));
+      else theta = TMath::Pi()-TMath::ATan(gkVZEROChannelRadii[ich]/(gkVZEROAz-values[kVtxZ]));
+      values[kVZEROChannelEta+ich] = -1.0*TMath::Log(TMath::Tan(theta/2.0));
+    }
+  }
+  
+  if(eventF) {
+    for(Int_t ih=0; ih<6; ++ih) {
+      // VZERO event plane variables
+      values[kVZEROQvecX+2*6+ih] = 0.0;
+      values[kVZEROQvecY+2*6+ih] = 0.0;
+      values[kVZERORP   +2*6+ih] = 0.0;
+      for(Int_t iVZEROside=0; iVZEROside<2; ++iVZEROside) {
+        values[kVZEROQvecX+iVZEROside*6+ih] = eventF->Qx(AliCorrelationReducedEventFriend::kVZEROA+iVZEROside, ih+1);
+        values[kVZEROQvecY+iVZEROside*6+ih] = eventF->Qy(AliCorrelationReducedEventFriend::kVZEROA+iVZEROside, ih+1);
+        values[kVZERORP   +iVZEROside*6+ih] = eventF->EventPlane(AliCorrelationReducedEventFriend::kVZEROA+iVZEROside, ih+1);
+       values[kVZEROQvecX+2*6         +ih] += values[kVZEROQvecX+iVZEROside*6+ih];
+       values[kVZEROQvecY+2*6         +ih] += values[kVZEROQvecY+iVZEROside*6+ih];
+       // cos(n(EPtpc-EPvzero A/C))    
+        values[kTPCRPres+iVZEROside*6+ih] = DeltaPhi(eventF->EventPlane(AliCorrelationReducedEventFriend::kTPC, ih+1), eventF->EventPlane(AliCorrelationReducedEventFriend::kVZEROA+iVZEROside, ih+1));
+        values[kTPCRPres+iVZEROside*6+ih] = TMath::Cos(values[kTPCRPres+iVZEROside*6+ih]*(ih+1));
+      }
+      values[kVZERORP   +2*6+ih] = TMath::ATan2(values[kVZEROQvecY+2*6+ih],values[kVZEROQvecX+2*6+ih]);
+      // cos (n*(psi_A-psi_C))
+      values[kVZERORPres + ih] = DeltaPhi(eventF->EventPlane(AliCorrelationReducedEventFriend::kVZEROA, ih+1), 
+                                         eventF->EventPlane(AliCorrelationReducedEventFriend::kVZEROC, ih+1));
+      values[kVZERORPres + ih] = TMath::Cos(values[kVZERORPres + ih]*(ih+1));
+      // Qx,Qy correlations for VZERO
+      values[kVZEROXaXc+ih] = eventF->Qx(AliCorrelationReducedEventFriend::kVZEROA, ih+1)*eventF->Qx(AliCorrelationReducedEventFriend::kVZEROC, ih+1);
+      values[kVZEROXaYa+ih] = eventF->Qx(AliCorrelationReducedEventFriend::kVZEROA, ih+1)*eventF->Qy(AliCorrelationReducedEventFriend::kVZEROA, ih+1);
+      values[kVZEROXaYc+ih] = eventF->Qx(AliCorrelationReducedEventFriend::kVZEROA, ih+1)*eventF->Qy(AliCorrelationReducedEventFriend::kVZEROC, ih+1);
+      values[kVZEROYaXc+ih] = eventF->Qy(AliCorrelationReducedEventFriend::kVZEROA, ih+1)*eventF->Qx(AliCorrelationReducedEventFriend::kVZEROC, ih+1);
+      values[kVZEROYaYc+ih] = eventF->Qy(AliCorrelationReducedEventFriend::kVZEROA, ih+1)*eventF->Qy(AliCorrelationReducedEventFriend::kVZEROC, ih+1);
+      values[kVZEROXcYc+ih] = eventF->Qx(AliCorrelationReducedEventFriend::kVZEROC, ih+1)*eventF->Qy(AliCorrelationReducedEventFriend::kVZEROC, ih+1);
+      // Psi_A - Psi_C
+      values[kVZEROdeltaRPac+ih] = DeltaPhi(eventF->EventPlane(AliCorrelationReducedEventFriend::kVZEROA, ih+1), 
+                                           eventF->EventPlane(AliCorrelationReducedEventFriend::kVZEROC, ih+1));
+      
+      // TPC event plane
+      values[kTPCQvecX+ih] = eventF->Qx(AliCorrelationReducedEventFriend::kTPC, ih+1);
+      values[kTPCQvecY+ih] = eventF->Qy(AliCorrelationReducedEventFriend::kTPC, ih+1);
+      values[kTPCRP   +ih] = eventF->EventPlane(AliCorrelationReducedEventFriend::kTPC, ih+1);
+      // TPC VZERO Q-vector correlations
+      values[kRPXtpcXvzeroa+ih] = values[kTPCQvecX+ih]*values[kVZEROQvecX+ih];
+      values[kRPXtpcXvzeroc+ih] = values[kTPCQvecX+ih]*values[kVZEROQvecX+6+ih];
+      values[kRPYtpcYvzeroa+ih] = values[kTPCQvecY+ih]*values[kVZEROQvecY+ih];
+      values[kRPYtpcYvzeroc+ih] = values[kTPCQvecY+ih]*values[kVZEROQvecY+6+ih];
+      values[kRPXtpcYvzeroa+ih] = values[kTPCQvecX+ih]*values[kVZEROQvecY+ih];
+      values[kRPXtpcYvzeroc+ih] = values[kTPCQvecX+ih]*values[kVZEROQvecY+6+ih];
+      values[kRPYtpcXvzeroa+ih] = values[kTPCQvecY+ih]*values[kVZEROQvecX+ih];
+      values[kRPYtpcXvzeroc+ih] = values[kTPCQvecY+ih]*values[kVZEROQvecX+6+ih];
+      // Psi_TPC - Psi_VZERO A/C      
+      values[kRPdeltaVZEROAtpc+ih] = DeltaPhi(values[kVZERORP+0*6+ih], values[kTPCRP+ih]);
+      values[kRPdeltaVZEROCtpc+ih] = DeltaPhi(values[kVZERORP+1*6+ih], values[kTPCRP+ih]);
+    }  // end loop over harmonics
+    
+    // VZERO v2 using TPC event plane
+    Double_t vzeroChannelPhi[8] = {0.3927, 1.1781, 1.9635, 2.7489, -2.7489, -1.9635, -1.1781, -0.3927};
+    for(Int_t ich=0; ich<64; ++ich) {
+      if(gUsedVars[kVZEROflowV2TPC]) {
+        values[kVZEROflowV2TPC+ich] = values[kVZEROChannelMult+ich]*TMath::Cos(2.0*DeltaPhi(vzeroChannelPhi[ich%8],values[kTPCRP+1]));
+      } 
+    }
+  }  // end if (eventF)  
+}
+
+
+//_________________________________________________________________
+void DstCommonMacros::FillTrackingFlag(AliCorrelationReducedTrack* track, UShort_t flag, Float_t* values) {
+  //
+  // fill the tracking flag
+  //
+  values[kTrackingFlag] = -1;
+  if(track->CheckTrackStatus(flag)) values[kTrackingFlag] = flag;
+}
+
+
+//_________________________________________________________________
+void DstCommonMacros::FillEventOfflineTriggers(UShort_t triggerBit, Float_t* values) {
+  //
+  // fill the trigger bit input
+  //
+  if(triggerBit>=64) return;
+  if(!gCurrentEvent) return;
+  ULong64_t trigger = BIT(0);
+  values[kOfflineTrigger] = triggerBit;
+  values[kOfflineTriggerFired] = (gCurrentEvent->TriggerMask()&(trigger<<triggerBit) ? 1.0 : 0.0);
+  values[kOfflineTriggerFired2] = (values[kOfflineTriggerFired]>0.01 ? triggerBit : -1.0); 
+}
+
+
+//_________________________________________________________________
+void DstCommonMacros::FillTrackInfo(AliCorrelationReducedTrack* p, Float_t* values) {
+  //
+  // fill track information
+  //
+                        values[kPt]     = p->Pt();
+                        values[kPtTPC]  = p->PtTPC();
+  if(gUsedVars[kP])     values[kP]      = p->P();
+  if(gUsedVars[kTheta]) values[kTheta]  = p->Theta();
+                        values[kPhi]    = p->Phi();
+                        values[kPhiTPC] = p->PhiTPC();
+                        values[kEta]    = p->Eta();
+                        values[kEtaTPC] = p->EtaTPC();
+                        values[kPin]    = p->Pin();
+                        values[kDcaXY]  = p->DCAxy();
+                        values[kDcaZ]   = p->DCAz();
+  
+  if(gUsedVars[kITSncls]) values[kITSncls] = p->ITSncls();
+                          values[kITSsignal] = p->ITSsignal();
+  
+  values[kTPCncls] = p->TPCncls();
+  if(gUsedVars[kTPCnclsRatio]) 
+    values[kTPCnclsRatio] = (p->TPCFindableNcls()>0 ? Float_t(p->TPCncls())/Float_t(p->TPCFindableNcls()) : 0.0);
+  values[kTPCnclsIter1]   = p->TPCnclsIter1();
+  values[kTPCnclsF]       = p->TPCFindableNcls();
+  values[kTPCsignal]      = p->TPCsignal();
+  
+  values[kTOFbeta] = p->TOFbeta();
+  for(Int_t specie=kElectron; specie<=kProton; ++specie) {
+    values[kTPCnSig+specie] = p->TPCnSig(specie);
+    values[kTOFnSig+specie] = p->TOFnSig(specie);
+  }
+  values[kTRDpidProbabilities]   = p->TRDpid(0);
+  values[kTRDpidProbabilities+1] = p->TRDpid(1);
+  
+  values[kTRDntracklets]    = p->TRDntracklets(0);
+  values[kTRDntrackletsPID] = p->TRDntracklets(1);
+  
+  if(gUsedVars[kEMCALmatchedEnergy] || gUsedVars[kEMCALmatchedEOverP]) {
+    AliCorrelationReducedCaloCluster* cluster = gCurrentEvent->GetCaloCluster(p->CaloClusterId());
+    values[kEMCALmatchedEnergy] = (cluster ? cluster->Energy() : -999.0);
+    Float_t mom = p->P();
+    values[kEMCALmatchedEnergy] = (TMath::Abs(mom)>1.e-8 && cluster ? values[kEMCALmatchedEOverP]/mom : -999.0);
+  }
+  
+  // Fill track flow variables
+  for(Int_t iVZEROside=0; iVZEROside<2; ++iVZEROside) {
+    for(Int_t ih=0; ih<6; ++ih) {
+      if(gUsedVars[kTrackVZEROFlowVn+iVZEROside*6+ih] || gUsedVars[kTrackDeltaPhiVZEROFlowVn+iVZEROside*6+ih]) {
+        values[kTrackVZEROFlowVn+iVZEROside*6+ih]         = TMath::Cos(DeltaPhi(values[kPhi],values[kVZERORP+iVZEROside*6+ih])*(ih+1));
+        values[kTrackDeltaPhiVZEROFlowVn+iVZEROside*6+ih] = DeltaPhi(values[kPhi],values[kVZERORP+iVZEROside*6+ih]);
+      }
+    }
+  }
+}
+
+
+//_________________________________________________________________
+void DstCommonMacros::FillCaloClusterInfo(AliCorrelationReducedCaloCluster* cl, Float_t* values) {
+  //
+  // Fill calorimeter cluster information
+  //
+  values[kEMCALclusterEnergy] = cl->Energy();
+  values[kEMCALclusterDx] = cl->Dx();
+  values[kEMCALclusterDz] = cl->Dz();
+  values[kEMCALdetector] = (cl->IsEMCAL() ? AliCorrelationReducedCaloCluster::kEMCAL : AliCorrelationReducedCaloCluster::kPHOS);
+}
+
+
+//_________________________________________________________________
+void DstCommonMacros::FillPairInfo(AliCorrelationReducedPair* p, Float_t* values) {
+  //
+  // fill pair information
+  //
+  
+  values[kCandidateId] = p->CandidateId();
+  values[kPairType]    = p->PairType();
+  if(gUsedVars[kMass]) {
+    values[kMass] = p->Mass();
+    if(p->CandidateId()==AliCorrelationReducedPair::kLambda0ToPPi) values[kMass] = p->Mass(1);
+    if(p->CandidateId()==AliCorrelationReducedPair::kALambda0ToPPi) values[kMass] = p->Mass(2);
+  }
+                            values[kPairPt]           = p->Pt();
+  if(gUsedVars[kPairP])     values[kPairP]            = p->P();
+  if(gUsedVars[kPairPx])    values[kPairPx]           = p->Px();
+  if(gUsedVars[kPairPy])    values[kPairPy]           = p->Py();
+  if(gUsedVars[kPairPz])    values[kPairPz]           = p->Pz();
+                            values[kPairEta]          = p->Eta();
+  if(gUsedVars[kPairRap])   values[kPairRap]          = p->Rapidity();
+                            values[kPairPhi]          = p->Phi();
+                            values[kPairLxy]          = p->Lxy();
+                            values[kPairOpeningAngle] = p->OpeningAngle();
+  if(gUsedVars[kPairTheta]) values[kPairTheta]        = p->Theta();
+  
+  // Flow variables
+  // cos(n*phi), sin(n*phi)
+  for(Int_t ih=0; ih<6; ++ih) {
+    if(gUsedVars[kPairCosNPhi+ih]) values[kPairCosNPhi+ih] = TMath::Cos(values[kPairPhi]*(1.0+ih));
+    if(gUsedVars[kPairSinNPhi+ih]) values[kPairSinNPhi+ih] = TMath::Sin(values[kPairPhi]*(1.0+ih));
+  }
+  // VZERO  
+  for(Int_t iVZEROside=0; iVZEROside<3; ++iVZEROside) {
+    // v3 using VZERO Psi_2
+    if(gUsedVars[kPairVZEROFlowV3Psi2+iVZEROside]) 
+      values[kPairVZEROFlowV3Psi2+iVZEROside] = TMath::Cos(3.0*DeltaPhi(values[kPairPhi],values[kVZERORP+iVZEROside*6+1]));
+    for(Int_t ih=0; ih<6; ++ih) {
+      // vn using VZERO Psi_n
+      if(gUsedVars[kPairVZEROFlowVn+iVZEROside*6+ih]) 
+       values[kPairVZEROFlowVn+iVZEROside*6+ih] = TMath::Cos(DeltaPhi(values[kPairPhi], values[kVZERORP+iVZEROside*6+ih])*(ih+1));
+      // phi - Psi_n
+      if(gUsedVars[kPairDeltaPhiVZEROFlowVn+iVZEROside*6+ih])
+        values[kPairDeltaPhiVZEROFlowVn+iVZEROside*6+ih] = DeltaPhi(values[kPairPhi], values[kVZERORP+iVZEROside*6+ih]);
+    }
+  }
+  // TPC
+  // v3 using Psi_2
+  if(gUsedVars[kPairTPCFlowV3Psi2]) 
+    values[kPairTPCFlowV3Psi2] = TMath::Cos(3.0*DeltaPhi(values[kPairPhi],values[kTPCRP+1]));
+  for(Int_t ih=0; ih<6; ++ih) {
+    // vn using Psi_n
+    if(gUsedVars[kPairTPCFlowVn+ih]) 
+      values[kPairTPCFlowVn+ih] = TMath::Cos(DeltaPhi(values[kPairPhi],values[kTPCRP+ih])*(ih+1));
+    if(gUsedVars[kPairDeltaPhiTPCFlowVn+ih])
+      values[kPairDeltaPhiTPCFlowVn+ih] = DeltaPhi(values[kPairPhi], values[kTPCRP+ih]);
+  }
+}
+
+
+//_________________________________________________________________
+void DstCommonMacros::FillPairInfo(AliCorrelationReducedTrack* t1, AliCorrelationReducedTrack* t2, Int_t type, Float_t* values) {
+  //
+  // fill pair information from 2 tracks
+  //
+  // type - Parameter encoding the resonance type 
+  //        This is needed for making a mass assumption on the legs
+  //
+  if(gUsedVars[kPairType])  {
+    if(t1->Charge()*t2->Charge()<0) values[kPairType]  = 1;
+    else if(t1->Charge()>0)         values[kPairType]  = 0;
+    else                            values[kPairType]  = 2;
+  }
+  Float_t kMass1 = 0.0;
+  Float_t kMass2 = 0.0;
+  switch (type) {
+    case AliCorrelationReducedPair::kK0sToPiPi :
+      kMass1 = 0.13957; kMass2 = 0.13957;
+      break;
+    case AliCorrelationReducedPair::kPhiToKK :
+      kMass1 = 0.493677; kMass2 = 0.493677;
+      break;
+    case AliCorrelationReducedPair::kLambda0ToPPi :
+      kMass1 = 0.938272; kMass2 = 0.13957;
+      break;
+    case AliCorrelationReducedPair::kALambda0ToPPi :
+      kMass1 = 0.13957; kMass2 = 0.938272;
+      break;
+    case AliCorrelationReducedPair::kJpsiToEE :
+      kMass1 = 0.000511; kMass2 = 0.000511;
+      break;
+    default :
+      break;
+  }
+  
+  if(gUsedVars[kMass]) {     
+    values[kMass]      = kMass1*kMass1+kMass2*kMass2 + 
+                         2.0*(TMath::Sqrt(kMass1*kMass1+t1->P()*t1->P())*TMath::Sqrt(kMass2*kMass2+t2->P()*t2->P()) - 
+                         t1->Px()*t2->Px() - t1->Py()*t2->Py() - t1->Pz()*t2->Pz());
+    if(values[kMass]<0.0) {
+      cout << "FillPairInfo(track, track, type, values): Warning: Very small squared mass found. "
+           << "   Could be negative due to resolution of Float_t so it will be set to a small positive value." << endl; 
+      cout << "   mass2: " << values[kMass] << endl;
+      cout << "p1(p,x,y,z): " << t1->P() << ", " << t1->Px() << ", " << t1->Py() << ", " << t1->Pz() << endl;
+      cout << "p2(p,x,y,z): " << t2->P() << ", " << t2->Px() << ", " << t2->Py() << ", " << t2->Pz() << endl;
+      values[kMass] = 0.0;
+    }
+    else
+      values[kMass]      = TMath::Sqrt(values[kMass]);
+  }
+  
+  if(gUsedVars[kPairPt])    values[kPairPt]    = TMath::Sqrt((t1->Px()+t2->Px())*(t1->Px()+t2->Px()) +
+                                                             (t1->Py()+t2->Py())*(t1->Py()+t2->Py()));
+  if(gUsedVars[kPairP])     values[kPairP]     = TMath::Sqrt((t1->Px()+t2->Px())*(t1->Px()+t2->Px()) +
+                                                             (t1->Py()+t2->Py())*(t1->Py()+t2->Py()) +
+                                                             (t1->Pz()+t2->Pz())*(t1->Pz()+t2->Pz()));
+  if(gUsedVars[kPairEta])   {
+    Float_t p = TMath::Sqrt((t1->Px()+t2->Px())*(t1->Px()+t2->Px()) +
+                            (t1->Py()+t2->Py())*(t1->Py()+t2->Py()) +
+                            (t1->Pz()+t2->Pz())*(t1->Pz()+t2->Pz()));
+    values[kPairEta] = p-t1->Pz()-t2->Pz();
+    values[kPairEta] = (TMath::Abs(values[kPairEta])>1.0e-8 ? (p+t1->Pz()+t2->Pz())/values[kPairEta] : 0.0);
+    values[kPairEta]   = (values[kPairEta]>1.0e-8 ? 0.5*TMath::Log(values[kPairEta]) : -999.);
+  }
+  if(gUsedVars[kPairRap])   {
+    Float_t mass = kMass1*kMass1+kMass2*kMass2 +
+                   2.0*(TMath::Sqrt(kMass1*kMass1+t1->P()*t1->P())*TMath::Sqrt(kMass2*kMass2+t2->P()*t2->P()) - 
+                   t1->Px()*t2->Px() - t1->Py()*t2->Py() - t1->Pz()*t2->Pz());
+    if(mass<0.0) {
+      cout << "Negative squared mass (Float_t resolution). Setting mass to zero" << endl;
+      mass = 0.0;
+    }
+    else mass = TMath::Sqrt(mass);
+    Float_t e = TMath::Sqrt(mass*mass+
+                            (t1->Px()+t2->Px())*(t1->Px()+t2->Px()) +
+                            (t1->Py()+t2->Py())*(t1->Py()+t2->Py()) +
+                            (t1->Pz()+t2->Pz())*(t1->Pz()+t2->Pz()));
+    values[kPairRap]   = 0.5*TMath::Log((e+t1->Pz()+t2->Pz())/(e-t1->Pz()-t2->Pz()));
+  }
+  if(gUsedVars[kPairPhi])   {
+    values[kPairPhi]   = TMath::ATan2(t1->Py()+t2->Py(),t1->Px()+t2->Px());
+    if(values[kPairPhi]<0.0) values[kPairPhi] = 2.0*TMath::Pi() + values[kPairPhi];
+  }
+  if(gUsedVars[kPairTheta]) values[kPairTheta] = TMath::ACos((t1->Pz()+t2->Pz())/
+                                                             TMath::Sqrt((t1->Px()+t2->Px())*(t1->Px()+t2->Px()) +
+                                                                         (t1->Py()+t2->Py())*(t1->Py()+t2->Py()) +
+                                                                         (t1->Pz()+t2->Pz())*(t1->Pz()+t2->Pz())));
+  // Flow variables
+  // cos(n*phi), sin(n*phi)
+  for(Int_t ih=0; ih<6; ++ih) {
+    if(gUsedVars[kPairCosNPhi+ih]) values[kPairCosNPhi+ih] = TMath::Cos(values[kPairPhi]*(1.0+ih));
+    if(gUsedVars[kPairSinNPhi+ih]) values[kPairSinNPhi+ih] = TMath::Sin(values[kPairPhi]*(1.0+ih));
+  }
+  // VZERO  
+  for(Int_t iVZEROside=0; iVZEROside<3; ++iVZEROside) {
+    // v3 using VZERO Psi_2
+    if(gUsedVars[kPairVZEROFlowV3Psi2+iVZEROside]) 
+      values[kPairVZEROFlowV3Psi2+iVZEROside] = TMath::Cos(3.0*DeltaPhi(values[kPairPhi],values[kVZERORP+iVZEROside*6+1]));
+    for(Int_t ih=0; ih<6; ++ih) {
+      // vn using VZERO Psi_n
+      if(gUsedVars[kPairVZEROFlowVn+iVZEROside*6+ih]) 
+       values[kPairVZEROFlowVn+iVZEROside*6+ih] = TMath::Cos(DeltaPhi(values[kPairPhi], values[kVZERORP+iVZEROside*6+ih])*(ih+1));
+      // phi - Psi_n
+      if(gUsedVars[kPairDeltaPhiVZEROFlowVn+iVZEROside*6+ih])
+        values[kPairDeltaPhiVZEROFlowVn+iVZEROside*6+ih] = DeltaPhi(values[kPairPhi], values[kVZERORP+iVZEROside*6+ih]);
+    }
+  }
+  // TPC
+  // v3 using Psi_2
+  if(gUsedVars[kPairTPCFlowV3Psi2]) 
+    values[kPairTPCFlowV3Psi2] = TMath::Cos(3.0*DeltaPhi(values[kPairPhi],values[kTPCRP+1]));
+  for(Int_t ih=0; ih<6; ++ih) {
+    // vn using Psi_n
+    if(gUsedVars[kPairTPCFlowVn+ih]) 
+      values[kPairTPCFlowVn+ih] = TMath::Cos(DeltaPhi(values[kPairPhi],values[kTPCRP+ih])*(ih+1));
+    if(gUsedVars[kPairDeltaPhiTPCFlowVn+ih])
+      values[kPairDeltaPhiTPCFlowVn+ih] = DeltaPhi(values[kPairPhi], values[kTPCRP+ih]);
+  }
+}
+
+
+//__________________________________________________________________
+void DstCommonMacros::FillCorrelationInfo(AliCorrelationReducedPair* p, AliCorrelationReducedTrack* t, Float_t* values) {
+  //
+  // fill pair-track correlation information
+  //
+  if(gUsedVars[kDeltaPhi]) 
+    values[kDeltaPhi] = DeltaPhi(p->Phi(), t->Phi());
+  
+  if(gUsedVars[kDeltaTheta]) 
+    values[kDeltaTheta] = p->Theta() - t->Theta();
+  
+  if(gUsedVars[kDeltaEta]) values[kDeltaEta] = p->Eta() - t->Eta();
+}
+
+
+//__________________________________________________________________
+void DstCommonMacros::DoEventMixing(TList* list1, TList* list2, Float_t* values, Int_t type, const Char_t* histClass) {
+  //
+  // Do the event mixing
+  //
+  if(type==0) return;
+    
+  cout << "mixing ..." << endl; 
+  switch(type) {
+    case -1:
+      EventMixingPairTracks(list1, list2, values);    // list1 contains pairs; list2 contains tracks
+      break;
+    case AliCorrelationReducedPair::kJpsiToEE:
+      // type is needed to encode the type of resonance which is needed for the mass assumption of legs when calculating the invariant mass
+      EventMixingResonanceLegs(list1, list2, values, type, histClass);  // list1 contains positive legs; list2 contains negative legs
+      break;
+    default:
+      break;
+  }
+  
+  for(Int_t i=list1->GetEntries()-1; i>=0; --i) ((TList*)list1->At(i))->RemoveAll();
+  for(Int_t j=list2->GetEntries()-1; j>=0; --j) ((TList*)list2->At(j))->RemoveAll();
+  list1->Clear();
+  list2->Clear();
+}
+
+
+//__________________________________________________________________
+void DstCommonMacros::EventMixingPairTracks(TList* pairLists, TList* trackLists, Float_t* values) {
+  //
+  //  Make event mixing for pair - track correlations
+  //
+  cout << "Mixing category " << gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data() << endl;
+  Int_t entries = pairLists->GetEntries();   // we should have the same number of entries in both pair and track lists
+  if(entries<2) return;
+  
+  TList* pairs = 0x0;
+  TList* tracks = 0x0;
+  AliCorrelationReducedPair* pair = 0x0;
+  AliCorrelationReducedTrack* track = 0x0;
+  
+  TIter nextPairList(pairLists);
+  for(Int_t ie1=0; ie1<entries; ++ie1) {
+    pairs = (TList*)nextPairList();
+    
+    TIter nextTrackList(trackLists); 
+    for(Int_t ie2=0; ie2<entries; ++ie2) {
+      tracks = (TList*)nextTrackList();
+      if(ie1==ie2) continue;
+      
+      TIter nextPair(pairs);
+      for(Int_t ip=0; ip<pairs->GetEntries(); ++ip) {
+        pair = (AliCorrelationReducedPair*)nextPair();
+        FillPairInfo(pair, values);
+
+        TIter nextTrack(tracks);
+       Int_t leadingIdx = -1;
+       Float_t leadingPt = 0.0;
+        for(Int_t it=0; it<tracks->GetEntries(); ++it) {
+          track = (AliCorrelationReducedTrack*)nextTrack();
+          FillTrackInfo(track, values);
+
+          FillCorrelationInfo(pair, track, values);
+          if(pair->PairType()==1) 
+            FillHistClass(Form("Correlation_ME_US%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()),values);
+          if(pair->PairType()==0) {
+            FillHistClass(Form("Correlation_ME_LS%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()), values); 
+            FillHistClass(Form("Correlation_ME_LSpp%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()), values);
+          }
+          if(pair->PairType()==2) {
+            FillHistClass(Form("Correlation_ME_LS%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()), values); 
+            FillHistClass(Form("Correlation_ME_LSmm%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()), values);
+          }
+          if(track->Pt()>leadingPt) {
+           leadingPt = track->Pt();
+           leadingIdx = it;
+         }
+        }   // end loop over tracks
+        if(leadingIdx!=-1) {
+         track = (AliCorrelationReducedTrack*)tracks->At(leadingIdx);
+         FillTrackInfo(track, values);
+         FillCorrelationInfo(pair, track, values);
+          if(pair->PairType()==1) 
+           FillHistClass(Form("Correlation_LeadingPt_ME_US%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()),values);
+          if(pair->PairType()==0) {
+            FillHistClass(Form("Correlation_LeadingPt_ME_LS%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()),values);
+            FillHistClass(Form("Correlation_LeadingPt_ME_LSpp%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()),values);
+          }
+          if(pair->PairType()==2) {
+            FillHistClass(Form("Correlation_LeadingPt_ME_LS%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()),values);
+            FillHistClass(Form("Correlation_LeadingPt_ME_LSmm%s", gEMCategoryNames[TMath::Nint(values[kEventMixingId])].Data()),values);
+         }
+       }
+      }   // end loop over pairs      
+    }  // end loop over second event
+  }  // end loop over first event
+}
+
+
+//__________________________________________________________________
+void DstCommonMacros::EventMixingResonanceLegs(TList* posLists, TList* negLists, Float_t* values, Int_t type, const Char_t* histClass) {
+  //
+  // Do event mixing with the legs of a resonance to obtain the background
+  //
+  cout << "Mixing event class " << histClass << ", (cent/vtx): " << values[kCentVZERO] << "/" << values[kVtxZ] << endl;
+  Int_t entries = posLists->GetEntries();
+  cout << "mixing positives: " << entries << endl;
+  cout << "mixing negatives: " << negLists->GetEntries() << endl;
+  if(entries<2) return;
+  
+  TList* positives1 = 0x0;   // list of tracks in the first event
+  //TList* negatives1 = 0x0;
+  //TList* positives2 = 0x0;   // list of tracks in the second event
+  TList* negatives2 = 0x0;
+  AliCorrelationReducedTrack* posTrack1 = 0x0;
+  //AliCorrelationReducedTrack* negTrack1 = 0x0;
+  //AliCorrelationReducedTrack* posTrack2 = 0x0;
+  AliCorrelationReducedTrack* negTrack2 = 0x0;
+  
+  TIter nextPosList1(posLists);
+  TIter nextNegList1(negLists);
+  for(Int_t ie1=0; ie1<entries; ++ie1) {
+    positives1 = (TList*)nextPosList1();
+    //negatives1 = (TList*)nextNegList1();
+    
+    TIter nextPosList2(posLists);
+    TIter nextNegList2(negLists);
+    for(Int_t ie2=0; ie2<entries; ++ie2) {
+      //positives2 = (TList*)nextPosList2();
+      negatives2 = (TList*)nextNegList2();
+      if(ie1==ie2) continue;    // no SE mixing
+      
+      TIter nextPosLeg1(positives1);
+      while((posTrack1=(AliCorrelationReducedTrack*)nextPosLeg1())) {
+        /*TIter nextPosLeg2(positives2);
+        while((posTrack2=(AliCorrelationReducedTrack*)nextPosLeg2())) {
+          FillPairInfo(posTrack1, posTrack2, type, values);             // ++ combinations
+          FillHistClass(Form("%s_LSpp", histClass),values);
+        }    // end while over pos legs in event 2
+        */
+        TIter nextNegLeg2(negatives2);
+        while((negTrack2=(AliCorrelationReducedTrack*)nextNegLeg2())) {
+          FillPairInfo(posTrack1, negTrack2, type, values);             // +- combinations
+         if(IsPairSelectedEM(values))
+            FillHistClass(histClass, values);
+        }    // end while over neg legs in event 2
+      }    // end while over pos legs in event 1
+      /*TIter nextNegLeg1(negatives1);
+      while((negTrack1=(AliCorrelationReducedTrack*)nextNegLeg1())) {
+        TIter nextNegLeg2(negatives2);
+        while((negTrack2=(AliCorrelationReducedTrack*)nextNegLeg2())) {
+          FillPairInfo(negTrack1, negTrack2, type, values);             // -- combinations
+          FillHistClass(Form("%s_LSmm", histClass),values);
+        }    // end while over neg legs in event 2
+      }    // end while over neg legs in event 1
+      */
+    }    // end for over event 2
+  }    // end for over event 1
+}
+
+
+
+
+//________________________________________________________________
+Double_t DstCommonMacros::DeltaPhi(Double_t phi1, Double_t phi2) {
+  //
+  // compute the delta of two angles defined in the (-pi,+pi) interval
+  //
+  Double_t delta = phi1-phi2;
+  if(delta>2.0*TMath::Pi()) delta -= 2.0*TMath::Pi();
+  if(delta<0.0) delta += 2.0*TMath::Pi();
+  /*Double_t delta = phi2;
+  if(phi2<0.0) delta += 2.0*TMath::Pi();
+  delta = phi1-delta;
+  if(delta>TMath::Pi()) delta = delta - 2.0*TMath::Pi();
+  if(delta<-1.*TMath::Pi()) delta = 2.0*TMath::Pi() + delta;
+  */
+  return delta;
+}
+
+
+//__________________________________________________________________
+void DstCommonMacros::FillHistClass(const Char_t* className, Float_t* values) {
+  //
+  //  fill a class of histograms
+  //
+  THashList* hList = (THashList*)gHistLists->FindObject(className);
+  if(!hList) {
+    //cout << "Warning in FillHistClass(): Histogram class " << className << " not found" << endl;
+    return;
+  }
+    
+  TIter next(hList);
+  TObject* h=0x0;
+  while((h=next())) {
+    UInt_t id = h->GetUniqueID();
+    UInt_t varX = id%kNVars;
+    UInt_t varY = (id/kNVars)%kNVars;
+    UInt_t varZ = (id/kNVars/kNVars)%kNVars;
+    if(id<kNVars) { 
+      ((TH1F*)h)->Fill(values[varX]);
+    } else if(id<kNVars*kNVars) {
+      if(((TH1*)h)->GetDimension()==1) ((TProfile*)h)->Fill(values[varX],values[varY]);
+      if(((TH1*)h)->GetDimension()==2) ((TH2F*)h)->Fill(values[varX],values[varY]);
+    } else {
+      if(((TH1*)h)->GetDimension()==2) ((TProfile2D*)h)->Fill(values[varX],values[varY],values[varZ]);
+      if(((TH1*)h)->GetDimension()==3) ((TH3F*)h)->Fill(values[varX],values[varY],values[varZ]);
+    };
+  }
+}
+
+
+//__________________________________________________________________
+void DstCommonMacros::AddHistClass(const Char_t* histClass) {
+  //
+  // Add a new histogram list
+  //
+  if(!gHistLists)
+    gHistLists = new TObjArray();
+  gHistLists->SetOwner();
+  gHistLists->SetName("histos");
+  
+  if(gHistLists->FindObject(histClass)) {
+    cout << "Warning in AddHistClass: Cannot add histogram class " << histClass
+         << " because it already exists." << endl;
+    return;
+  }
+  THashList* hList=new THashList;
+  hList->SetOwner(kTRUE);
+  hList->SetName(histClass);
+  gHistLists->Add(hList);
+}
+
+
+//_________________________________________________________________
+Int_t DstCommonMacros::ValidateHistogramName(THashList* hList, const Char_t* name) {
+  //
+  // check whether a histogram with this name already exist, and how many of them
+  //
+  for(Int_t i=0; i<hList->GetEntries(); ++i) {
+    TString hname = hList->At(i)->GetName();
+    TObjArray* arr=hname.Tokenize("#");
+    TString nameRoot = arr->At(0)->GetName();
+    if(nameRoot.CompareTo(name)==0) {
+      cout << "Warning in AddHistogram(): Histogram " << name << " already exists in this list (" << nameRoot.Data() << ")" << endl;
+      return -1;
+    }
+  }
+  Int_t nnames = 0;
+  for(Int_t il=0; il<gHistLists->GetEntries(); ++il) {
+    THashList* tlist = (THashList*)gHistLists->At(il);
+    for(Int_t ih=0; ih<tlist->GetEntries(); ++ih) {
+      TString hname = tlist->At(ih)->GetName();
+      TObjArray* arr=hname.Tokenize("#");
+      TString nameRoot = arr->At(0)->GetName();
+      if(nameRoot.CompareTo(name)==0) ++nnames;
+    }
+  }
+  return nnames;
+}
+
+
+//_________________________________________________________________
+void DstCommonMacros::AddHistogram(const Char_t* histClass,
+                                  const Char_t* name, const Char_t* title, Bool_t isProfile,
+                                   Int_t nXbins, Double_t xmin, Double_t xmax, Int_t varX,
+                                  Int_t nYbins, Double_t ymin, Double_t ymax, Int_t varY,
+                                  Int_t nZbins, Double_t zmin, Double_t zmax, Int_t varZ,
+                                  const Char_t* xLabels, const Char_t* yLabels, const Char_t* zLabels) {
+  //
+  // add a histogram
+  //
+  THashList* hList = (THashList*)gHistLists->FindObject(histClass);
+  if(hList->FindObject(name)) {
+    cout << "Warning in AddHistogram(): Histogram " << name << " already exists" << endl;
+    return;
+  }
+  /*Int_t nnames = ValidateHistogramName(hList, name);
+  if(nnames<0) return;
+  TString hname = Form("%s#v%d", name, nnames);
+  cout << "Assigned name " << hname.Data() << endl;*/
+  TString hname = name;
+  
+  Int_t dimension = 1;
+  if(varY!=kNothing) dimension = 2;
+  if(varZ!=kNothing) dimension = 3;
+  
+  TString titleStr(title);
+  TObjArray* arr=titleStr.Tokenize(";");
+  
+  TH1* h=0x0;
+  switch(dimension) {
+    case 1:
+      h=new TH1F(hname.Data(),arr->At(0)->GetName(),nXbins,xmin,xmax);
+      //cout << "HISTOGRAM " << hname.Data() << ", ID: " << UInt_t(varX) << endl;
+      h->SetUniqueID(UInt_t(varX));
+      if(arr->At(1)) h->GetXaxis()->SetTitle(arr->At(1)->GetName());
+      if(xLabels[0]!='\0') MakeAxisLabels(h->GetXaxis(), xLabels);
+      gUsedVars[varX] = kTRUE;
+      hList->Add(h);
+      break;
+    case 2:
+      if(isProfile)
+       h=new TProfile(hname.Data(),arr->At(0)->GetName(),nXbins,xmin,xmax);
+      else
+       h=new TH2F(hname.Data(),arr->At(0)->GetName(),nXbins,xmin,xmax,nYbins,ymin,ymax);
+      //cout << "HISTOGRAM " << hname.Data() << ", ID: " << UInt_t(varX+kNVars*varY) << endl;
+      h->SetUniqueID(UInt_t(varX+kNVars*varY));
+      if(arr->At(1)) h->GetXaxis()->SetTitle(arr->At(1)->GetName());
+      if(xLabels[0]!='\0') MakeAxisLabels(h->GetXaxis(), xLabels);
+      if(arr->At(2)) h->GetYaxis()->SetTitle(arr->At(2)->GetName());
+      if(yLabels[0]!='\0') MakeAxisLabels(h->GetYaxis(), yLabels);
+      gUsedVars[varX] = kTRUE;
+      gUsedVars[varY] = kTRUE;
+      hList->Add(h);
+      break;
+    case 3:
+      if(isProfile)
+       h=new TProfile2D(hname.Data(),arr->At(0)->GetName(),nXbins,xmin,xmax,nYbins,ymin,ymax);
+      else
+       h=new TH3F(hname.Data(),arr->At(0)->GetName(),nXbins,xmin,xmax,nYbins,ymin,ymax,nZbins,zmin,zmax);
+      //cout << "HISTOGRAM " << hname.Data() << ", ID: " << UInt_t(varX+kNVars*varY+kNVars*kNVars*varZ) << endl;
+      h->SetUniqueID(UInt_t(varX+kNVars*varY+kNVars*kNVars*varZ));
+      if(arr->At(1)) h->GetXaxis()->SetTitle(arr->At(1)->GetName());
+      if(xLabels[0]!='\0') MakeAxisLabels(h->GetXaxis(), xLabels);
+      if(arr->At(2)) h->GetYaxis()->SetTitle(arr->At(2)->GetName());
+      if(yLabels[0]!='\0') MakeAxisLabels(h->GetYaxis(), yLabels);
+      if(arr->At(3)) h->GetZaxis()->SetTitle(arr->At(3)->GetName());
+      if(zLabels[0]!='\0') MakeAxisLabels(h->GetZaxis(), zLabels);
+      gUsedVars[varX] = kTRUE;
+      gUsedVars[varY] = kTRUE;
+      gUsedVars[varZ] = kTRUE;
+      hList->Add(h);
+      break;
+  }
+}
+
+//_________________________________________________________________
+void DstCommonMacros::AddHistogram(const Char_t* histClass,
+                                  const Char_t* name, const Char_t* title, Bool_t isProfile,
+                                   Int_t nXbins, Double_t* xbins, Int_t varX,
+                                  Int_t nYbins, Double_t* ybins, Int_t varY,
+                                  Int_t nZbins, Double_t* zbins, Int_t varZ,
+                                  const Char_t* xLabels, const Char_t* yLabels, const Char_t* zLabels) {
+  //
+  // add a histogram
+  //
+  THashList* hList = (THashList*)gHistLists->FindObject(histClass);
+  if(hList->FindObject(name)) {
+    cout << "Warning in AddHistogram(): Histogram " << name << " already exists" << endl;
+    return;
+  }
+  //Int_t nnames = ValidateHistogramName(hList, name);
+  //if(nnames<0) return;
+  //TString hname = Form("%s#v%d", name, nnames);
+  TString hname = name;
+  
+  Int_t dimension = 1;
+  if(varY!=kNothing) dimension = 2;
+  if(varZ!=kNothing) dimension = 3;
+  
+  TString titleStr(title);
+  TObjArray* arr=titleStr.Tokenize(";");
+  
+  TH1* h=0x0;
+  switch(dimension) {
+    case 1:
+      h=new TH1F(hname.Data(),arr->At(0)->GetName(),nXbins,xbins);
+      //cout << "HISTOGRAM " << hname.Data() << ", ID: " << UInt_t(varX) << endl;
+      h->SetUniqueID(UInt_t(varX));
+      if(arr->At(1)) h->GetXaxis()->SetTitle(arr->At(1)->GetName());
+      if(xLabels[0]!='\0') MakeAxisLabels(h->GetXaxis(), xLabels);
+      gUsedVars[varX] = kTRUE;
+      hList->Add(h);
+      break;
+    case 2:
+      if(isProfile)
+       h=new TProfile(hname.Data(),arr->At(0)->GetName(),nXbins,xbins);
+      else
+       h=new TH2F(hname.Data(),arr->At(0)->GetName(),nXbins,xbins,nYbins,ybins);
+      //cout << "HISTOGRAM " << hname.Data() << ", ID: " << UInt_t(varX+kNVars*varY) << endl;
+      h->SetUniqueID(UInt_t(varX+kNVars*varY));
+      if(arr->At(1)) h->GetXaxis()->SetTitle(arr->At(1)->GetName());
+      if(xLabels[0]!='\0') MakeAxisLabels(h->GetXaxis(), xLabels);
+      if(arr->At(2)) h->GetYaxis()->SetTitle(arr->At(2)->GetName());
+      if(yLabels[0]!='\0') MakeAxisLabels(h->GetYaxis(), yLabels);
+      gUsedVars[varX] = kTRUE;
+      gUsedVars[varY] = kTRUE;
+      hList->Add(h);
+      break;
+    case 3:
+      if(isProfile)
+       h=new TProfile2D(hname.Data(),arr->At(0)->GetName(),nXbins,xbins,nYbins,ybins);
+      else
+       h=new TH3F(hname.Data(),arr->At(0)->GetName(),nXbins,xbins,nYbins,ybins,nZbins,zbins);
+      //cout << "HISTOGRAM " << hname.Data() << ", ID: " << UInt_t(varX+kNVars*varY+kNVars*kNVars*varZ) << endl;
+      h->SetUniqueID(UInt_t(varX+kNVars*varY+kNVars*kNVars*varZ));
+      if(arr->At(1)) h->GetXaxis()->SetTitle(arr->At(1)->GetName());
+      if(xLabels[0]!='\0') MakeAxisLabels(h->GetXaxis(), xLabels);
+      if(arr->At(2)) h->GetYaxis()->SetTitle(arr->At(2)->GetName());
+      if(yLabels[0]!='\0') MakeAxisLabels(h->GetYaxis(), yLabels);
+      if(arr->At(3)) h->GetZaxis()->SetTitle(arr->At(3)->GetName());
+      if(zLabels[0]!='\0') MakeAxisLabels(h->GetZaxis(), zLabels);
+      gUsedVars[varX] = kTRUE;
+      gUsedVars[varY] = kTRUE;
+      gUsedVars[varZ] = kTRUE;
+      hList->Add(h);
+      break;
+  }
+}
+
+
+//____________________________________________________________________________________
+void DstCommonMacros::MakeAxisLabels(TAxis* ax, const Char_t* labels) {
+  //
+  // add bin labels to an axis
+  //
+  TString labelsStr(labels);
+  TObjArray* arr=labelsStr.Tokenize(";");
+  for(Int_t ib=1; ib<=ax->GetNbins(); ++ib) {
+    if(ib>=arr->GetEntries()+1) break;
+    ax->SetBinLabel(ib, arr->At(ib-1)->GetName());
+  }
+}
+
+
+//____________________________________________________________________________________
+void DstCommonMacros::InitFile(const Char_t* filename) {
+  //
+  // Open an existing ROOT file containing lists of histograms and initialize the global list pointer
+  //
+  //if(gHistFile) gHistFile->Close();
+  TString histfilename="";
+  if(gHistFile) histfilename = gHistFile->GetName();
+  if(!histfilename.Contains(filename)) 
+    gHistFile = new TFile(filename);    // open file only if not already open
+  
+  if(!gHistFile) {
+    cout << "GlobalMacros.C::GetHistogram() : File " << filename << " not opened!!" << endl;
+    return;
+  }
+  if(gHistFile->IsZombie()) {
+    cout << "GlobalMacros.C::GetHistogram() : File " << filename << " not opened!!" << endl;
+    return;
+  }
+  TList* list1 = gHistFile->GetListOfKeys();
+  TKey* key1 = (TKey*)list1->At(0);
+  gHistListsOld = (TDirectoryFile*)key1->ReadObj();
+}
+
+
+//____________________________________________________________________________________
+void DstCommonMacros::CloseFile() {
+  //
+  // Close the opened file
+  //
+  gHistListsOld = 0x0;
+  if(gHistFile && gHistFile->IsOpen()) gHistFile->Close();
+}
+
+
+//____________________________________________________________________________________
+TObject* DstCommonMacros::GetHistogram(const Char_t* listname, const Char_t* hname) {
+  //
+  // Retrieve a histogram from the list hlist
+  //
+  if(!gHistListsOld) {
+    cout << "GlobalMacros.C::GetHistogram() : The main list was not initialized." << endl;
+    cout << "                   A ROOT file must pe initialized first!!" << endl;
+    return 0x0;
+  }
+  TKey* listKey = gHistListsOld->FindKey(listname);
+  TDirectoryFile* hlist = (TDirectoryFile*)listKey->ReadObj();
+  TKey* key = hlist->FindKey(hname);
+  return key->ReadObj();
+}
+
+
+//_________________________________________________________________
+TChain* DstCommonMacros::GetChain(const Char_t* filename, Int_t howMany, Int_t offset, Long64_t& entries,
+                                  TChain* friendChain/*=0x0*/, const Char_t* friendChainFile/*=0x0*/) {
+  //
+  // read an ascii file containing a list of root files with reduced trees
+  // and build a TChain
+  //
+  cout << "Creating the data chain from " << filename << " ..." << flush; 
+  TChain* chain = new TChain("DstTree");
+  ifstream inBuf;
+  inBuf.open(filename);
+  Int_t index = 0;
+  while(inBuf.good()) {
+    Char_t str[512];
+    inBuf.getline(str,512,'\n');
+    
+    if(index<offset) {++index; continue;}
+    if(index>=offset+howMany) break;
+    
+    TString strstr = str;
+    if(!strstr.Contains(".root")) continue;
+    cout << endl << "Adding file " << str << endl;
+    chain->Add(str);
+    if(friendChain) {
+      TObjArray* arr = strstr.Tokenize("/");
+      strstr.ReplaceAll(arr->At(arr->GetEntries()-1)->GetName(),friendChainFile);
+      friendChain->Add(strstr.Data());
+    }    
+    ++index;
+  }
+  inBuf.close();
+  entries = chain->GetEntries();
+  Long64_t entriesFriend = (friendChain ? friendChain->GetEntries() : 0);
+  cout << "DstCommonMacros::GetChain() Chain entries = " << entries << endl;
+  if(friendChain)
+    cout << "DstCommonMacros::GetChain() Friend chain entries = " << entriesFriend << endl;
+  if(friendChain && (entries!=entriesFriend)) {
+    cout << "DstCommonMacros::GetChain() The friend chain does not have the same number of entries as the main chain!!!" << endl;
+    cout << "                            Check it out and retry !!" << endl;
+    return 0x0;
+  }
+  cout << " done" << endl;
+  return chain;
+}
+
+
+//__________________________________________________________________
+void DstCommonMacros::WriteOutput(TFile* save) {
+  //
+  // Write the histogram lists in the output file
+  //
+  cout << "Writing the output to " << save->GetName() << " ... " << flush;
+  //TFile* save=new TFile(filename,"RECREATE");
+  TDirectory* mainDir = save->mkdir(gHistLists->GetName());
+  mainDir->cd();
+  for(Int_t i=0; i<gHistLists->GetEntries(); ++i) {
+    THashList* list = (THashList*)gHistLists->At(i);
+    TDirectory* dir = mainDir->mkdir(list->GetName());
+    dir->cd();
+    list->Write();
+    mainDir->cd();
+  }
+  save->Close();
+  cout << "done" << endl;
+}
+
+
+//__________________________________________________________________
+Bool_t DstCommonMacros::IsPairSelectedEM(Float_t* values) {
+  //
+  // pair selection on the pair resulting from the event mixing
+  //
+  if(values[kPairPt]<gkJpsiPtCut[0]) return kFALSE;
+  if(values[kPairPt]>gkJpsiPtCut[1]) return kFALSE;
+  return kTRUE;
+}
diff --git a/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/RunDstPbPbJpsiAnalysis.C b/PWGDQ/dielectron/macrosJPSI/RaaPbPb2010/RunDstPbPbJpsiAnalysis.C
new file mode 100644 (file)
index 0000000..526356c
--- /dev/null
@@ -0,0 +1,928 @@
+// J/psi analysis in PbPb
+// author: Ionut-Cristian Arsene, i.c.arsene@gsi.de
+//         2012/Apr/11
+
+#include <iostream>
+using namespace std;
+
+#include <TTimeStamp.h>
+
+#ifndef ALICORRELATIONREDUCEDEVENT_H
+#include "AliCorrelationReducedEvent.h"
+#endif
+
+#include "DstCommonMacros.C"
+using namespace DstCommonMacros;
+
+// function prototypes
+void DefineHistograms(const Char_t* histClasses, const Char_t* output);
+Bool_t IsEventSelected(AliCorrelationReducedEvent* event);
+Bool_t IsLegSelected(AliCorrelationReducedTrack* track, Bool_t* legQualityMap);
+Bool_t IsLegSelected(AliCorrelationReducedTrack* track);
+Bool_t IsLegSelectedTRD(AliCorrelationReducedTrack* track, Int_t trdCut=-1, Int_t trdMinNtr=4, Float_t eleCut=0.7);
+Bool_t IsLegSelectedTOF(AliCorrelationReducedTrack* track, Int_t tofCut=-1, Float_t lowExcl=0.3, Float_t highExcl=0.93);
+Bool_t IsTrackUsedForMixing(UShort_t* idxArr, UShort_t size, UShort_t idx);
+Bool_t IsPairSelected(AliCorrelationReducedPair* pair);
+void RunDstPbPbJpsiAnalysis(const Char_t* output, const Char_t* inputfilename,
+                           Int_t howMany/* = 5000*/, Int_t offset/* = 0*/);
+
+TFile* gSaveFile=0x0;
+// event plane friend file 
+const Char_t* gkEPfile="dstTree_VZERO_TPC_recentered.root";
+
+// mixing pool depth
+const Int_t gkEventMixingPoolDepth = 100;
+
+// centrality binning for the event mixing
+const Int_t gkNCentRanges = 3;
+/*Double_t gkEMCentLims[gkNCentRanges+1] = { 0.0,  2.5,  5.0,  7.5, 10.0, 
+                                          12.5, 15.0, 17.5, 20.0, 22.5,
+                                         25.0, 27.5, 30.0, 32.5, 35.0, 
+                                         37.5, 40.0, 50.0, 60.0, 70.0, 80.0};*/
+Double_t gkEMCentLims[gkNCentRanges+1] = { 0.0,  10.0, 40.0, 80.0};
+// vertex binning for the event mixing                                   
+const Int_t gkNVtxRanges = 1;
+//Double_t gkEMVtxLims[gkNVtxRanges+1] = {-10.0, -6.0, -2.0, 2.0, 6.0, 10.0};
+Double_t gkEMVtxLims[gkNVtxRanges+1] = {-10.0, 10.0};
+
+// event plane angle binning for the event mixing
+const Int_t gkNPhiEPRanges = 1;
+Double_t gkEMPhiEPLims[gkNPhiEPRanges+1] = {-1.5708, 1.5708};
+//Double_t gkEMPhiEPLims[gkNPhiEPRanges+1] = {-1.5708, -1.2566, -0.94248, -0.62832, -0.31415926, 0.0, 0.31415926, 0.62832, 0.94248, 1.2566, 1.5708};
+/*Double_t gkEMPhiEPLims[gkNPhiEPRanges+1] = {-1.5708, -1.4137, -1.2566, -1.0996, -0.94248, -0.78540, -0.62832, -0.47124, -0.31416, -0.15708, 0.0, 
+                                             0.15708, 0.31416, 0.47124, 0.62832, 0.7854,   0.94248,  1.09956,  1.2566,   1.4137,   1.5708};*/
+// which event plane to be used
+const Int_t gkEPused = kVZERORP + 6*1 + 1;    // VZEROC 2nd harmonic event plane
+//const Int_t gkEPused = kVZERORP + 6*0 + 1;    // VZEROA 2nd harmonic event plane
+//const Int_t gkEPused = kTPCRP + 1;    // TPC harmonic event plane
+
+// define detector cuts
+const Int_t gkNDetCuts = 6;
+const Char_t* gkLegDetCutNames[gkNDetCuts] = {
+  "TPC", 
+  "TPC_TRD4_1_0.7", "TPC_TRD4_1_0.8", "TPC_TRD4_1_0.9", 
+  "TPC_TOF", "TPC_TRD4_1_0.9_TOF"
+};
+
+//_________________________________________________________________________________________________
+void RunDstPbPbJpsiAnalysis(const Char_t* output, const Char_t* inputfilename, 
+                           Int_t howMany/* = 5000*/, Int_t offset/* = 0*/) {
+  //
+  // J/psi analysis in Pb-Pb
+  //
+  cout << "start ..." << endl;
+  TTimeStamp start;
+  cout << "creating chain ..." << endl;
+  // create the input chains -----------------------------------------
+  Long64_t entries=0;
+  TChain* friendChain=0x0;
+  if(gkEPfile[0]!='\0')
+    friendChain = new TChain("DstFriendTree");
+  TChain* chain = GetChain(inputfilename, howMany, offset, entries, friendChain, gkEPfile);
+  if(!chain) return;
+  if(gkEPfile[0]!='\0' && !friendChain) return;
+  AliCorrelationReducedEvent* event = new AliCorrelationReducedEvent();
+  chain->SetBranchAddress("Event",&event);
+  AliCorrelationReducedEventFriend* eventF = 0x0;
+  if(gkEPfile[0]!='\0') {
+    eventF = new AliCorrelationReducedEventFriend();
+    friendChain->SetBranchAddress("Event",&eventF);
+  }
+  
+  cout << "initialize event mixing lists ..." << endl;
+      
+  // define histograms -----------------------------------------------
+  TString histClasses = "";
+  histClasses += "Event_BeforeCuts;Event_AfterCuts;VZERORP;TPCRP;";
+  histClasses += "OfflineTriggers;";
+  histClasses += "TrackingFlags_Before;TrackQA_JpsiLegs_BeforeCuts_ITS_TPC_TRD_TOF;";
+  for(Int_t iLegCut=0; iLegCut<gkNDetCuts; ++iLegCut) {
+    histClasses += Form("TrackQA_JpsiLegs_%s_AfterCuts_ITS_TPC_TRD_TOF;TrackingFlags_%s_AfterCuts;",
+                        gkLegDetCutNames[iLegCut], gkLegDetCutNames[iLegCut]);
+    for(Int_t iVtx=0; iVtx<gkNVtxRanges; ++iVtx)
+      histClasses += Form("PairQA_SE_%s_vtx%.1f_%.1f;", gkLegDetCutNames[iLegCut], gkEMVtxLims[iVtx], gkEMVtxLims[iVtx+1]);
+  }
+  
+  // initialize event lists for mixing
+  //const Int_t kNVarMixingRanges = (gkEventMixingType==0 ? 1 : (gkEventMixingType==1 ? gkNVtxRanges : gkNPhiEPRanges));
+  gEMCategories = gkNDetCuts*gkNCentRanges*gkNPhiEPRanges*gkNVtxRanges;
+  TList* list1[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges];  // event master lists
+  TList* list2[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges];  // event master lists
+  TList* selectedPosLegs[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges][gkEventMixingPoolDepth];
+  TList* selectedNegLegs[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges][gkEventMixingPoolDepth];
+  Int_t mixingPoolSize[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges] = {{{{0}}}};
+  UShort_t tracksUsedForMixing[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges][100] = {{{{{0}}}}};
+  UShort_t nTracksUsedForMixing[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges] = {{{{0}}}};
+  Bool_t eventHasCandidates[gkNDetCuts][gkNCentRanges][gkNVtxRanges][gkNPhiEPRanges] = {{{{kFALSE}}}};
+  Bool_t fullListFound = kFALSE;
+  for(Int_t iDetCut=0; iDetCut<gkNDetCuts; ++iDetCut) {
+    for(Int_t iVtx=0; iVtx<gkNVtxRanges; ++iVtx) 
+      histClasses += Form("PairQA_ME_%s_vtx%.1f_%.1f;", gkLegDetCutNames[iDetCut], gkEMVtxLims[iVtx], gkEMVtxLims[iVtx+1]);
+  }
+  for(Int_t iDetCut=0; iDetCut<gkNDetCuts; ++iDetCut) {
+    for(Int_t iCent=0; iCent<gkNCentRanges; ++iCent) {
+      for(Int_t iVtx=0; iVtx<gkNVtxRanges; ++iVtx) {
+       for(Int_t iPhi=0; iPhi<gkNPhiEPRanges; ++iPhi) {
+          list1[iDetCut][iCent][iVtx][iPhi] = new TList();
+          list2[iDetCut][iCent][iVtx][iPhi] = new TList();
+          for(Int_t i=0; i<gkEventMixingPoolDepth; ++i) {
+            selectedPosLegs[iDetCut][iCent][iVtx][iPhi][i] = new TList();
+            selectedPosLegs[iDetCut][iCent][iVtx][iPhi][i]->SetOwner();
+            selectedNegLegs[iDetCut][iCent][iVtx][iPhi][i] = new TList();
+            selectedNegLegs[iDetCut][iCent][iVtx][iPhi][i]->SetOwner();
+          }
+       }  // end loop over phi bins
+      }  // end loop over vtx bins
+    }  // end loop over centrality bins
+  }  // end loop over leg cuts
+  DefineHistograms(histClasses.Data(), output);  
+  
+  Float_t values[kNVars];
+  Int_t trackIdMap[20000] = {-1};
+  TClonesArray* trackList=0x0;
+  TClonesArray* pairList=0x0;
+  Bool_t legsQuality[2][gkNDetCuts] = {{kFALSE}};
+  Bool_t allLegCutsOr[2] = {kFALSE};
+  Bool_t pairQuality[gkNDetCuts] = {kFALSE};
+  
+  Float_t oldVertex = -999.; Float_t oldBC=-999.; Float_t oldCentVZERO=-999.; Float_t oldCentSPD=-999.; Float_t oldCentTPC=-999.;  
+  Double_t mixingTime = 0.0;
+  TTimeStamp startEventLoop;
+  
+  for(Int_t ie=0; ie<entries; ++ie) {  
+    chain->GetEntry(ie);
+    friendChain->GetEntry(ie);    
+    
+    gCurrentEvent = event;
+    gCurrentEventFriend = eventF;
+    if(ie%100==0) cout << "event " << ie << endl;    
+    
+    FillEventInfo(event, values, eventF);
+    FillHistClass("Event_BeforeCuts", values);
+    // event cuts
+    if(!IsEventSelected(event)) continue;
+    // check wheter this event is the same as the previous
+    if(TMath::Abs(event->Vertex(2)-oldVertex)<0.0001 && TMath::Abs(event->CentralityVZERO()-oldCentVZERO)<0.001) {
+      cout << "This event is the a copy of the previous event" << endl;
+      cout << "OLD/NEW:  vtxZ " << oldVertex << "/" << event->Vertex(2)
+           << "  BC " << oldBC << "/" << event->BC()
+          << "  CentVZERO " << oldCentVZERO << "/" << event->CentralityVZERO()
+          << "  CentSPD " << oldCentSPD << "/" << event->CentralitySPD()
+          << "  CentTPC " << oldCentTPC << "/" << event->CentralityTPC() << endl;
+      ++ie;
+      continue;
+    }
+    else {
+      oldVertex = event->Vertex(2); oldBC = event->BC();
+      oldCentVZERO = event->CentralityVZERO(); oldCentSPD = event->CentralitySPD();
+      oldCentTPC = event->CentralityTPC();
+    }
+  
+    for(UShort_t ibit=0; ibit<64; ++ibit) {
+      FillEventOfflineTriggers(ibit, values);
+      FillHistClass("OfflineTriggers", values);
+    }
+
+    // get the event vtx and centrality bins
+    Float_t centVZERO = values[kCentVZERO];
+    Float_t vtxZ = values[kVtxZ];
+    Int_t binCent = -1;
+    for(Int_t i=0; i<gkNCentRanges; ++i) {
+      if(centVZERO>=gkEMCentLims[i] && centVZERO<gkEMCentLims[i+1]) {
+       binCent = i; break;
+      }
+    }
+    Int_t binVtxZ = -1;
+    for(Int_t i=0; i<gkNVtxRanges; ++i) {
+      if(vtxZ>=gkEMVtxLims[i] && vtxZ<gkEMVtxLims[i+1]) {
+       binVtxZ = i; break;
+      }
+    }
+    if(binCent==-1) {
+      cout << "Warning: Centrality bin for this event is -1!! Something went wrong, check it out!" << endl;
+      cout << "centVZERO = " << centVZERO << endl;
+      continue;
+    }
+    if(binVtxZ==-1) {
+      cout << "Warning: Vertex bin for this event is -1!! Something went wrong, check it out!" << endl;
+      cout << "vtxZ = " << vtxZ << endl;
+      continue;
+    }
+    
+    Float_t phiEP = values[gkEPused];
+    Int_t binPhiEP = -1;                                                                                                            
+    for(Int_t i=0; i<gkNPhiEPRanges; ++i) {                                                                                         
+      if(values[gkEPused]>=gkEMPhiEPLims[i] &&                                                                  
+       values[gkEPused]<gkEMPhiEPLims[i+1]) {                                                                 
+         binPhiEP = i; break;                                                                                                        
+      }                                                                                                                                
+    }                                                                                                                                  
+    if(binPhiEP==-1) {                                                                                                              
+      cout << "Warning: EP Phi bin for this event is -1!! Something went wrong, check it out!" << endl;                             
+      cout << "phi = " << values[gkEPused] << endl;                                                          
+      continue;                                                                                                                        
+    }                                                                                                                                  
+
+    // Do the mixing if the events in the pool reached the maximum number of events
+    if(fullListFound) {
+      TTimeStamp startMix;
+      for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+        for(Int_t iCent=0; iCent<gkNCentRanges; ++iCent) {
+         for(Int_t iVtx=0; iVtx<gkNVtxRanges; ++iVtx) {
+           for(Int_t iPhi=0; iPhi<gkNPhiEPRanges; ++iPhi) {
+              if(mixingPoolSize[iCut][iCent][iVtx][iPhi]>=gkEventMixingPoolDepth) {
+                values[kCentVZERO] = 0.5*(gkEMCentLims[iCent]+gkEMCentLims[iCent+1]);
+                values[kVtxZ] = 0.5*(gkEMVtxLims[iVtx]+gkEMVtxLims[iVtx+1]);
+               values[gkEPused] = 0.5*(gkEMPhiEPLims[iPhi]+gkEMPhiEPLims[iPhi+1]);
+                DoEventMixing(list1[iCut][iCent][iVtx][iPhi], list2[iCut][iCent][iVtx][iPhi], values, 
+                             AliCorrelationReducedPair::kJpsiToEE, 
+                             Form("PairQA_ME_%s_vtx%.1f_%.1f", gkLegDetCutNames[iCut], gkEMVtxLims[iVtx], gkEMVtxLims[iVtx+1]));
+                mixingPoolSize[iCut][iCent][iVtx][iPhi] = 0;   // reset the mixing events number
+              }
+           }  // end loop over phi ranges
+         }   // end loop over vertex ranges
+        }   // end loop over centralities ranges
+        TTimeStamp stopMix;
+       mixingTime += Double_t(stopMix.GetSec())+Double_t(stopMix.GetNanoSec())/1.0e+9 - 
+                    (Double_t(startMix.GetSec())+Double_t(startMix.GetNanoSec())/1.0e+9);
+      }   // end loop over detector cuts 
+      fullListFound = kFALSE;
+    }  // end if (fullListFound)
+    // reset the correct centrality, vtx and phi for this event
+    values[kCentVZERO] = centVZERO;
+    values[kVtxZ] = vtxZ;
+    values[gkEPused] = phiEP;
+    
+    // make an index map for track access optimization
+    AliCorrelationReducedTrack* track = 0x0;
+    trackList = event->GetTracks();
+    TIter nextTrack(trackList);
+    for(Int_t i=0; i<20000; ++i) trackIdMap[i] = -1;
+    for(Int_t it=0; it<event->NTracks(); ++it) {
+      track = (AliCorrelationReducedTrack*)nextTrack();
+      if(track)
+        trackIdMap[track->TrackId()] = it;
+    }
+    
+    pairList = event->GetPairs();
+    TIter nextPair(pairList);
+    AliCorrelationReducedPair* pair = 0x0;
+    AliCorrelationReducedTrack* leg1 = 0x0;
+    AliCorrelationReducedTrack* leg2 = 0x0;
+    values[kNpairsSelected] = 0.0;
+    
+    // reset arrays
+    for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+      for(Int_t iCent=0; iCent<gkNCentRanges; ++iCent) {
+       for(Int_t iVtx=0; iVtx<gkNVtxRanges; ++iVtx) {
+         for(Int_t iPhi=0; iPhi<gkNPhiEPRanges; ++iPhi) {
+           nTracksUsedForMixing[iCut][iCent][iVtx][iPhi] = 0;
+           eventHasCandidates[iCut][iCent][iVtx][iPhi] = kFALSE;
+         }  // end loop over phi bins
+       }  // end loop over vtx bins
+      }  // end loop over centrality bins
+    }  // end loop over detector cuts
+        
+    // loop over pairs
+    for(Int_t ip=0; ip<event->NDielectrons(); ++ip) {
+      pair = event->GetDielectronPair(ip);
+      // pair cuts
+      if(!IsPairSelected(pair)) continue;
+      
+      // reset flag arrays
+      for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+       legsQuality[0][iCut] = kFALSE; legsQuality[1][iCut] = kFALSE;
+       pairQuality[iCut] = kFALSE;
+      }
+      allLegCutsOr[0] = kFALSE; allLegCutsOr[1] = kFALSE;
+      // apply cuts on the first leg
+      if(trackIdMap[pair->LegId(0)]!=-1) {
+        leg1 = event->GetTrack(trackIdMap[pair->LegId(0)]);
+       FillTrackInfo(leg1, values);
+       for(UShort_t iflag=0; iflag<kNTrackingFlags; ++iflag) {
+         FillTrackingFlag(leg1, iflag, values);
+         FillHistClass("TrackingFlags_Before", values);
+       }
+       FillHistClass("TrackQA_JpsiLegs_BeforeCuts_ITS_TPC_TRD_TOF", values);
+       allLegCutsOr[0] = IsLegSelected(leg1, legsQuality[0]);
+      }   // end if
+      
+      // apply cuts on the second leg
+      if(trackIdMap[pair->LegId(1)]!=-1) {
+        leg2 = event->GetTrack(trackIdMap[pair->LegId(1)]);
+       FillTrackInfo(leg2, values);
+       for(UShort_t iflag=0; iflag<kNTrackingFlags; ++iflag) {
+         FillTrackingFlag(leg2, iflag, values);
+         FillHistClass("TrackingFlags_Before", values);
+       }
+       FillHistClass("TrackQA_JpsiLegs_BeforeCuts_ITS_TPC_TRD_TOF", values);
+       allLegCutsOr[1] = IsLegSelected(leg2, legsQuality[1]);
+      }   // end if
+      if(!allLegCutsOr[0] || !allLegCutsOr[1]) continue;
+      Int_t nCutsPassed = 0;
+      for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+       pairQuality[iCut] = legsQuality[0][iCut] && legsQuality[1][iCut];
+       if(pairQuality[iCut]) ++nCutsPassed;
+      }
+      if(nCutsPassed==0) continue;
+    
+      FillPairInfo(pair, values);
+                        
+      // fill track leg histograms
+      FillTrackInfo(leg1, values);
+      for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+       if(pairQuality[iCut]) {
+         if(!IsTrackUsedForMixing(tracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  leg1->TrackId())) {
+            FillHistClass(Form("TrackQA_JpsiLegs_%s_AfterCuts_ITS_TPC_TRD_TOF", gkLegDetCutNames[iCut]), values);
+            for(UShort_t iflag=0; iflag<kNTrackingFlags; ++iflag) {
+             FillTrackingFlag(leg1, iflag, values);
+             FillHistClass(Form("TrackingFlags_%s_AfterCuts", gkLegDetCutNames[iCut]), values);
+            }
+         }
+       }
+      }
+      FillTrackInfo(leg2, values);
+      for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+        if(pairQuality[iCut]) {
+         if(!IsTrackUsedForMixing(tracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  leg2->TrackId())) {
+            FillHistClass(Form("TrackQA_JpsiLegs_%s_AfterCuts_ITS_TPC_TRD_TOF", gkLegDetCutNames[iCut]), values);
+            for(UShort_t iflag=0; iflag<kNTrackingFlags; ++iflag) {
+             FillTrackingFlag(leg2, iflag, values);
+             FillHistClass(Form("TrackingFlags_%s_AfterCuts", gkLegDetCutNames[iCut]), values);
+            }
+         }
+       }
+      }
+      
+      // fill single-event pair histograms
+      for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+       if(pairQuality[iCut]) {
+         if(IsPairSelectedEM(values))
+            FillHistClass(Form("PairQA_SE_%s_vtx%.1f_%.1f", gkLegDetCutNames[iCut], gkEMVtxLims[binVtxZ], gkEMVtxLims[binVtxZ+1]), values);
+       }
+      }
+      
+      values[kNpairsSelected] += 1.0;
+      
+      // add legs to the mixing lists
+      for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+       if(pairQuality[iCut]) {
+         if(!IsTrackUsedForMixing(tracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  leg1->TrackId())) {
+           if(leg1->Charge()>0) selectedPosLegs[iCut][binCent][binVtxZ][binPhiEP][mixingPoolSize[iCut][binCent][binVtxZ][binPhiEP]]->Add(leg1->Clone());
+            else selectedNegLegs[iCut][binCent][binVtxZ][binPhiEP][mixingPoolSize[iCut][binCent][binVtxZ][binPhiEP]]->Add(leg1->Clone());
+           tracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP][nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP]] = leg1->TrackId();
+           nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP] += 1;
+         }
+         if(!IsTrackUsedForMixing(tracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP], 
+                                  leg2->TrackId())) {
+           if(leg2->Charge()>0) selectedPosLegs[iCut][binCent][binVtxZ][binPhiEP][mixingPoolSize[iCut][binCent][binVtxZ][binPhiEP]]->Add(leg2->Clone());
+            else selectedNegLegs[iCut][binCent][binVtxZ][binPhiEP][mixingPoolSize[iCut][binCent][binVtxZ][binPhiEP]]->Add(leg2->Clone());
+           tracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP][nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP]] = leg2->TrackId();
+           nTracksUsedForMixing[iCut][binCent][binVtxZ][binPhiEP] += 1;
+         }
+         eventHasCandidates[iCut][binCent][binVtxZ][binPhiEP] = kTRUE;
+       }  // end if(pairQuality)
+      }
+    }  // end loop over pairs
+    
+    // If this event has candidates, then store the event in the list for event mixing
+    for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+      for(Int_t iCent=0; iCent<gkNCentRanges; ++iCent) {
+       for(Int_t iVtx=0; iVtx<gkNVtxRanges; ++iVtx) {
+         for(Int_t iPhi=0; iPhi<gkNPhiEPRanges; ++iPhi) {
+            if(!eventHasCandidates[iCut][iCent][iVtx][iPhi]) continue;
+           list1[iCut][iCent][iVtx][iPhi]->Add(selectedPosLegs[iCut][iCent][iVtx][iPhi][mixingPoolSize[iCut][iCent][iVtx][iPhi]]);
+            list2[iCut][iCent][iVtx][iPhi]->Add(selectedNegLegs[iCut][iCent][iVtx][iPhi][mixingPoolSize[iCut][iCent][iVtx][iPhi]]);
+            /*
+           cout << "event mixing category (cut/cent/vtx) " << iCut << "/" << iCent << "/" << iVtx << ", pool size (pos/neg): " 
+                 << list1[iCut][iCent][iVtx]->GetEntries() 
+                 << "/" << list2[iCut][iCent][iVtx]->GetEntries() << "; ntracks this entry (pos/neg): " 
+                 << selectedPosLegs[iCut][iCent][iVtx][mixingPoolSize[iCut][iCent][iVtx]]->GetEntries() << "/" 
+                 << selectedNegLegs[iCut][iCent][iVtx][mixingPoolSize[iCut][iCent][iVtx]]->GetEntries() << endl;
+           */
+            mixingPoolSize[iCut][iCent][iVtx][iPhi] += 1;
+           if(mixingPoolSize[iCut][iCent][iVtx][iPhi]==gkEventMixingPoolDepth)
+             fullListFound = kTRUE;
+         }  // end loop over phi ranges
+       }  // end loop over vertex ranges
+      }  // end loop over centrality ranges
+    }  // end loop over detector cuts
+    
+    FillHistClass("Event_AfterCuts", values);
+    FillHistClass("TPCRP", values);
+    FillHistClass("VZERORP", values);
+  }  // end loop over events
+  
+  // Mixing the leftover events
+  cout << "Leftover mixing ..." << endl;
+  TTimeStamp startMix;
+  for(Int_t iCut=0; iCut<gkNDetCuts; ++iCut) {
+    for(Int_t iCent=0; iCent<gkNCentRanges; ++iCent) {
+      for(Int_t iVtx=0; iVtx<gkNVtxRanges; ++iVtx) {
+       for(Int_t iPhi=0; iPhi<gkNPhiEPRanges; ++iPhi) {
+          values[kCentVZERO] = 0.5*(gkEMCentLims[iCent]+gkEMCentLims[iCent+1]);
+         values[kVtxZ] = 0.5*(gkEMVtxLims[iVtx]+gkEMVtxLims[iVtx+1]);
+         values[gkEPused] = 0.5*(gkEMPhiEPLims[iPhi]+gkEMPhiEPLims[iPhi+1]);
+          DoEventMixing(list1[iCut][iCent][iVtx][iPhi], list2[iCut][iCent][iVtx][iPhi], values, 
+                       AliCorrelationReducedPair::kJpsiToEE, 
+                       Form("PairQA_ME_%s_vtx%.1f_%.1f", gkLegDetCutNames[iCut], gkEMVtxLims[iVtx], gkEMVtxLims[iVtx+1])); // after the event mixing the lists will be cleared
+          mixingPoolSize[iCut][iCent][iVtx][iPhi] = 0;   // reset the mixing events number
+       }  // end loop over phi ranges
+      }   // end loop over vertex ranges
+    }   // end loop over centralities ranges
+  }   // end loop over detector cuts 
+  TTimeStamp stopMix;
+  mixingTime += Double_t(stopMix.GetSec())+Double_t(stopMix.GetNanoSec())/1.0e+9 - 
+              (Double_t(startMix.GetSec())+Double_t(startMix.GetNanoSec())/1.0e+9);
+  
+  TTimeStamp stopEventLoop;
+  
+  WriteOutput(gSaveFile);
+  
+  cout << "Initialization time: " << startEventLoop.GetSec() - start.GetSec() << " seconds" << endl;
+  cout << "Total looping time: " << stopEventLoop.GetSec() - startEventLoop.GetSec() << " seconds" << endl;
+  cout << "Time spent in mixing: " << mixingTime << " seconds" << endl;
+  cout << "Overall speed       : " << Double_t(stopEventLoop.GetSec() - startEventLoop.GetSec())/Double_t(entries) << " sec./event" << endl;
+}
+
+
+//__________________________________________________________________
+Bool_t IsTrackUsedForMixing(UShort_t* idxArray, UShort_t size, UShort_t idx) {
+  //
+  // check whether track with idx was already added to the mixing list
+  //
+  for(Int_t i=0; i<size; ++i) {
+    if(idxArray[i]==idx) return kTRUE;
+  }
+  return kFALSE;
+}
+
+
+//__________________________________________________________________
+Bool_t IsEventSelected(AliCorrelationReducedEvent* event) {
+  //
+  // event selection
+  //
+  if(!event->IsPhysicsSelection()) return kFALSE;
+  if(event->VertexNContributors()<1) return kFALSE;
+  if(event->CentralityQuality()!=0) return kFALSE;
+  if(event->CentralityVZERO()<-0.0001) return kFALSE;
+  if(event->CentralityVZERO()>80.0) return kFALSE;
+  if(TMath::Abs(event->Vertex(2))>10.0) return kFALSE;
+  return kTRUE;
+}
+
+
+//__________________________________________________________________
+Bool_t IsLegSelected(AliCorrelationReducedTrack* track, Bool_t* legQuality) {
+  //
+  //  track leg selection
+  //  
+  legQuality[0] = IsLegSelected(track);
+  legQuality[1] = legQuality[0] && IsLegSelectedTRD(track, 1, 4, 0.7);
+  legQuality[2] = legQuality[0] && IsLegSelectedTRD(track, 1, 4, 0.80);
+  legQuality[3] = legQuality[0] && IsLegSelectedTRD(track, 1, 4, 0.90);
+  legQuality[4] = legQuality[0] && IsLegSelectedTOF(track, 2);
+  legQuality[5] = legQuality[3] && legQuality[4];
+  Bool_t globalOr = kFALSE;
+  for(Int_t i=0; i<gkNDetCuts; ++i) globalOr = globalOr || legQuality[i];
+  return globalOr;
+}
+
+
+//__________________________________________________________________
+Bool_t IsLegSelected(AliCorrelationReducedTrack* track) {
+  //
+  // track leg selection
+  //
+  if(!track->CheckTrackStatus(kTPCrefit)) return kFALSE;
+  if(!track->CheckTrackStatus(kITSrefit)) return kFALSE;
+  if(!(track->ITSLayerHit(0) || track->ITSLayerHit(1))) return kFALSE;
+  
+  if(track->Pt()<0.7) return kFALSE;
+  if(TMath::Abs(track->Eta())>0.9) return kFALSE;
+  
+  if(track->TPCncls()<70) return kFALSE;
+  
+  if(track->TPCnSig(kElectron)>3.0) return kFALSE;
+  if(track->TPCnSig(kElectron)<-2.0) return kFALSE;
+  
+  if(TMath::Abs(track->DCAz())>3.0) return kFALSE;
+  if(TMath::Abs(track->DCAxy())>1.0) return kFALSE;
+  
+  //if(track->Pin()<2.5) {
+  if(TMath::Abs(track->TPCnSig(kProton))<3.5) return kFALSE;
+  if(TMath::Abs(track->TPCnSig(kPion))<3.5) return kFALSE;
+  if(track->TPCnSig(kProton)<-3.5) return kFALSE;
+  //if(track->TPCnSig(kProton)<-3.5) return kFALSE;
+  //}
+  
+  return kTRUE;
+}
+
+
+//__________________________________________________________________
+Bool_t IsLegSelectedTRD(AliCorrelationReducedTrack* track, 
+                       Int_t trdCut/*=-1*/, Int_t trdMinNtr/*=4*/, Float_t eleCut/*=0.7*/) {
+  //
+  // TRD leg selection
+  //
+  if(trdCut==1 && track->TRDntracklets(0)>=trdMinNtr) { 
+    if(track->TRDpid(0)<eleCut) return kFALSE;
+  }
+  if(trdCut==2 && track->TRDntracklets(0)>=trdMinNtr && track->Pin()>1.0) {
+    if(track->TRDpid(0)<eleCut) return kFALSE;
+  }
+  if(trdCut==3 && track->CheckTrackStatus(kTRDpid) && track->TRDntracklets(0)>=trdMinNtr) { 
+    if(track->TRDpid(0)<eleCut) return kFALSE;
+  }
+  if(trdCut==4 && track->CheckTrackStatus(kTRDpid) && track->TRDntracklets(1)>=trdMinNtr && track->Pin()>1.0) {
+    if(track->TRDpid(0)<eleCut) return kFALSE;
+  }
+  return kTRUE;
+}
+
+
+//__________________________________________________________________
+Bool_t IsLegSelectedTOF(AliCorrelationReducedTrack* track,
+                       Int_t tofCut/*=-1*/, Float_t lowExcl/*=0.3*/, Float_t highExcl/*=0.93*/) {
+  //
+  // TOF leg selection
+  //
+  if(tofCut==1 && track->TOFbeta()>lowExcl && track->TOFbeta()<highExcl) return kFALSE;
+  if(tofCut==2 && track->CheckTrackStatus(kTOFpid) && TMath::Abs(track->TOFnSig(kElectron))>3.5) return kFALSE;
+  return kTRUE;
+}
+
+
+//__________________________________________________________________
+Bool_t IsPairSelected(AliCorrelationReducedPair* pair) {
+  //
+  // pair selection
+  //
+  if(!pair) return kFALSE;
+  if(pair->CandidateId()!=AliCorrelationReducedPair::kJpsiToEE) return kFALSE;
+  if(pair->PairType()!=1) return kFALSE;
+  if(TMath::Abs(pair->Rapidity())>0.9) return kFALSE;
+  return kTRUE;
+}
+
+
+//__________________________________________________________________
+void DefineHistograms(const Char_t* histClasses, const Char_t* output) {
+  //
+  // define the histograms
+  //
+  cout << "Defining histograms ..." << flush;
+  cout << "histogram classes: " << histClasses << endl;
+  
+  gSaveFile=new TFile(output,"RECREATE");
+  
+  TString classesStr(histClasses);
+  TObjArray* arr=classesStr.Tokenize(";");
+  
+  const Int_t kNRunBins = 3000;
+  Double_t runHistRange[2] = {137000.,140000.};
+  
+  for(Int_t iclass=0; iclass<arr->GetEntries(); ++iclass) {
+    TString classStr = arr->At(iclass)->GetName();
+    cout << "hist class: " << classStr.Data() << endl;
+    
+    // Event wise histograms
+    if(classStr.Contains("Event")) {
+      cout << "Event" << endl;
+      AddHistClass(classStr.Data());
+      AddHistogram(classStr.Data(),"RunNo","Run numbers;Run",kFALSE, kNRunBins, runHistRange[0], runHistRange[1], kRunNo);
+      AddHistogram(classStr.Data(),"BC","Bunch crossing;BC",kFALSE,3000,0.,3000.,kBC);
+      AddHistogram(classStr.Data(),"IsPhysicsSelection","Physics selection flag;;",kFALSE,
+                  2,-0.5,1.5,kIsPhysicsSelection, 0,0.0,0.0,kNothing, 0,0.0,0.0,kNothing, "off;on");
+      
+      AddHistogram(classStr.Data(),"VtxZ","Vtx Z;vtx Z (cm)",kFALSE,300,-15.,15.,kVtxZ);
+      AddHistogram(classStr.Data(),"VtxX","Vtx X;vtx X (cm)",kFALSE,300,-0.4,0.4,kVtxX);
+      AddHistogram(classStr.Data(),"VtxY","Vtx Y;vtx Y (cm)",kFALSE,300,-0.4,0.4,kVtxY);
+      
+      AddHistogram(classStr.Data(),"VtxZ_Run_prof", "<VtxZ> vs run; Run; vtxZ (cm)", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, -20, 20., 1000., kVtxZ);
+      AddHistogram(classStr.Data(),"VtxX_Run_prof", "<VtxX> vs run; Run; vtxX (cm)", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, -20, 20., 1000., kVtxX);
+      AddHistogram(classStr.Data(),"VtxY_Run_prof", "<VtxY> vs run; Run; vtxY (cm)", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, -20, 20., 1000., kVtxY);
+      
+      AddHistogram(classStr.Data(),"CentVZERO","Centrality(VZERO);centrality VZERO (percents)",kFALSE,
+                   100, 0.0, 100.0, kCentVZERO);
+      AddHistogram(classStr.Data(),"CentQuality","Centrality quality;centrality quality",kFALSE,
+                   100, -50.5, 49.5, kCentQuality);
+      AddHistogram(classStr.Data(),"CentVZERO_Run_prof","<Centrality(VZERO)> vs run;Run; centrality VZERO (%)",kTRUE,
+                   kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, 0.0, 100.0, kCentVZERO);      
+      
+      AddHistogram(classStr.Data(),"NPairs","Number of candidates per event;# pairs",kFALSE,
+                   5000,0.,5000.,kNdielectrons);
+      AddHistogram(classStr.Data(),"NPairsSelected", "Number of selected pairs per event; #pairs", kFALSE,
+                  5000,0.,5000.,kNpairsSelected);
+      AddHistogram(classStr.Data(),"NTracksTotal","Number of total tracks per event;# tracks",kFALSE,
+                   1000,0.,30000.,kNtracksTotal);
+      AddHistogram(classStr.Data(),"NTracksSelected","Number of selected tracks per event;# tracks",kFALSE,
+                   1000,0.,30000.,kNtracksSelected);
+      AddHistogram(classStr.Data(),"SPDntracklets", "SPD #tracklets in |#eta|<1.0; tracklets", kFALSE,
+                   3000, -0.5, 2999.5, kSPDntracklets);
+      
+      AddHistogram(classStr.Data(),"Ndielectrons_Run_prof", "<Number of dielectrons> per run; Run; #tracks", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, 0., 10000., kNdielectrons);
+      AddHistogram(classStr.Data(),"NpairsSelected_Run_prof", "<Number of selected pairs> per run; Run; #tracks", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, 0., 10000., kNpairsSelected);
+      AddHistogram(classStr.Data(),"NTracksTotal_Run_prof", "<Number of tracks> per run; Run; #tracks", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, 0., 10000., kNtracksTotal);
+      AddHistogram(classStr.Data(),"NTracksSelected_Run_prof", "<Number of selected tracks> per run; Run; #tracks", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, 0., 10000., kNtracksSelected);
+      AddHistogram(classStr.Data(),"SPDntracklets_Run_prof", "<SPD ntracklets> per run; Run; #tracks", kTRUE,
+                  kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, 0., 10000., kSPDntracklets);
+      
+      AddHistogram(classStr.Data(),"VtxZ_CentVZERO","Centrality(VZERO) vs vtx. Z;vtx Z (cm); centrality VZERO (%)",kFALSE,
+                   300,-15.,15.,kVtxZ, 100, 0.0, 100.0, kCentVZERO);
+      AddHistogram(classStr.Data(),"VtxZ_CentSPD","Centrality(SPD) vs vtx. Z;vtx Z (cm); centrality SPD (%)",kFALSE,
+                   300,-15.,15.,kVtxZ, 100, 0.0, 100.0, kCentSPD);
+      AddHistogram(classStr.Data(),"VtxZ_CentTPC","Centrality(TPC) vs vtx. Z;vtx Z (cm); centrality TPC (%)",kFALSE,
+                   300,-15.,15.,kVtxZ, 100, 0.0, 100.0, kCentTPC);
+      continue;
+    }  // end if className contains "Event"
+    
+    // Offline trigger histograms
+    if(classStr.Contains("OfflineTriggers")) {
+      cout << "OfflineTriggers" << endl;
+      AddHistClass(classStr.Data());
+
+      TString triggerNames = "";
+      for(Int_t i=0; i<64; ++i) {triggerNames += gkOfflineTriggerNames[i]; triggerNames+=";";}
+      
+      AddHistogram(classStr.Data(), "Triggers", "Offline triggers fired; ; ;", kFALSE,
+                  64, -0.5, 63.5, kOfflineTrigger, 2, -0.5, 1.5, kOfflineTriggerFired, 0, 0.0, 0.0, kNothing, triggerNames.Data(), "off;on");
+      AddHistogram(classStr.Data(), "Triggers2", "Offline triggers fired; ; ;", kFALSE,
+                  64, -0.5, 63.5, kOfflineTriggerFired2, 0, 0.0, 0.0, kNothing, 0, 0.0, 0.0, kNothing, triggerNames.Data());
+      AddHistogram(classStr.Data(), "CentVZERO_Triggers2", "Offline triggers fired vs centrality VZERO; ; centrality VZERO;", kFALSE,
+                  64, -0.5, 63.5, kOfflineTriggerFired2, 20, 0.0, 100.0, kCentVZERO, 0, 0.0, 0.0, kNothing, triggerNames.Data());
+      AddHistogram(classStr.Data(), "VtxZ_Triggers2", "Offline triggers fired vs vtxZ; ; vtx Z (cm.);", kFALSE,
+                  64, -0.5, 63.5, kOfflineTriggerFired2, 200, -20.0, 20.0, kVtxZ, 0, 0.0, 0.0, kNothing, triggerNames.Data());
+      continue;
+    }
+    
+    if(classStr.Contains("VZERORP")) {
+      cout << "VZERORP" << endl;
+      AddHistClass(classStr.Data());
+      const Char_t* sname[3] = {"A","C","A&C"};
+      for(Int_t ih=1; ih<2; ++ih) {
+        for(Int_t iS=0; iS<3; ++iS) {
+          AddHistogram(classStr.Data(), Form("QvecX_side%s_h%d_CentSPDVtxZ_prof",sname[iS],ih+1), 
+                       Form("Q_{x}, side %s, harmonic %d, vs centSPD and vtxZ; Centrality (percents); VtxZ (cm); <Q_{x}>",sname[iS],ih+1), kTRUE, 
+                       20, 0.0, 100.0, kCentSPD, 24, -12.0, 12.0, kVtxZ, 500, -10000.0, 10000.0, kVZEROQvecX+iS*6+ih);
+         AddHistogram(classStr.Data(), Form("QvecY_side%s_h%d_CentSPDVtxZ_prof",sname[iS],ih+1), 
+                       Form("Q_{y}, side %s, harmonic %d, vs centSPD and vtxZ; Centrality (percents); VtxZ (cm); <Q_{y}>",sname[iS],ih+1), kTRUE, 
+                       20, 0.0, 100.0, kCentSPD, 24, -12.0, 12.0, kVtxZ, 500, -10000.0, 10000.0, kVZEROQvecY+iS*6+ih);
+         AddHistogram(classStr.Data(), Form("QvecX_side%s_h%d_Run_prof", sname[iS], ih+1), 
+                      Form("<Q_{x}>, VZERO side %s, harmonic %d, vs run; Run; <Q_{x}>", sname[iS], ih+1), kTRUE,
+                      kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, -100., 100., kVZEROQvecX+iS*6+ih);
+         AddHistogram(classStr.Data(), Form("QvecY_side%s_h%d_Run_prof", sname[iS], ih+1), 
+                      Form("<Q_{y}>, VZERO side %s, harmonic %d, vs run; Run; <Q_{y}>", sname[iS], ih+1), kTRUE,
+                      kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, -100., 100., kVZEROQvecY+iS*6+ih);
+         AddHistogram(classStr.Data(), Form("RP_side%s_h%d_CentSPD",sname[iS],ih+1), 
+                       Form("VZERO reaction plane, side %s, harmonic %d, vs centrality SPD; #Psi (rad.); centSPD (percents)",sname[iS],ih+1), kFALSE, 
+                       400, -4.0/Double_t(ih+1), 4.0/Double_t(ih+1), kVZERORP+iS*6+ih, 20, 0.0, 100.0, kCentSPD);
+         AddHistogram(classStr.Data(), Form("RP_side%s_h%d_VtxZ",sname[iS],ih+1), 
+                       Form("VZERO reaction plane, side %s, harmonic %d, vs vtxZ; #Psi (rad.); vtxZ (cm)",sname[iS],ih+1), kFALSE, 
+                       400, -4.0/Double_t(ih+1), 4.0/Double_t(ih+1), kVZERORP+iS*6+ih, 24, -12.0, +12.0, kVtxZ);          
+        }   // end loop over VZERO sides
+      }   // end loop over harmonics    
+      continue;
+    }   // end if for the VZERO reaction plane histograms
+    
+    if(classStr.Contains("TPCRP")) {
+      cout << "TPCRP" << endl;
+      AddHistClass(classStr.Data());
+      for(Int_t ih=1; ih<2; ++ih) {
+       AddHistogram(classStr.Data(), Form("QvecX_TPC_h%d_Run_prof", ih+1), 
+                    Form("<Q_{x}>, TPC, harmonic %d, vs run; Run; <Q_{x}>", ih+1), kTRUE,
+                    kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, -100., 100., kTPCQvecX+ih);
+       AddHistogram(classStr.Data(), Form("QvecY_TPC_h%d_Run_prof", ih+1), 
+                    Form("<Q_{y}>, TPC, harmonic %d, vs run; Run; <Q_{y}>", ih+1), kTRUE,
+                    kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 100, -100., 100., kTPCQvecY+ih);
+       AddHistogram(classStr.Data(), Form("TPCRP_h%d", ih+1), 
+                     Form("TPC event plane, harmonic %d; #Psi (rad.)", ih+1), kFALSE, 
+                     400, -4.0/Double_t(ih+1), 4.0/Double_t(ih+1), kTPCRP+ih);
+       AddHistogram(classStr.Data(), Form("TPCQvecX_h%d_CentSPDVtxZ_prof", ih+1), 
+                     Form("TPC Q_{x}, harmonic %d, vs centSPD and vtxZ; Centrality (percents); VtxZ (cm); <Q_{x}>", ih+1), kTRUE, 
+                     20, 0.0, 100.0, kCentSPD, 24, -12.0, 12.0, kVtxZ, 500, -600.0, 600.0, kTPCQvecX+ih);
+       AddHistogram(classStr.Data(), Form("TPCQvecY_h%d_CentSPDVtxZ_prof", ih+1), 
+                     Form("TPC Q_{y}, harmonic %d, vs centSPD and vtxZ; Centrality (percents); VtxZ (cm); <Q_{y}>", ih+1), kTRUE, 
+                     20, 0.0, 100.0, kCentSPD, 24, -12.0, 12.0, kVtxZ, 500, -600.0, 600.0, kTPCQvecY+ih);
+      }    // end loop over harmonics        
+      continue;
+    }    // end if for the TPC reaction plane histograms
+    
+    TString trkFlagNames = "";
+    for(Int_t iflag=0; iflag<kNTrackingFlags; ++iflag) {
+      trkFlagNames += gkTrackingFlagNames[iflag];
+      trkFlagNames += ";";
+    }
+    
+    // Track histograms
+    if(classStr.Contains("TrackingFlags")) {
+      AddHistClass(classStr.Data());
+      
+      AddHistogram(classStr.Data(), "TrackingFlags", "Tracking flags;;", kFALSE,
+                  kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, 0, 0.0, 0.0, kNothing, trkFlagNames.Data());
+      AddHistogram(classStr.Data(), "TrackingFlags_Pt", "Tracking flags vs p_{T};p_{T} (GeV/c);", kFALSE,
+                  100, 0.0, 20.0, kPt, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());
+      AddHistogram(classStr.Data(), "TrackingFlags_Eta", "Tracking flags vs #eta;#eta;", kFALSE,
+                  30, -1.5, 1.5, kEta, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());
+      AddHistogram(classStr.Data(), "TrackingFlags_Phi", "Tracking flags vs #varphi;#varphi (rad.);", kFALSE,
+                  60, 0.0, 6.3, kPhi, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());
+      AddHistogram(classStr.Data(), "TrackingFlags_CentVZERO", "Tracking flags vs centrality VZERO; centrality (%);", kFALSE,
+                  20, 0.0, 100.0, kCentVZERO, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());
+      
+      AddHistogram(classStr.Data(), "TrackingFlags_TRDntracklets", "Tracking flags vs TRD #tracklets; TRD #tracklets;", kFALSE,
+                  7, -0.5, 6.5, kTRDntracklets, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());      
+      AddHistogram(classStr.Data(), "TrackingFlags_TRDntrackletsPID", "Tracking flags vs TRD # pid tracklets; TRD #tracklets;", kFALSE,
+                  7, -0.5, 6.5, kTRDntrackletsPID, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());      
+      AddHistogram(classStr.Data(), "TrackingFlags_TRDeleProbab", "Tracking flags vs TRD electron probability; TRD probab.;", kFALSE,
+                  50, 0.0, 1.0, kTRDpidProbabilities, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());
+      AddHistogram(classStr.Data(), "TrackingFlags_TOFbeta", "Tracking flags vs TOF #beta; TOF #beta;", kFALSE,
+                  50, 0.0, 1.0, kTOFbeta, kNTrackingFlags, -0.5, kNTrackingFlags-0.5, kTrackingFlag, 0, 0.0, 0.0, kNothing, "", trkFlagNames.Data());
+    }
+    
+    if(classStr.Contains("TrackQA")) {
+      AddHistClass(classStr.Data());
+    
+      AddHistogram(classStr.Data(), "Pt", "p_{T} distribution; p_{T} (GeV/c^{2});", kFALSE,
+                   1000, 0.0, 50.0, kPt);
+      AddHistogram(classStr.Data(), "Eta", "#eta illumination; #eta;", kFALSE,
+                   1000, -1.5, 1.5, kEta);
+      AddHistogram(classStr.Data(), "Phi", "#varphi illumination; #varphi;", kFALSE,
+                   1000, 0.0, 6.3, kPhi);
+      AddHistogram(classStr.Data(), "DCAxy", "DCAxy; DCAxy (cm.)", kFALSE,
+                   1000, -10.0, 10.0, kDcaXY);
+      AddHistogram(classStr.Data(), "DCAz", "DCAz; DCAz (cm.)", kFALSE,
+                   1000, -10.0, 10.0, kDcaZ);
+
+      // run dependence
+      AddHistogram(classStr.Data(), "Pt_Run", "<p_{T}> vs run; run;", kTRUE,
+                   kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 1000, 0.0, 50.0, kPt);
+      AddHistogram(classStr.Data(), "Eta_Run", "<#eta> vs run; run;", kTRUE,
+                   kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 1000, -1.5, 1.5, kEta);      
+      AddHistogram(classStr.Data(), "Phi_Run", "<#varphi> vs run; run;", kTRUE,
+                   kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 1000, 0.0, 6.3, kPhi);      
+      AddHistogram(classStr.Data(), "DCAxy_Run", "<DCAxy> vs run; run;", kTRUE,
+                   kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 1000, -10.0, 10.0, kDcaXY);
+      AddHistogram(classStr.Data(), "DCAz_Run", "<DCAz> vs run; run;", kTRUE,
+                   kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 1000, -10.0, 10.0, kDcaZ);
+
+      // correlations between parameters
+      AddHistogram(classStr.Data(), "Eta_Pt_prof", "<p_{T}> vs #eta; #eta; p_{T} (GeV/c);", kTRUE,
+                   300, -1.5, +1.5, kEta, 100, 0.0, 10.0, kPt);
+      AddHistogram(classStr.Data(), "Phi_Pt_prof", "<p_{T}> vs #varphi; #varphi (rad.); p_{T} (GeV/c)", kTRUE,
+                   300, 0.0, 6.3, kPhi, 100, 0.0, 10.0, kPt);
+      AddHistogram(classStr.Data(), "Eta_Phi", "#varphi vs #eta; #eta; #varphi (rad.);", kFALSE,
+                   200, -1.0, +1.0, kEta, 100, 0.0, 6.3, kPhi);
+      AddHistogram(classStr.Data(), "Pt_DCAxy", "DCAxy vs p_{T}; p_{T} (GeV/c); DCA_{xy} (cm)", kFALSE,
+                   100, 0.0, 10.0, kPt, 500, -2.0, 2.0, kDcaXY);
+      AddHistogram(classStr.Data(), "Pt_DCAz", "DCAz vs p_{T}; p_{T} (GeV/c); DCA_{z} (cm)", kFALSE,
+                   100, 0.0, 10.0, kPt, 500, -2.0, 2.0, kDcaZ);
+      AddHistogram(classStr.Data(), "Eta_DCAxy", "DCAxy vs #eta; #eta; DCA_{xy} (cm)", kFALSE,
+                   100, -1.0, 1.0, kEta, 500, -2.0, 2.0, kDcaXY);
+      AddHistogram(classStr.Data(), "Eta_DCAz", "DCAz vs #eta; #eta; DCA_{z} (cm)", kFALSE,
+                   100, -1.0, 1.0, kEta, 500, -2.0, 2.0, kDcaZ);
+      
+      if(classStr.Contains("ITS")) {
+        AddHistogram(classStr.Data(),"ITSncls", "ITS nclusters;# clusters ITS", kFALSE,
+                     7,-0.5,6.5,kITSncls);
+       AddHistogram(classStr.Data(),"ITSncls_Run", "ITS <nclusters> vs run;run;# clusters ITS", kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 7,-0.5,6.5, kITSncls);
+       AddHistogram(classStr.Data(),"ITSncls_Cent_prof", "ITS <nclusters> vs centrality; centrality;# clusters ITS", kTRUE,
+                     20, 0.0, 100.0, kCentVZERO, 7,-0.5,6.5, kITSncls);
+        AddHistogram(classStr.Data(),"Pt_ITSncls","ITS nclusters vs p_{T};p_{T} (GeV/c);# clusters ITS",kFALSE,
+                     100, 0.0, 10.0, kPt, 7,-0.5,6.5, kITSncls);
+        AddHistogram(classStr.Data(),"Eta_Phi_ITSncls_prof","ITS <nclusters> vs (#eta,#phi);#eta;#phi (rad.);# clusters ITS",kTRUE,
+                     192, -1.2, 1.2, kEta, 126, 0.0, 6.3, kPhi, 7, -0.5, 6.5, kITSncls);
+      }  // end if ITS histograms
+      
+      if(classStr.Contains("TPC")) {
+        AddHistogram(classStr.Data(),"TPCncls","TPC nclusters;# clusters TPC",kFALSE,
+                     160,-0.5,159.5,kTPCncls);
+       AddHistogram(classStr.Data(),"TPCncls_Run","TPC nclusters vs run;run;# clusters TPC",kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 160,-0.5,159.5, kTPCncls);
+       AddHistogram(classStr.Data(),"TPCncls_CentVZERO","TPC nclusters vs centrality;centrality;# clusters TPC",kFALSE,
+                     20, 0.0, 100.0, kCentVZERO, 160,-0.5,159.5, kTPCncls);
+       AddHistogram(classStr.Data(),"TPCncls_Pin","TPC nclusters vs inner param P; P (GeV/c); # clusters TPC",kFALSE,
+                     200,0.0,20,kPin,160,-0.5,159.5,kTPCncls);
+       AddHistogram(classStr.Data(),"Eta_Phi_TPCncls_prof","TPC <nclusters> vs (#eta,#phi);#eta;#phi (rad.);# clusters TPC",kTRUE,
+                     192, -1.2, 1.2, kEta, 126, 0.0, 6.3, kPhi, 160, -0.5, 159.5, kTPCncls);    
+        AddHistogram(classStr.Data(),"TPCsignal_Pin","TPC dE/dx vs. inner param P;P (GeV/c);TPC dE/dx",kFALSE,
+                     1000,0.0,20.0,kPin,151,-0.5,150.5,kTPCsignal);
+        AddHistogram(classStr.Data(),"TPCsignal_TPCclusters","TPC dE/dx vs. TPC nclusters;TPC #clusters;TPC dE/dx",kFALSE,
+                     160,-0.5,159.5,kTPCncls,151,-0.5,150.5,kTPCsignal);
+        AddHistogram(classStr.Data(),"TPCnsigElectron_Pin","TPC N_{#sigma} electron vs. inner param P;P (GeV/c);N_{#sigma}",kFALSE,
+                     1000,0.0,20.0,kPin,100,-5.0,5.0,kTPCnSig+kElectron);
+       AddHistogram(classStr.Data(),"TPCnsigElectron_CentEta_prof","TPC N_{#sigma} electron vs. (#eta,centrality); #eta; centrality VZERO;N_{#sigma}",kTRUE,
+                     100,-1.0,1.0,kEta, 20, 0.0, 100.0, kCentVZERO, 100,-5.0,5.0,kTPCnSig+kElectron);
+       AddHistogram(classStr.Data(),"TPCnsigElectron_Run","TPC N_{#sigma} electron vs. run; run; N_{#sigma}",kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo,100,-5.0,5.0,kTPCnSig+kElectron);
+      }      // end if TPC histograms
+    
+      if(classStr.Contains("TRD")) {
+        AddHistogram(classStr.Data(),"TRDntracklets","TRD ntracklets; #tracklets TRD",kFALSE,
+                     7,-0.5,6.5,kTRDntracklets);
+       AddHistogram(classStr.Data(),"TRDntrackletsPID","TRD ntracklets PID; #tracklets TRD",kFALSE,
+                     7,-0.5,6.5,kTRDntrackletsPID);
+       AddHistogram(classStr.Data(),"TRDprobabElectron","TRD electron probability; probability",kFALSE,
+                     500,0.0,1.0,kTRDpidProbabilities);
+       AddHistogram(classStr.Data(),"TRDprobabPion","TRD pion probability; probability",kFALSE,
+                     500,0.0,1.0,kTRDpidProbabilities+1);
+        AddHistogram(classStr.Data(),"TRDntracklets_Run","TRD <ntracklets> vs run; run; #tracklets TRD",kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 7,-0.5,6.5,kTRDntracklets);
+        AddHistogram(classStr.Data(),"TRDntrackletsPID_Run","TRD <ntracklets PID> vs run; run; #tracklets TRD",kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 7,-0.5,6.5,kTRDntrackletsPID);
+        AddHistogram(classStr.Data(),"TRDprobabEle_Run","TRD <electron probability> vs run; run; probability",kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 10,0.0,1.0,kTRDpidProbabilities);
+       AddHistogram(classStr.Data(),"TRDprobabPion_Run","TRD <pion probability> vs run; run; probability",kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 10,0.0,1.0,kTRDpidProbabilities+1);
+       AddHistogram(classStr.Data(),"Eta_Phi_TRDntracklets_prof","TRD <ntracklets> vs (#eta,#phi);#eta;#phi (rad.);#tracklets TRD",kTRUE,
+                     192, -1.2, 1.2, kEta, 126, 0.0, 6.3, kPhi, 7, -0.5, 6.5, kTRDntracklets);   
+        AddHistogram(classStr.Data(),"TRDntracklets_cent","TRD ntracklets vs centrality; #tracklets TRD; centrality (%)",kFALSE,
+                     7,-0.5,6.5,kTRDntracklets,20,0.0, 100.0, kCentSPD);
+        AddHistogram(classStr.Data(),"Eta_Phi_TRDntrackletsPID_prof","TRD <ntracklets PID> vs (#eta,#phi);#eta;#phi (rad.);#tracklets TRD",kTRUE,
+                     192, -1.2, 1.2, kEta, 126, 0.0, 6.3, kPhi, 7, -0.5, 6.5, kTRDntrackletsPID);
+        AddHistogram(classStr.Data(),"TRDntrackletsPID_cent","TRD ntracklets PID vs centrality; #tracklets TRD; centrality (%)",kFALSE,
+                     7,-0.5,6.5,kTRDntrackletsPID,20,0.0, 100.0, kCentSPD);
+        AddHistogram(classStr.Data(),"TRDntracklets_TRDntrackletsPID","TRD ntracklets vs TRD ntracklets PID; #tracklets TRD; #tracklets TRD pid",kFALSE,
+                     7,-0.5,6.5,kTRDntracklets,7,-0.5, 6.5, kTRDntrackletsPID);
+      }   // end if TRD histograms
+    
+      if(classStr.Contains("TOF")) {
+        AddHistogram(classStr.Data(),"TOFbeta_P","TOF #beta vs P;P (GeV/c);#beta",kFALSE,
+                     200,0.0,20.0,kP, 220,0.0,1.1,kTOFbeta);
+       AddHistogram(classStr.Data(),"Eta_Phi_TOFbeta_prof","TOF <#beta> vs (#eta,#phi);#eta;#phi (rad.);TOF #beta",kTRUE,
+                     192, -1.2, 1.2, kEta, 126, 0.0, 6.3, kPhi, 160, -0.5, 159.5, kTOFbeta);
+        AddHistogram(classStr.Data(),"TOFnsigElectron_P","TOF N_{#sigma} electron vs. P;P (GeV/c);N_{#sigma}",kFALSE,
+                     200,0.0,20.0,kP, 100,-5.0,5.0,kTOFnSig+kElectron);
+       AddHistogram(classStr.Data(),"TOFnSigElectron_Run","TOF <n-#sigma_{e}> vs run number;run;TOF n-#sigma_{e}",kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 160, -0.5, 159.5, kTOFnSig+kElectron);
+      }    // end if TOF histograms
+      continue;
+    }  // end if "TrackQA"
+    
+    Double_t massBinWidth = 0.04;     // *GeV/c^2
+    Double_t massRange[2] = {0.0,6.0};
+    const Int_t nMassBins = TMath::Nint((massRange[1]-massRange[0])/massBinWidth);
+    Double_t massBinLims[nMassBins+1]; for(Int_t im=0; im<=nMassBins; ++im) massBinLims[im] = massBinWidth*im;
+        
+    // Histograms for pairs
+    if(classStr.Contains("PairQA")) {
+      AddHistClass(classStr.Data());
+      
+      AddHistogram(classStr.Data(), "Mass_CentVZEROCep", 
+                  "Inv. mass vs (centVZERO, #Psi^{2}); centrality VZERO; #Psi^{2}; m (GeV/c^{2})", 
+                  kFALSE, gkNCentRanges, gkEMCentLims, kCentVZERO, gkNPhiEPRanges, gkEMPhiEPLims, gkEPused, nMassBins, massBinLims, kMass);  
+      AddHistogram(classStr.Data(), "Pt", "Pt; p_{T} (GeV/c)", kFALSE,
+                     1000, 0.0, 10.0, kPairPt);
+      
+      if(classStr.Contains("SE")) {
+        AddHistogram(classStr.Data(), "CandidateId", "Candidate id; p_{T} (GeV/c)", kFALSE,
+                     AliCorrelationReducedPair::kNMaxCandidateTypes+1, -0.5, Double_t(AliCorrelationReducedPair::kNMaxCandidateTypes)+0.5, kCandidateId);
+        AddHistogram(classStr.Data(), "PairType", "Pair type; pair type", kFALSE,
+                     4, -0.5, 3.5, kPairType); 
+        AddHistogram(classStr.Data(), "Mass", "Invariant mass; m_{inv} (GeV/c^{2})", kFALSE,
+                     nMassBins, massRange[0], massRange[1], kMass);
+        AddHistogram(classStr.Data(), "Rapidity", "Rapidity; y", kFALSE,
+                     240, -1.2, 1.2, kPairRap);
+       AddHistogram(classStr.Data(), "Eta", "Pseudo-rapidity #eta; #eta", kFALSE,
+                     240, -2.0, 2.0, kPairEta);
+        AddHistogram(classStr.Data(), "Phi", "Azimuthal distribution; #phi (rad.)", kFALSE,
+                     315, 0.0, 6.3, kPairPhi);
+       AddHistogram(classStr.Data(), "OpeningAngle", "Opening angle; op. angle (rad)", kFALSE,
+                     1000, 0.0, 3.2, kPairOpeningAngle);
+       AddHistogram(classStr.Data(), "Mass_Pt", "Pt vs invariant mass; m_{inv} (GeV/c^{2}); p_{T} (GeV/c)", kFALSE,
+                     nMassBins, massRange[0], massRange[1], kMass, 100, 0.0, 10.0, kPairPt);
+       AddHistogram(classStr.Data(), "Mass_Run_prof", "<Invariant mass> vs run; run;m_{inv} (GeV/c^{2})", kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, nMassBins, massRange[0], massRange[1], kMass);
+        AddHistogram(classStr.Data(), "Pt_Run_prof", "<p_{T}> vs run; run;p_{T} (GeV/c)", kTRUE,
+                     kNRunBins, runHistRange[0], runHistRange[1], kRunNo, 1000, 0.0, 10.0, kPairPt);
+       AddHistogram(classStr.Data(), "VZEROflow_sideA_v2_Mass",
+                     "Pair v2 coefficient using VZERO-A reaction plane; inv.mass (GeV/c^{2});v_{2}(#Psi_{2}^{VZERO-A})", kTRUE,
+                     nMassBins, massRange[0], massRange[1], kMass, 1000, -1., 1., kPairVZEROFlowVn+0*6+1);
+       AddHistogram(classStr.Data(), "VZEROflow_sideC_v2_Mass",
+                     "Pair v2 coefficient using VZERO-C reaction plane; inv.mass (GeV/c^{2});v_{2}(#Psi_{2}^{VZERO-C})", kTRUE,
+                     nMassBins, massRange[0], massRange[1], kMass, 1000, -1., 1., kPairVZEROFlowVn+1*6+1);
+       AddHistogram(classStr.Data(), "TPCflow_v2_Mass",
+                     "Pair v2 coefficient using TPC reaction plane; inv.mass (GeV/c^{2});v_{2}(#Psi_{2}^{TPC})", kTRUE,
+                     nMassBins, massRange[0], massRange[1], kMass, 1000, -1., 1., kPairTPCFlowVn+1);
+      }
+      continue;
+    }   // end if for Pair classes of histograms
+    
+  }   // end loop over histogram classes
+}