]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGCF/Correlations/Base/AliUEHist.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGCF / Correlations / Base / AliUEHist.cxx
index ad5ed98f29ffa18f1b1812730ecd84defa1f98bf..18e396589474ad913af2a780f5266bda898934ab 100644 (file)
@@ -41,7 +41,7 @@ ClassImp(AliUEHist)
 
 const Int_t AliUEHist::fgkCFSteps = 11;
 
-AliUEHist::AliUEHist(const char* reqHist) : 
+AliUEHist::AliUEHist(const char* reqHist, const char* binning) : 
   TObject(),
   fkRegions(4),
   fEventHist(0),
@@ -51,13 +51,17 @@ AliUEHist::AliUEHist(const char* reqHist) :
   fEtaMax(0),
   fPtMin(0),
   fPtMax(0),
+  fPartSpecies(-1),
   fCentralityMin(0),
   fCentralityMax(0),
   fZVtxMin(0),
   fZVtxMax(0),
+  fPt2Min(0),
   fContaminationEnhancement(0),
   fCombineMinMax(0),
   fTrackEtaCut(0),
+  fWeightPerEvent(0),
+  fSkipScaleMixedEvent(kFALSE),
   fCache(0),
   fGetMultCacheOn(kFALSE),
   fGetMultCache(0),
@@ -71,7 +75,7 @@ AliUEHist::AliUEHist(const char* reqHist) :
   if (strlen(reqHist) == 0)
     return;
   
-  Printf("Creating AliUEHist with %s", reqHist);
+  Printf("Creating AliUEHist with %s (binning: %s)", reqHist, binning);
     
   AliLog::SetClassDebugLevel("AliCFContainer", -1);
   AliLog::SetClassDebugLevel("AliCFGridSparse", -3);
@@ -80,114 +84,58 @@ AliUEHist::AliUEHist(const char* reqHist) :
     
   // track level
   Int_t nTrackVars = 4; // eta vs pT vs pT,lead (vs delta phi) vs multiplicity
-  Int_t iTrackBin[6];
-  Double_t* trackBins[6];
-  const char* trackAxisTitle[6];
+  Int_t iTrackBin[7];
+  Double_t* trackBins[7];
+  const char* trackAxisTitle[7];
   
   // eta
-  const Int_t kNEtaBins = 20;
-  Double_t etaBins[20+1];
-  for (Int_t i=0; i<=kNEtaBins; i++)
-    etaBins[i] = -1.0 + 0.1 * i;
+  Int_t nEtaBins = -1;
+  Double_t* etaBins = GetBinning(binning, "eta", nEtaBins);
   const char* etaTitle = "#eta";
-  iTrackBin[0] = kNEtaBins;
+  
+  iTrackBin[0] = nEtaBins;
   trackBins[0] = etaBins;
   trackAxisTitle[0] = etaTitle;
   
   // delta eta
-  const Int_t kNDeltaEtaBins = 48;
-  Double_t deltaEtaBins[kNDeltaEtaBins+1] = { -2.4, -2.3, -2.2, -2.1, 
-                                             -2.0, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, 
-                                             -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 
-                                             0, 
-                                             0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 
-                                             1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0,
-                                             2.1, 2.2, 2.3, 2.4 };
-  
-  const Int_t kNDeltaEtaBinsTTR = 40+4;
-  Double_t deltaEtaBinsTTR[kNDeltaEtaBinsTTR+1] = { -2.0, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, 
-                                                 -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 
-                                                 -0.05, -0.025, 0, 0.025, 0.05, 
-                                                 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 
-                                                 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0 };
+  Int_t nDeltaEtaBins = -1;
+  Double_t* deltaEtaBins = GetBinning(binning, "delta_eta", nDeltaEtaBins);
 
   // pT
-  iTrackBin[1] = 9;
-  Double_t pTBins[] = {0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 8.0 };
-  trackBins[1] = pTBins;
+  trackBins[1] = GetBinning(binning, "p_t_assoc", iTrackBin[1]);
   trackAxisTitle[1] = "p_{T} (GeV/c)";
   
   // pT, fine
-  const Int_t kNpTBinsFine = 22;
-  Double_t pTBinsFine[kNpTBinsFine+1] = {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.25, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0};
-
-  // pT, wide range
-  //const Int_t kNpTBinsWideRange = 20;
-  //Double_t pTBinsWideRange[kNpTBinsWideRange+1] = {0.15, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 7.0, 8.0, 10.0, 12.0, 15.0};
+  Int_t npTBinsFine = -1;
+  Double_t* pTBinsFine = GetBinning(binning, "p_t_eff", npTBinsFine);
 
   // pT,lead binning 1
-  const Int_t kNLeadingpTBins = 100;
-  Double_t leadingpTBins[kNLeadingpTBins+1];
-  for (Int_t i=0; i<=kNLeadingpTBins; i++)
-    leadingpTBins[i] = 0.5 * i;
-  
+  Int_t nLeadingpTBins = -1;
+  Double_t* leadingpTBins = GetBinning(binning, "p_t_leading", nLeadingpTBins);
+
   // pT,lead binning 2
