]> 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 e5ef76804aea4357d863e4f55c489c7886f21c8b..18e396589474ad913af2a780f5266bda898934ab 100644 (file)
@@ -51,14 +51,17 @@ AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
   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),
@@ -81,13 +84,18 @@ AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
     
   // 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
-  trackBins[0] = GetBinning(binning, "eta", iTrackBin[0]);
-  trackAxisTitle[0] = "#eta";
+  Int_t nEtaBins = -1;
+  Double_t* etaBins = GetBinning(binning, "eta", nEtaBins);
+  const char* etaTitle = "#eta";
+  
+  iTrackBin[0] = nEtaBins;
+  trackBins[0] = etaBins;
+  trackAxisTitle[0] = etaTitle;
   
   // delta eta
   Int_t nDeltaEtaBins = -1;
@@ -156,6 +164,15 @@ AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
     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));
   
@@ -208,10 +225,37 @@ AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
       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);
@@ -227,19 +271,23 @@ AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
   
   // 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]);
@@ -248,21 +296,27 @@ AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
   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[0] = nEtaBins;
   iTrackBin[1] = npTBinsFine;
   iTrackBin[2] = kNSpeciesBins;
   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);
@@ -282,7 +336,30 @@ AliUEHist::AliUEHist(const char* reqHist, const char* binning) :
   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>
@@ -330,14 +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),
@@ -433,10 +513,12 @@ 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());
@@ -444,6 +526,7 @@ void AliUEHist::Copy(TObject& c) const
   target.fCombineMinMax = fCombineMinMax;
   target.fTrackEtaCut = fTrackEtaCut;
   target.fWeightPerEvent = fWeightPerEvent;
+  target.fSkipScaleMixedEvent = fSkipScaleMixedEvent;
   target.fHistogramType = fHistogramType;
 }
 
@@ -514,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);
 }  
 
 //____________________________________________________________________
@@ -823,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;
   }
@@ -839,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");
@@ -849,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 + ... ]
@@ -862,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());
   
@@ -900,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();
@@ -997,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");
@@ -1068,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);
@@ -1079,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();
   
@@ -1089,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)
 {
@@ -1810,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);
@@ -2307,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));
 }
 
 //____________________________________________________________________
@@ -2333,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()
@@ -2538,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)
 {