-  //const Int_t kNLeadingpTBins2 = 8;
-//   Double_t leadingpTBins2[] = { 0.5, 1.0, 2.0, 3.0, 4.0, 6.0, 8.0, 10.0, 15.0 };
-  const Int_t kNLeadingpTBins2 = 6;
-  Double_t leadingpTBins2[] = { 0.5, 1.0, 2.0, 3.0, 4.0, 6.0, 8.0 };
-  
-  // phi,lead; this binning starts at -pi/2 and is modulo 3
-  const Int_t kNLeadingPhiSpacing = 72;
-  const Int_t kNLeadingPhiBins = kNLeadingPhiSpacing;
-  Double_t leadingPhiBins[kNLeadingPhiBins+1];
-  for (Int_t i=0; i<=kNLeadingPhiSpacing; i++)
-    leadingPhiBins[i] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * i;
-  
-  const Int_t kNLeadingPhiBinsTTR = kNLeadingPhiSpacing+4;
-  Double_t leadingPhiBinsTTR[kNLeadingPhiBinsTTR+1];
-  for (Int_t i=0; i<=17; i++)
-    leadingPhiBinsTTR[i] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * i;
-  leadingPhiBinsTTR[18] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * 17 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() / 2;
-  leadingPhiBinsTTR[19] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * 17 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() / 2 * 1.5;
-  leadingPhiBinsTTR[20] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * 17 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() / 2 * 2; // = 0
-  leadingPhiBinsTTR[21] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * 17 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() / 2 * 2.5;
-  leadingPhiBinsTTR[22] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * 17 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() / 2 * 3;
-  for (Int_t i=19; i<=kNLeadingPhiSpacing; i++)
-    leadingPhiBinsTTR[i+4] = -TMath::Pi() / 2 + 1.0 / kNLeadingPhiSpacing * TMath::TwoPi() * i;
-
-  // multiplicity
-  const Int_t kNMultiplicityBins = 15;
-  Double_t multiplicityBins[kNMultiplicityBins+1];
-  for (Int_t i=0; i<=kNMultiplicityBins; i++)
-    multiplicityBins[i] = -0.5 + i;
-  multiplicityBins[kNMultiplicityBins] = 200;
-  
-  trackBins[3] = multiplicityBins;
-  iTrackBin[3] = kNMultiplicityBins;
-  trackAxisTitle[3] = "multiplicity";
+  Int_t nLeadingpTBins2 = -1;
+  Double_t* leadingpTBins2 = GetBinning(binning, "p_t_leading_course", nLeadingpTBins2);
   
-  // centrality (in %)
-  const Int_t kNCentralityBins = 5 + 1 + 9;
-  Double_t centralityBins[] = { 0, 1, 2, 3, 4, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.1 };
+  // phi,lead
+  Int_t nLeadingPhiBins = -1;
+  Double_t* leadingPhiBins = GetBinning(binning, "delta_phi", nLeadingPhiBins);
+  
+  trackBins[3] = GetBinning(binning, "multiplicity", iTrackBin[3]);
+  trackAxisTitle[3] = "multiplicity";
   
-  const Int_t kNCentralityBinsCourse = 5;
-  Double_t centralityBinsCourse[] = { 0, 20, 40, 60, 80, 100.1 };
-
   // particle species
   const Int_t kNSpeciesBins = 4; // pi, K, p, rest
   Double_t speciesBins[] = { -0.5, 0.5, 1.5, 2.5, 3.5 };
   
   // vtx-z axis
   const char* vertexTitle = "z-vtx (cm)";
-  const Int_t kNVertexBins = 7;
-  Double_t vertexBins[] = { -7, -5, -3, -1, 1, 3, 5, 7 };
-  const Int_t kNVertexBins2 = 10;
-  Double_t vertexBins2[] = { -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10 };
+  Int_t nVertexBins = -1;
+  Double_t* vertexBins = GetBinning(binning, "vertex", nVertexBins);
+  Int_t nVertexBinsEff = -1;
+  Double_t* vertexBinsEff = GetBinning(binning, "vertex_eff", nVertexBinsEff);
   
   Int_t useVtxAxis = 0;
-  Bool_t useTTRBinning = kFALSE;
-  Bool_t useCourseCentralityBinning = kFALSE;
   
   // selection depending on requested histogram
   Int_t axis = -1; // 0 = pT,lead, 1 = phi,lead
@@ -205,12 +153,6 @@ AliUEHist::AliUEHist(const char* reqHist) :
   {
     if (TString(reqHist).Contains("Vtx"))
       useVtxAxis = 1;
-    if (TString(reqHist).Contains("Vtx10"))
-      useVtxAxis = 2;
-    if (TString(reqHist).Contains("TTR"))
-      useTTRBinning = kTRUE;
-    if (TString(reqHist).Contains("Course"))
-      useCourseCentralityBinning = kTRUE;
     
     reqHist = "NumberDensityPhiCentrality";
     fHistogramType = reqHist;
@@ -222,6 +164,15 @@ AliUEHist::AliUEHist(const char* reqHist) :
     axis = 0;
     title = "d^{2}#Sigma p_{T}/d#varphid#eta";
   }
+  else if (TString(reqHist).BeginsWith("TwoPlusOne"))
+  { 
+    useVtxAxis = 1;
+
+    reqHist = "TwoPlusOne";
+    fHistogramType = reqHist;
+    axis = 3;
+    title = "d^{2}N_{ch}/d#varphid#eta";
+  }
   else
     AliFatal(Form("Invalid histogram requested: %s", reqHist));
   
@@ -230,7 +181,7 @@ AliUEHist::AliUEHist(const char* reqHist) :
   if (axis == 0)
   {
     trackBins[2] = leadingpTBins;
-    iTrackBin[2] = kNLeadingpTBins;
+    iTrackBin[2] = nLeadingpTBins;
     trackAxisTitle[2] = "leading p_{T} (GeV/c)";
     
   }
@@ -239,11 +190,11 @@ AliUEHist::AliUEHist(const char* reqHist) :
     nTrackVars = 5;
     initRegions = 1;
   
-    iTrackBin[2] = kNLeadingpTBins2;
+    iTrackBin[2] = nLeadingpTBins2;
     trackBins[2] = leadingpTBins2;
     trackAxisTitle[2] = "leading p_{T} (GeV/c)";
     
-    iTrackBin[4] = kNLeadingPhiBins;
+    iTrackBin[4] = nLeadingPhiBins;
     trackBins[4] = leadingPhiBins;
     trackAxisTitle[4] = "#Delta #varphi w.r.t. leading track";
   }
@@ -252,34 +203,59 @@ AliUEHist::AliUEHist(const char* reqHist) :
     nTrackVars = 5;
     initRegions = 1;
   
-    iTrackBin[0] = (useTTRBinning) ? kNDeltaEtaBinsTTR : kNDeltaEtaBins;
-    trackBins[0] = (useTTRBinning) ? deltaEtaBinsTTR : deltaEtaBins;
+    iTrackBin[0] = nDeltaEtaBins;
+    trackBins[0] = deltaEtaBins;
     trackAxisTitle[0] = "#Delta#eta";
   
-    iTrackBin[2] = kNLeadingpTBins2;
+    iTrackBin[2] = nLeadingpTBins2;
     trackBins[2] = leadingpTBins2;
     trackAxisTitle[2] = "leading p_{T} (GeV/c)";
     
-    trackBins[3] = (useCourseCentralityBinning) ? centralityBinsCourse : centralityBins;
-    iTrackBin[3] = (useCourseCentralityBinning) ? kNCentralityBinsCourse : kNCentralityBins;
     trackAxisTitle[3] = "centrality";
   
-    iTrackBin[4] = (useTTRBinning) ? kNLeadingPhiBinsTTR : kNLeadingPhiBins;
-    trackBins[4] = (useTTRBinning) ? leadingPhiBinsTTR : leadingPhiBins;
+    iTrackBin[4] = nLeadingPhiBins;
+    trackBins[4] = leadingPhiBins;
     trackAxisTitle[4] = "#Delta#varphi (rad)";
 
     if (useVtxAxis > 0)
     {
       nTrackVars = 6;
-      iTrackBin[5] = (useVtxAxis == 1) ? kNVertexBins : kNVertexBins2;
-      trackBins[5] = (useVtxAxis == 1) ? vertexBins : vertexBins2;
+      iTrackBin[5] = nVertexBins;
+      trackBins[5] = vertexBins;
       trackAxisTitle[5] = vertexTitle;
     }
   }
+  else if (axis == 3)
+  {
+    nTrackVars = 7;
+    initRegions = 1;
+
+    iTrackBin[0] = nDeltaEtaBins;
+    trackBins[0] = deltaEtaBins;
+    trackAxisTitle[0] = "#Delta#eta";
+  
+    iTrackBin[2] = nLeadingpTBins;
+    trackBins[2] = leadingpTBins;
+    trackAxisTitle[2] = "Trigger 1 p_{T} (GeV/c)";
+    
+    trackAxisTitle[3] = "centrality";
+  
+    iTrackBin[4] = nLeadingPhiBins;
+    trackBins[4] = leadingPhiBins;
+    trackAxisTitle[4] = "#Delta#varphi (rad)";
+
+    iTrackBin[5] = nVertexBins;
+    trackBins[5] = vertexBins;
+    trackAxisTitle[5] = vertexTitle;
+
+    iTrackBin[6] = nLeadingpTBins2;
+    trackBins[6] = leadingpTBins2;
+    trackAxisTitle[6] = "Trigger 2 p_{T} (GeV/c)";
+  }
     
   for (UInt_t i=0; i<initRegions; i++)
   {
-    if (strcmp(reqHist, "NumberDensityPhiCentrality") == 0)
+    if (axis >= 2)
       fTrackHist[i] = new AliTHn(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
     else
       fTrackHist[i] = new AliCFContainer(Form("fTrackHist_%d", i), title, fgkCFSteps, nTrackVars, iTrackBin);
@@ -295,19 +271,23 @@ AliUEHist::AliUEHist(const char* reqHist) :
   
   // event level
   Int_t nEventVars = 2;
-  Int_t iEventBin[3];
+  Int_t iEventBin[4];
 
   // track 3rd and 4th axis --> event 1st and 2nd axis
   iEventBin[0] = iTrackBin[2];
   iEventBin[1] = iTrackBin[3];
   
   // plus track 5th axis (in certain cases)
-  if (axis == 2 && useVtxAxis)
+  if (axis >= 2 && useVtxAxis)
   {
     nEventVars = 3;
     iEventBin[2] = iTrackBin[5];
   }
-  
+  if (axis >= 3)
+  {
+    nEventVars = 4;
+    iEventBin[3] = iTrackBin[6];
+  }
   fEventHist = new AliCFContainer("fEventHist", title, fgkCFSteps, nEventVars, iEventBin);
   
   fEventHist->SetBinLimits(0, trackBins[2]);
@@ -316,31 +296,104 @@ AliUEHist::AliUEHist(const char* reqHist) :
   fEventHist->SetBinLimits(1, trackBins[3]);
   fEventHist->SetVarTitle(1, trackAxisTitle[3]);
   
-  if (axis == 2 && useVtxAxis)
+  if (axis >= 2 && useVtxAxis)
   {
     fEventHist->SetBinLimits(2, trackBins[5]);
     fEventHist->SetVarTitle(2, trackAxisTitle[5]);
   }
+  if (axis >= 3)
+  {
+    fEventHist->SetBinLimits(3, trackBins[6]);
+    fEventHist->SetVarTitle(3, trackAxisTitle[6]);
+  }
 
   SetStepNames(fEventHist);
   
-  iTrackBin[1] = kNpTBinsFine;
+  iTrackBin[0] = nEtaBins;
+  iTrackBin[1] = npTBinsFine;
   iTrackBin[2] = kNSpeciesBins;
-  iTrackBin[4] = kNVertexBins2;
+  iTrackBin[4] = nVertexBinsEff;
 
-  fTrackHistEfficiency = new AliCFContainer("fTrackHistEfficiency", "Tracking efficiency", 4, 5, iTrackBin);
-  fTrackHistEfficiency->SetBinLimits(0, trackBins[0]);
-  fTrackHistEfficiency->SetVarTitle(0, trackAxisTitle[0]);
+  fTrackHistEfficiency = new AliCFContainer("fTrackHistEfficiency", "Tracking efficiency", 6, 5, iTrackBin);
+  fTrackHistEfficiency->SetBinLimits(0, etaBins);
+  fTrackHistEfficiency->SetVarTitle(0, etaTitle);
   fTrackHistEfficiency->SetBinLimits(1, pTBinsFine);
   fTrackHistEfficiency->SetVarTitle(1, trackAxisTitle[1]);
   fTrackHistEfficiency->SetBinLimits(2, speciesBins);
   fTrackHistEfficiency->SetVarTitle(2, "particle species");
   fTrackHistEfficiency->SetBinLimits(3, trackBins[3]);
   fTrackHistEfficiency->SetVarTitle(3, trackAxisTitle[3]);
-  fTrackHistEfficiency->SetBinLimits(4, vertexBins2);
+  fTrackHistEfficiency->SetBinLimits(4, vertexBinsEff);
   fTrackHistEfficiency->SetVarTitle(4, vertexTitle);
 
   fFakePt = new TH3F("fFakePt","fFakePt;p_{T,rec};p_{T};centrality", 200, 0, 20, 200, 0, 20, 20, 0, 100);
+  
+  delete[] deltaEtaBins;
+  delete[] pTBinsFine;
+  delete[] leadingpTBins;
+  delete[] leadingpTBins2;
+  delete[] leadingPhiBins;
+  delete[] vertexBins;
+  delete[] vertexBinsEff;
+}
+  
+TString AliUEHist::CombineBinning(TString defaultBinning, TString customBinning) 
+{
+  // combine default binning with custom binning
+  // replaces binnings in default binning if it is defined in custom binning
+  
+  TString binningStr;
+
+  TObjArray* lines = defaultBinning.Tokenize("\n");
+  for (Int_t i=0; i<lines->GetEntriesFast(); i++)
+  {
+    TString line(lines->At(i)->GetName());
+    TString tag = line(0, line.Index(":")+1);
+    if (!customBinning.BeginsWith(tag) && !customBinning.Contains(TString("\n") + tag))
+      binningStr += line + "\n";
+    else
+      Printf("Using custom binning for %s", tag.Data());
+  }
+  delete lines;
+  binningStr += customBinning;
+  
+  return binningStr;
+}
+  
+Double_t* AliUEHist::GetBinning(const char* configuration, const char* tag, Int_t& nBins)
+{
+  // takes the binning from <configuration> identified by <tag>
+  // configuration syntax example:
+  // eta: 2.4, -2.3, -2.2, -2.1, -2.0, -1.9, -1.8, -1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1.0, -0.9, -0.8, -0.7, -0.6, -0.5, -0.4, -0.3, -0.2, -0.1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4
+  // phi: .....
+  //
+  // returns bin edges which have to be deleted by the caller
+  
+  TString config(configuration);
+  TObjArray* lines = config.Tokenize("\n");
+  for (Int_t i=0; i<lines->GetEntriesFast(); i++)
+  {
+    TString line(lines->At(i)->GetName());
+    if (line.BeginsWith(TString(tag) + ":"))
+    {
+      line.Remove(0, strlen(tag) + 1);
+      line.ReplaceAll(" ", "");
+      TObjArray* binning = line.Tokenize(",");
+      Double_t* bins = new Double_t[binning->GetEntriesFast()];
+      for (Int_t j=0; j<binning->GetEntriesFast(); j++)
+       bins[j] = TString(binning->At(j)->GetName()).Atof();
+      
+      nBins = binning->GetEntriesFast() - 1;
+
+      delete binning;
+      delete lines;
+      return bins;
+    }
+  }
+  
+  delete lines;
+  AliFatal(Form("Tag %s not found in %s", tag, configuration));
+  return 0;
 }
 
 //_____________________________________________________________________________
@@ -354,13 +407,17 @@ AliUEHist::AliUEHist(const AliUEHist &c) :
   fEtaMax(0),
   fPtMin(0),
   fPtMax(0),
+  fPartSpecies(-1),
   fCentralityMin(0),
   fCentralityMax(0),
   fZVtxMin(0),
   fZVtxMax(0),
+  fPt2Min(0),
   fContaminationEnhancement(0),
   fCombineMinMax(0),
   fTrackEtaCut(0),
+  fWeightPerEvent(0),
+  fSkipScaleMixedEvent(kFALSE),
   fCache(0),
   fGetMultCacheOn(kFALSE),
   fGetMultCache(0),
@@ -456,16 +513,20 @@ void AliUEHist::Copy(TObject& c) const
   target.fEtaMax = fEtaMax;
   target.fPtMin = fPtMin;
   target.fPtMax = fPtMax;
+  target.fPartSpecies = fPartSpecies;
   target.fCentralityMin = fCentralityMin;
   target.fCentralityMax = fCentralityMax;
   target.fZVtxMin = fZVtxMin;
   target.fZVtxMax = fZVtxMax;
+  target.fPt2Min = fPt2Min;
   
   if (fContaminationEnhancement)
     target.fContaminationEnhancement = dynamic_cast<TH1F*> (fContaminationEnhancement->Clone());
     
   target.fCombineMinMax = fCombineMinMax;
   target.fTrackEtaCut = fTrackEtaCut;
+  target.fWeightPerEvent = fWeightPerEvent;
+  target.fSkipScaleMixedEvent = fSkipScaleMixedEvent;
   target.fHistogramType = fHistogramType;
 }
 
@@ -536,6 +597,8 @@ void AliUEHist::SetBinLimits(THnBase* grid)
     grid->GetAxis(0)->SetRangeUser(fEtaMin, fEtaMax);
   if (fPtMax > fPtMin)
     grid->GetAxis(1)->SetRangeUser(fPtMin, fPtMax);
+  if (fPt2Min > 0)
+    grid->GetAxis(6)->SetRangeUser(fPt2Min, grid->GetAxis(6)->GetXmax() - 0.01);
 }  
 
 //____________________________________________________________________
@@ -642,7 +705,7 @@ void AliUEHist::CountEmptyBins(AliUEHist::CFStep step, Float_t ptLeadMin, Float_
 }  
 
 //____________________________________________________________________
-TH1* AliUEHist::GetUEHist(AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Int_t twoD, Bool_t etaNorm, Int_t* normEvents)
+TH1* AliUEHist::GetUEHist(AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Int_t twoD, Bool_t etaNorm, Long64_t* normEvents)
 {
   // Extracts the UE histogram at the given step and in the given region by projection and dividing tracks by events
   //
@@ -776,8 +839,8 @@ TH1* AliUEHist::GetUEHist(AliUEHist::CFStep step, AliUEHist::Region region, Floa
     
     // NOTE fEventHist contains the number of events for the underlying event analysis and the number of trigger particles for the azimuthal correlation analysis. In the latter case the naming is therefore somewhat misleading!
     TH1D* events = fEventHist->ShowProjection(0, step);
-    Int_t nEvents = (Int_t) events->Integral(firstBin, lastBin);
-    Printf("Calculated histogram --> %d events", nEvents);
+    Long64_t nEvents = (Long64_t) events->Integral(firstBin, lastBin);
+    Printf("Calculated histogram --> %lld events", nEvents);
     if (normEvents)
       *normEvents = nEvents;
       
@@ -845,7 +908,6 @@ void AliUEHist::GetHistsZVtxMult(AliUEHist::CFStep step, AliUEHist::Region regio
     {
       fGetMultCache = ChangeToThn(sparse);
       // should work but causes SEGV in ProjectionND below 
-//       delete sparse;
     }
     sparse = fGetMultCache;
   }
@@ -861,6 +923,15 @@ void AliUEHist::GetHistsZVtxMult(AliUEHist::CFStep step, AliUEHist::Region regio
   Printf("Using leading pT range %d --> %d", firstBin, lastBin);
   sparse->GetAxis(2)->SetRange(firstBin, lastBin);
   fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->SetRange(firstBin, lastBin);
+
+  // cut on the second trigger particle if there is a minimum set
+  if (fPt2Min > 0)
+  {
+    Int_t firstBinPt2 = sparse->GetAxis(6)->FindBin(fPt2Min);
+    Int_t lastBinPt2 = sparse->GetAxis(6)->GetNbins();
+
+    fEventHist->GetGrid(step)->GetGrid()->GetAxis(3)->SetRange(firstBinPt2, lastBinPt2);
+  }
     
   Int_t dimensions[] = { 4, 0, 5, 3 };
   THnBase* tmpTrackHist = sparse->ProjectionND(4, dimensions, "E");
@@ -871,10 +942,11 @@ void AliUEHist::GetHistsZVtxMult(AliUEHist::CFStep step, AliUEHist::Region regio
 
   // convert to THn 
   *trackHist = ChangeToThn(tmpTrackHist);
+  delete tmpTrackHist;
 }
 
 //____________________________________________________________________
-TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd)
+TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Bool_t normalizePerTrigger, Int_t stepForMixed)
 {
   // Calls GetUEHist(...) for *each* vertex bin and multiplicity bin and performs a sum of ratios:
   // 1_N [ (same/mixed)_1 + (same/mixed)_2 + (same/mixed)_3 + ... ]
@@ -884,25 +956,38 @@ TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEH
   // returns a 2D histogram: deltaphi, deltaeta
   //
   // Parameters:
-  //   mixed: AliUEHist containing mixed event corresponding to this object
+  //   mixed: AliUEHist containing mixed event corresponding to this object (the histograms are taken from step <stepForMixed> if defined otherwise from step <step>)
   //   <other parameters> : check documentation of AliUEHist::GetUEHist
+  //  normalizePerTrigger: divide through number of triggers
   
   // do not add this hists to the directory
   Bool_t oldStatus = TH1::AddDirectoryStatus();
   TH1::AddDirectory(kFALSE);
-
+  
   TH2* totalTracks = 0;
   
   THnBase* trackSameAll = 0;
   THnBase* trackMixedAll = 0;
+  THnBase* trackMixedAllStep6 = 0;
   TH2* eventSameAll = 0;
   TH2* eventMixedAll = 0;
+  TH2* eventMixedAllStep6 = 0;
   
-  Int_t totalEvents = 0;
+  Long64_t totalEvents = 0;
   Int_t nCorrelationFunctions = 0;
   
   GetHistsZVtxMult(step, region, ptLeadMin, ptLeadMax, &trackSameAll, &eventSameAll);
-  mixed->GetHistsZVtxMult(step, region, ptLeadMin, ptLeadMax, &trackMixedAll, &eventMixedAll);
+  mixed->GetHistsZVtxMult((stepForMixed == -1) ? step : (CFStep) stepForMixed, region, ptLeadMin, ptLeadMax, &trackMixedAll, &eventMixedAll);
+  
+  // If we ask for histograms from step8 (TTR cut applied) there is a hole at 0,0; so this cannot be used for the
+  // mixed-event normalization. If step6 is available, the normalization factor is read out from that one.
+  // If step6 is not available we fallback to taking the normalization along all delta phi (WARNING requires a
+  // flat delta phi distribution)
+  if (stepForMixed == -1 && step == kCFStepBiasStudy && mixed->fEventHist->GetGrid(kCFStepReconstructed)->GetEntries() > 0 && !fSkipScaleMixedEvent)
+  {
+    Printf("Using mixed-event normalization factors from step %d", kCFStepReconstructed);
+    mixed->GetHistsZVtxMult(kCFStepReconstructed, region, ptLeadMin, ptLeadMax, &trackMixedAllStep6, &eventMixedAllStep6);
+  }
   
 //   Printf("%f %f %f %f", trackSameAll->GetEntries(), eventSameAll->GetEntries(), trackMixedAll->GetEntries(), eventMixedAll->GetEntries());
   
@@ -922,85 +1007,127 @@ TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEH
   {
     trackSameAll->GetAxis(3)->SetRange(multBin, multBin);
     trackMixedAll->GetAxis(3)->SetRange(multBin, multBin);
+    if (trackMixedAllStep6)
+      trackMixedAllStep6->GetAxis(3)->SetRange(multBin, multBin);
 
-    // get mixed normalization correction factor: is independent of vertex bin if scaled with number of triggers
-    trackMixedAll->GetAxis(2)->SetRange(0, -1);
-    TH2* tracksMixed = trackMixedAll->Projection(1, 0, "E");
-//     Printf("%f", tracksMixed->Integral());
-    Float_t binWidthEta = tracksMixed->GetYaxis()->GetBinWidth(1);
-    
-    // get mixed event normalization by assuming full acceptance at deta at 0 (integrate over dphi), excluding (0, 0)
+    Double_t mixedNorm = 1;
     Double_t mixedNormError = 0;
-    Double_t mixedNorm = tracksMixed->IntegralAndError(1, tracksMixed->GetYaxis()->FindBin(-0.01)-1, tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError);
-    Double_t mixedNormError2 = 0;
-    Double_t mixedNorm2 = tracksMixed->IntegralAndError(tracksMixed->GetYaxis()->FindBin(0.01)+1, tracksMixed->GetNbinsX(), tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError2);
-    
-    if (mixedNormError == 0 || mixedNormError2 == 0)
+
+    if (!fSkipScaleMixedEvent)
     {
-      Printf("ERROR: Skipping multiplicity %d because mixed event is empty %f %f %f %f", multBin, mixedNorm, mixedNormError, mixedNorm2, mixedNormError2);
-      continue;
-    }
+      // get mixed normalization correction factor: is independent of vertex bin if scaled with number of triggers
+      TH2* tracksMixed = 0;
+      if (trackMixedAllStep6)
+      {
+       trackMixedAllStep6->GetAxis(2)->SetRange(0, -1);
+       tracksMixed = trackMixedAllStep6->Projection(1, 0, "E");
+      }
+      else
+      {
+       trackMixedAll->GetAxis(2)->SetRange(0, -1);
+       tracksMixed = trackMixedAll->Projection(1, 0, "E");
+      }
+  //     Printf("%f", tracksMixed->Integral());
+      Float_t binWidthEta = tracksMixed->GetYaxis()->GetBinWidth(1);
     
-    Int_t nBinsMixedNorm = (tracksMixed->GetYaxis()->FindBin(-0.01) - 1 - 1 + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
-    mixedNorm /= nBinsMixedNorm;
-    mixedNormError /= nBinsMixedNorm;
+      if (step == kCFStepBiasStudy && !trackMixedAllStep6)
+      {
+       // get mixed event normalization by assuming full acceptance at deta at 0 (integrate over dphi), excluding (0, 0)
+       Float_t phiExclude = 0.41;
+       mixedNorm = tracksMixed->IntegralAndError(1, tracksMixed->GetXaxis()->FindBin(-phiExclude)-1, tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError);
+       Double_t mixedNormError2 = 0;
+       Double_t mixedNorm2 = tracksMixed->IntegralAndError(tracksMixed->GetXaxis()->FindBin(phiExclude)+1, tracksMixed->GetNbinsX(), tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError2);
+      
+       if (mixedNormError == 0 || mixedNormError2 == 0)
+       {
+         Printf("ERROR: Skipping multiplicity %d because mixed event is empty %f %f %f %f", multBin, mixedNorm, mixedNormError, mixedNorm2, mixedNormError2);
+         continue;
+       }
+       
+       Int_t nBinsMixedNorm = (tracksMixed->GetXaxis()->FindBin(-phiExclude) - 1 - 1 + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
+       mixedNorm /= nBinsMixedNorm;
+       mixedNormError /= nBinsMixedNorm;
 
-    Int_t nBinsMixedNorm2 = (tracksMixed->GetNbinsX() - tracksMixed->GetYaxis()->FindBin(0.01) - 1 + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
-    mixedNorm2 /= nBinsMixedNorm2;
-    mixedNormError2 /= nBinsMixedNorm2;
+       Int_t nBinsMixedNorm2 = (tracksMixed->GetNbinsX() - tracksMixed->GetXaxis()->FindBin(phiExclude) - 1 + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
+       mixedNorm2 /= nBinsMixedNorm2;
+       mixedNormError2 /= nBinsMixedNorm2;
 
-    mixedNorm = mixedNorm / mixedNormError / mixedNormError + mixedNorm2 / mixedNormError2 / mixedNormError2;
-    mixedNormError = TMath::Sqrt(1.0 / (1.0 / mixedNormError / mixedNormError + 1.0 / mixedNormError2 / mixedNormError2));
-    mixedNorm *= mixedNormError * mixedNormError;
-    
-/*    Double_t mixedNorm = tracksMixed->IntegralAndError(tracksMixed->GetXaxis()->FindBin(-0.01), tracksMixed->GetXaxis()->FindBin(0.01), tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError);
-    Int_t nBinsMixedNorm = (tracksMixed->GetXaxis()->FindBin(0.01) - tracksMixed->GetXaxis()->FindBin(-0.01) + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);*/
+       mixedNorm = mixedNorm / mixedNormError / mixedNormError + mixedNorm2 / mixedNormError2 / mixedNormError2;
+       mixedNormError = TMath::Sqrt(1.0 / (1.0 / mixedNormError / mixedNormError + 1.0 / mixedNormError2 / mixedNormError2));
+       mixedNorm *= mixedNormError * mixedNormError;
+      }
+      else
+      {
+       // get mixed event normalization at (0,0)
+      
+       mixedNorm = tracksMixed->IntegralAndError(tracksMixed->GetXaxis()->FindBin(-0.01), tracksMixed->GetXaxis()->FindBin(0.01), tracksMixed->GetYaxis()->FindBin(-0.01), tracksMixed->GetYaxis()->FindBin(0.01), mixedNormError);
+       Int_t nBinsMixedNorm = (tracksMixed->GetXaxis()->FindBin(0.01) - tracksMixed->GetXaxis()->FindBin(-0.01) + 1) * (tracksMixed->GetYaxis()->FindBin(0.01) - tracksMixed->GetYaxis()->FindBin(-0.01) + 1);
+       mixedNorm /= nBinsMixedNorm;
+       mixedNormError /= nBinsMixedNorm;
 
-    delete tracksMixed;
-    
-    Float_t triggers = eventMixedAll->Integral(1, eventMixedAll->GetNbinsX(), multBin, multBin);
+       if (mixedNormError == 0)
+       {
+         Printf("ERROR: Skipping multiplicity %d because mixed event is empty %f %f", multBin, mixedNorm, mixedNormError);
+         continue;
+       }
+      }
+
+      // finite bin correction
+      if (fTrackEtaCut > 0)
+      {
+       Double_t finiteBinCorrection = -1.0 / (2*fTrackEtaCut) * binWidthEta / 2 + 1;
+       Printf("Finite bin correction: %f", finiteBinCorrection);
+       mixedNorm /= finiteBinCorrection;
+       mixedNormError /= finiteBinCorrection;
+      }
+      else
+      {
+       Printf("ERROR: fTrackEtaCut not set. Finite bin correction cannot be applied. Continuing anyway...");
+      }
+
+      Float_t triggers = eventMixedAll->Integral(1, eventMixedAll->GetNbinsX(), multBin, multBin);
 //     Printf("%f +- %f | %f | %f", mixedNorm, mixedNormError, triggers, mixedNorm / triggers);
-    if (triggers <= 0)
-    {
-      Printf("ERROR: Skipping multiplicity %d because mixed event is empty", multBin);
-      continue;
+      if (triggers <= 0)
+      {
+       Printf("ERROR: Skipping multiplicity %d because mixed event is empty", multBin);
+       continue;
+      }
+      
+      mixedNorm /= triggers;
+      mixedNormError /= triggers;      
+      
+      delete tracksMixed;
     }
-    
-    mixedNorm /= triggers;
-    mixedNormError /= triggers;
-    
+    else
+      Printf("WARNING: Skipping mixed-event scaling! fSkipScaleMixedEvent IS set!");
+
     if (mixedNorm <= 0)
     {
       Printf("ERROR: Skipping multiplicity %d because mixed event is empty at (0,0)", multBin);
       continue;
     }
     
-    // finite bin correction
-    if (fTrackEtaCut > 0)
-    {
-      Double_t finiteBinCorrection = -1.0 / (2*fTrackEtaCut) * binWidthEta / 2 + 1;
-      Printf("Finite bin correction: %f", finiteBinCorrection);
-      mixedNorm *= finiteBinCorrection;
-      mixedNormError *= finiteBinCorrection;
-    }
-    else
-    {
-      Printf("ERROR: fTrackEtaCut not set. Finite bin correction cannot be applied. Continuing anyway...");
-    }
-    
 //     Printf("Norm: %f +- %f", mixedNorm, mixedNormError);
 
 //     normParameters->Fill(mixedNorm);
       
     TAxis* vertexAxis = trackSameAll->GetAxis(2);
-    for (Int_t vertexBin = 1; vertexBin <= vertexAxis->GetNbins(); vertexBin++)
-//     for (Int_t vertexBin = 5; vertexBin <= 6; vertexBin++)
+    Int_t vertexBinBegin = 1;
+    Int_t vertexBinEnd = vertexAxis->GetNbins();
+    
+    if (fZVtxMax > fZVtxMin)
+    {
+      vertexBinBegin = vertexAxis->FindBin(fZVtxMin);
+      vertexBinEnd = vertexAxis->FindBin(fZVtxMax);
+    }
+    
+    for (Int_t vertexBin = vertexBinBegin; vertexBin <= vertexBinEnd; vertexBin++)
     {
       trackSameAll->GetAxis(2)->SetRange(vertexBin, vertexBin);
       trackMixedAll->GetAxis(2)->SetRange(vertexBin, vertexBin);
 
       TH2* tracksSame = trackSameAll->Projection(1, 0, "E");
-      tracksMixed = trackMixedAll->Projection(1, 0, "E");
+      TH2* tracksMixed = trackMixedAll->Projection(1, 0, "E");
       
       // asssume flat in dphi, gain in statistics
       //     TH1* histMixedproj = mixedTwoD->ProjectionY();
@@ -1019,7 +1146,10 @@ TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEH
       }
       else
       {
-       tracksMixed->Scale(1.0 / triggers2 / mixedNorm);
+       if (!fSkipScaleMixedEvent)
+         tracksMixed->Scale(1.0 / triggers2 / mixedNorm);
+       else if (tracksMixed->Integral() > 0)
+         tracksMixed->Scale(1.0 / tracksMixed->Integral());
        // tracksSame->Scale(tracksMixed->Integral() / tracksSame->Integral());
          
 //     new TCanvas; tracksSame->DrawClone("SURF1");
@@ -1090,9 +1220,12 @@ TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEH
     if (sums[0] > 0)
       errors[0] /= sums[0];
     
-    Printf("Dividing %f tracks by %d events (%d correlation function(s)) (error %f)", totalTracks->Integral(), totalEvents, nCorrelationFunctions, errors[0]);
-    if (totalEvents > 0)
-      totalTracks->Scale(1.0 / totalEvents);
+    if (normalizePerTrigger)
+    {
+      Printf("Dividing %f tracks by %lld events (%d correlation function(s)) (error %f)", totalTracks->Integral(), totalEvents, nCorrelationFunctions, errors[0]);
+      if (totalEvents > 0)
+       totalTracks->Scale(1.0 / totalEvents);
+    }
   
     // normalizate to dphi width
     Float_t normalization = totalTracks->GetXaxis()->GetBinWidth(1);
@@ -1101,8 +1234,10 @@ TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEH
   
   delete trackSameAll;
   delete trackMixedAll;
+  delete trackMixedAllStep6;
   delete eventSameAll;
   delete eventMixedAll;
+  delete eventMixedAllStep6;
   
 //   new TCanvas; normParameters->Draw();
   
@@ -1111,6 +1246,30 @@ TH2* AliUEHist::GetSumOfRatios2(AliUEHist* mixed, AliUEHist::CFStep step, AliUEH
   return totalTracks;
 }
 
+TH1* AliUEHist::GetTriggersAsFunctionOfMultiplicity(AliUEHist::CFStep step, Float_t ptLeadMin, Float_t ptLeadMax)
+{
+  // returns the distribution of triggers as function of centrality/multiplicity
+
+  ResetBinLimits(fEventHist->GetGrid(step));
+  
+  Int_t firstBin = fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(ptLeadMin);
+  Int_t lastBin = fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->FindBin(ptLeadMax);
+  Printf("Using pT range %d --> %d", firstBin, lastBin);
+  fEventHist->GetGrid(step)->GetGrid()->GetAxis(0)->SetRange(firstBin, lastBin);
+
+  if (fZVtxMax > fZVtxMin)
+  {
+    fEventHist->GetGrid(step)->GetGrid()->GetAxis(2)->SetRangeUser(fZVtxMin, fZVtxMax);
+    Printf("Restricting z-vtx: %f-%f", fZVtxMin, fZVtxMax);
+  }
+  
+  TH1* eventHist = fEventHist->GetGrid(step)->Project(1);
+
+  ResetBinLimits(fEventHist->GetGrid(step));
+  
+  return eventHist;  
+}
+
 /*
 TH2* AliUEHist::GetPtDistInPhiRegion(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHist::Region region, Float_t ptLeadMin, Float_t ptLeadMax, Int_t multBinBegin, Int_t multBinEnd, Float_t phiBegin, Float_t phiEnd)
 {
@@ -1170,7 +1329,7 @@ TH2* AliUEHist::GetSumOfRatios(AliUEHist* mixed, AliUEHist::CFStep step, AliUEHi
        multIter++;
       }
        
-      Int_t nEvents = 0;
+      Long64_t nEvents = 0;
       TH2* tracks = (TH2*) GetUEHist(step, region, ptLeadMin, ptLeadMax, multBinBeginLocal, multBinEndLocal, 1, etaNorm, &nEvents);
       // undo normalization
       tracks->Scale(nEvents);
@@ -1832,6 +1991,12 @@ TH1* AliUEHist::GetTrackEfficiency(CFStep step1, CFStep step2, Int_t axis1, Int_
     sourceContainer->GetGrid(step1)->SetRangeUser(1, fPtMin, fPtMax);
     sourceContainer->GetGrid(step2)->SetRangeUser(1, fPtMin, fPtMax);
   }
+  if (fPartSpecies != -1 && axis1 != 2 && axis2 != 2 && axis3 != 2)
+  {
+    Printf("Restricted to particle species %d", fPartSpecies);
+    sourceContainer->GetGrid(step1)->SetRangeUser(2, fPartSpecies, fPartSpecies);
+    sourceContainer->GetGrid(step2)->SetRangeUser(2, fPartSpecies, fPartSpecies);
+  }
   if (fCentralityMax > fCentralityMin && axis1 != 3 && axis2 != 3 && axis3 != 3)
   {
     Printf("Restricted centrality range to %f %f", fCentralityMin, fCentralityMax);
@@ -2329,7 +2494,7 @@ TH2D* AliUEHist::GetTrackingEfficiency()
 //____________________________________________________________________
 TH2D* AliUEHist::GetFakeRate()
 {
-  return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, kCFStepReconstructed, 0, 1));
+  return dynamic_cast<TH2D*> (GetTrackEfficiency(kCFStepTracked, (CFStep) (kCFStepTracked+3), 0, 1));
 }
 
 //____________________________________________________________________
@@ -2355,7 +2520,7 @@ TH1D* AliUEHist::GetTrackingEfficiency(Int_t axis)
 //____________________________________________________________________
 TH1D* AliUEHist::GetFakeRate(Int_t axis)
 {
-  return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, kCFStepReconstructed, axis));
+  return dynamic_cast<TH1D*> (GetTrackEfficiency(kCFStepTracked, (CFStep) (kCFStepTracked+3), axis));
 }
 //____________________________________________________________________
 TH2D* AliUEHist::GetTrackingCorrection()
@@ -2560,6 +2725,85 @@ void AliUEHist::DeepCopy(AliUEHist* from)
   }
 }
 
+void AliUEHist::SymmetrizepTBins()
+{
+  // copy pt,a < pt,t bins to pt,a > pt,t (inverting deltaphi and delta eta as it should be) including symmetric bins
+  
+  for (Int_t region=0; region<4; region++)
+  {
+    if (!fTrackHist[region])
+      continue;
+  
+    for (Int_t step=0; step<fTrackHist[region]->GetNStep(); step++)
+    {
+      Printf("Copying region %d step %d", region, step);
+      THnSparse* target = fTrackHist[region]->GetGrid(step)->GetGrid();
+      if (target->GetEntries() == 0)
+       continue;
+      
+      // for symmetric bins
+      THnSparse* source = (THnSparse*) target->Clone();
+      
+      Int_t zVtxBins = 1;
+      if (target->GetNdimensions() > 5)
+       zVtxBins = target->GetAxis(5)->GetNbins();
+      
+      // axes: 0 delta eta; 1 pT,a; 2 pT,t; 3 centrality; 4 delta phi; 5 vtx-z
+      for (Int_t i3 = 1; i3 <= target->GetAxis(3)->GetNbins(); i3++)
+       for (Int_t i5 = 1; i5 <= zVtxBins; i5++)
+       {
+         for (Int_t i1 = 1; i1 <= target->GetAxis(1)->GetNbins(); i1++)
+           for (Int_t i2 = 1; i2 <= target->GetAxis(2)->GetNbins(); i2++)
+           {
+             // find source bin
+             Int_t binA = target->GetAxis(1)->FindBin(target->GetAxis(2)->GetBinCenter(i2));
+             Int_t binT = target->GetAxis(2)->FindBin(target->GetAxis(1)->GetBinCenter(i1));
+             
+             Printf("(%d %d) Copying from %d %d to %d %d", i3, i5, binA, binT, i1, i2);
+             
+             for (Int_t i0 = 1; i0 <= target->GetAxis(0)->GetNbins(); i0++)
+               for (Int_t i4 = 1; i4 <= target->GetAxis(4)->GetNbins(); i4++)
+               {
+                 Int_t binEta = target->GetAxis(0)->FindBin(-target->GetAxis(0)->GetBinCenter(i0));
+                 Double_t phi = -target->GetAxis(4)->GetBinCenter(i4);
+                 if (phi < -TMath::Pi()/2)
+                   phi += TMath::TwoPi();
+                 Int_t binPhi = target->GetAxis(4)->FindBin(phi);
+                 
+                 Int_t binSource[] = { binEta, binA, binT, i3, binPhi, i5 };
+                 Int_t binTarget[] = { i0, i1, i2, i3, i4, i5 };
+                 
+                 Double_t value = source->GetBinContent(binSource);
+                 Double_t error = source->GetBinError(binSource);
+                 
+                 if (error == 0)
+                   continue;
+                 
+                 Double_t value2 = target->GetBinContent(binTarget);
+                 Double_t error2 = target->GetBinError(binTarget);
+                 
+                 Double_t sum = value;
+                 Double_t err = error;
+                 
+                 if (error2 > 0)
+                 {
+                   sum = value + value2;
+                   err = TMath::Sqrt(error * error + error2 * error2);
+                 }
+
+                 // Printf("  Values: %f +- %f; %f +- %f --> %f +- %f", value, error, value2, error2, sum, err);
+                 
+                 target->SetBinContent(binTarget, sum);
+                 target->SetBinError(binTarget, err);
+               }
+           }
+       }
+       
+       delete source;
+    }
+  }
+}
+
 //____________________________________________________________________
 void AliUEHist::ExtendTrackingEfficiency(Bool_t verbose)
 {