]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
TPC rdEdx analysis code, macros and more (P.Christiansen)
authorrpreghen <rpreghen@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 11 May 2012 12:32:42 +0000 (12:32 +0000)
committerrpreghen <rpreghen@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 11 May 2012 12:32:42 +0000 (12:32 +0000)
50 files changed:
PWGLF/SPECTRA/IdentifiedHighPt/README.txt [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/corrected_fraction/corrected_fraction.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/corrected_fraction/syst_vs_pt.root [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/efficiency/createEfficiency.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_phojet.root [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_pythia.root [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_2.76TeV.root [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_7TeV.root [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_900GeV.root [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/convertToMyBins.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/makeSpectra.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/AddTaskHighPtDeDx.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/AddTaskHighPtDeDxV0.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDx.cxx [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDx.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDxV0.cxx [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDxV0.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/CreateAlienHandler.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/DebugClasses.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/DebugClasses_C.d [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/HighPtDeDx_lhc10b_Data_ESDs_merge.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/HighPtDeDx_lhc10c_Data_ESDs_merge.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/ListDirectories.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/copyStatisticFiles.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/lhc10b.conf [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/macro_HighPtDeDx_lhc10b_Data_ESDs.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/runAAF.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/grid/test_esd.txt [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBase.cxx [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBase.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBaseCint.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxCalib.cxx [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxCalib.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxData.cxx [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxData.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxMc.cxx [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxMc.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxSpectra.cxx [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxSpectra.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/Include.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/LinkDef.h [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/lib/Makefile [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/calibrate_de_dx.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/drawText.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/draw_separation.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/fit_yields_final.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/fit_yields_old.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/my_functions.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/my_tools.C [new file with mode: 0644]
PWGLF/SPECTRA/IdentifiedHighPt/macros/run_code.C [new file with mode: 0644]

diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/README.txt b/PWGLF/SPECTRA/IdentifiedHighPt/README.txt
new file mode 100644 (file)
index 0000000..25adb1e
--- /dev/null
@@ -0,0 +1,79 @@
+The idea is to document the different steps needed to make spectra.
+
+STEP 1: GRID CODE
+=================
+
+In the directory grid you will find the code used to produce the trees. For
+info on how to use have a look at runAAF.C
+
+STEP 2: EXTRACT TREES
+=====================
+
+The file produced on the grid contains the trees in the list. This means that
+one cannot direcrtly chain tghem. Therefore we use the code in extract_code to
+make new files with the trees only.
+
+Example:
+./merge.sh aortizve/Trees_LHC10b_Pass3/files/
+and 
+./merge.sh aortizve/Trees_LHC10b_Pass3/files/ HighPtDeDxV0
+
+STEP 3: COMPILE LIBRARY
+=======================
+
+cd lib
+make clean
+make
+
+
+STEP 4: DETERMINE RATIOS
+========================
+
+This is the biggest step.
+
+mkdir ratios_7tevb
+cd ratios_7tevb
+
+First we need to create the text files we want to analyze.
+Example:
+find /home/pchristi/work/analysis/7tev/ | grep HighPtDeDx_Tree | grep new | grep 117059 > 7tev_b_test.dat
+find /home/pchristi/work/analysis/7tev/ | grep HighPtDeDx_Tree | grep new > 7tev_b.dat
+
+find /home/pchristi/work/analysis/7tev/ | grep HighPtDeDxV0_Tree | grep new | grep 117059 > 7tev_b_test_v0.dat
+find /home/pchristi/work/analysis/7tev/ | grep HighPtDeDxV0_Tree | grep new > 7tev_b_v0.dat
+
+ln -s ../macros/run_code.C .
+ln -s ../macros/calibrate_de_dx.C .
+
+cp ../macros/drawText.C .
+Edit the text here. This macro is used to tag the pictures.
+
+Follow the example in the macro run_code.C
+
+Step 1-5 is about determining the dE/dx calibrations and the input data to the
+fits in pT.
+
+Now it is time for extracting the uncorrected ratios.
+
+ln -s ../macros/fit_yields_final.C .
+
+This is documented in fit_yields_final.C
+
+
+There is still things missing:
+- Option to generate tree when generating the data.
+- The code to estimate systematic errors
+- Efficiency code
+- Corrected fractions
+- Spectra and RAA code
+
+But that will come soon - hopefully next week.
+
+
+
+
+To zip:
+
+ls -1 README.txt lib/Makefile lib/*.cxx lib/*.h macros/*.C > tozip.txt
+tar -hcvzf analysis.tgz -T tozip.txt
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/corrected_fraction/corrected_fraction.C b/PWGLF/SPECTRA/IdentifiedHighPt/corrected_fraction/corrected_fraction.C
new file mode 100644 (file)
index 0000000..ef070b3
--- /dev/null
@@ -0,0 +1,195 @@
+#include <TFile.h>
+#include <TH1.h>
+#include <TF1.h>
+#include <TCanvas.h>
+#include <TList.h>
+#include <TLegend.h>
+#include <TStyle.h>
+#include <TMath.h>
+#include <TSystem.h>
+#include <TLatex.h>
+
+#include "my_tools.C"
+
+
+/*
+  Info:
+  * Efficiencies are currently set by hand!!!!!
+  * Systematic errors needs an update also.
+  * Need to accomodate k+p at soem point!
+
+  To run:
+  
+  gSystem->AddIncludePath("-I../macros")
+  gSystem->AddIncludePath("-I../lib")
+  gROOT->SetMacroPath(".:../macros")
+  .L my_tools.C++
+  .L corrected_fraction.C+
+  
+  
+  CorrectedFraction("../ratios_7tevb/fit_yields_results/7tev_b.root", "fraction_7tev_b_pi.root", 1, "PP", 0, 10.0);
+  CorrectedFraction("../ratios_7tevb/fit_yields_results/7tev_b.root", "fraction_7tev_b_k.root", 2, "PP", 0, 10.0);
+  CorrectedFraction("../ratios_7tevb/fit_yields_results/7tev_b.root", "fraction_7tev_b_p.root", 3, "PP", 0, 10.0);
+
+
+  And in the shell one can add files like:
+  
+  hadd fraction_7tev_b_all.root fraction_7tev_b_pi.root fraction_7tev_b_k.root fraction_7tev_b_p.root
+
+ */
+
+void CorrectedFraction(const Char_t* inFileName, const Char_t* outFileName, Int_t pid, 
+                      const Char_t* endName="PP", Int_t centBin=0, 
+                      Double_t ptMax=20.0, const Char_t* outDir="plots");
+TH1D* GetSystErrorHist(TH1D* hRatio, Int_t centBin, TF1* electronFraction);
+
+
+//________________________________________________________________________________________
+void CorrectedFraction(const Char_t* inFileName, const Char_t* outFileName, Int_t pid, 
+                  const Char_t* endName, Int_t centBin, 
+                  Double_t ptMax, const Char_t* outDir)
+{
+  gStyle->SetOptStat(0);
+  
+  
+  TFile* fileData = FindFileFresh(inFileName);
+
+  if(!fileData)
+    return;
+  
+  TF1*  fElectronFraction   = (TF1*)fileData->Get("fElectronFraction");
+  cout << "Electron fraction found!" << endl;
+  TH1D* hPionRatio   = 0;
+  if(pid==1) {
+    hPionRatio = (TH1D*)fileData->Get("hPionRatio");
+    CutHistogram(hPionRatio, 2.0, ptMax);
+    hPionRatio->SetMarkerStyle(24);
+  } else if(pid==2) {
+    hPionRatio = (TH1D*)fileData->Get("hKaonRatio");
+    CutHistogram(hPionRatio, 3.0, ptMax);
+    hPionRatio->SetMarkerStyle(25);
+  } else if(pid==3) {
+    hPionRatio = (TH1D*)fileData->Get("hProtonRatio");
+    CutHistogram(hPionRatio, 3.0, ptMax);
+    hPionRatio->SetMarkerStyle(25);
+  }
+
+  // Global variable
+  TH1D* hSystFraction = 0;
+  if(pid==1)
+    hSystFraction =  GetSystErrorHist(hPionRatio, centBin, fElectronFraction);
+  else
+    hSystFraction =  GetSystErrorHist(hPionRatio, centBin, 0);
+  hSystFraction->SetLineColor(1);
+  hSystFraction->SetMarkerStyle(1);
+  hSystFraction->SetFillStyle(1001);
+  hSystFraction->SetFillColor(kGray);
+
+  TH1D* hPionFraction = (TH1D*)hPionRatio->Clone("hPionFraction");
+  if(pid==1 && !fElectronFraction) {
+    TF1 f1("f1", "1.0", 0.0, 50.0);
+    cout << "NO ELECTRON FRACTION!!!" << endl;
+    hPionFraction->Add(&f1, -0.01); // correct for muons and electrons
+    CutHistogram(hPionFraction, 3.0, ptMax);
+    hSystFraction->Add(&f1, -0.01); // correct for muons and electrons
+    CutHistogram(hSystFraction, 3.0, ptMax);
+  }
+
+  if(pid==1 || pid ==3) {
+
+    hPionFraction->Scale(0.94); // correct for efficiency ratio
+    hSystFraction->Scale(0.94); // correct for efficiency ratio
+  } else {
+
+    TF1* effRatioK = new TF1("effRatioK", "exp(-[1]*x)+[0]", 0.0, 50.0);
+    effRatioK->SetParameters(9.82065e-01, 1.28157e+00);
+    hPionFraction->Multiply(effRatioK); // correct for efficiency ratio
+    hSystFraction->Multiply(effRatioK); // correct for efficiency ratio
+  }
+
+  if(pid==1)
+    hPionFraction->SetMarkerStyle(20);
+  else
+    hPionFraction->SetMarkerStyle(20);
+  TLatex latex;
+  latex.SetNDC();
+  latex.SetTextSize(0.05);
+
+  TCanvas* cRatios = new TCanvas("cRatios", "Particle fractions");
+  cRatios->Clear();
+  hSystFraction->GetXaxis()->SetRangeUser(0, ptMax);
+  hSystFraction->GetYaxis()->SetRangeUser(0, 1);
+  hSystFraction->Draw("E5");
+  hPionRatio->Draw("SAME");
+  hPionFraction->Draw("SAME");
+  latex.DrawLatex(0.6, 0.95, Form("%s", endName));
+  
+  CreateDir(outDir);
+  if(pid==1) {
+    hPionFraction->SetName(Form("hPionFraction_%s", endName));
+    hSystFraction->SetName(Form("hPionFractionSyst_%s", endName));
+    cRatios->SaveAs(Form("%s/fractions_%s_pions.gif", outDir, endName));
+  } else if (pid==2) {
+    hPionFraction->SetName(Form("hKaonFraction_%s", endName));
+    hSystFraction->SetName(Form("hKaonFractionSyst_%s", endName));
+    cRatios->SaveAs(Form("%s/fractions_%s_kaons.gif", outDir, endName));
+  } else if (pid==3) {
+    hPionFraction->SetName(Form("hProtonFraction_%s", endName));
+    hSystFraction->SetName(Form("hProtonFractionSyst_%s", endName));
+    cRatios->SaveAs(Form("%s/fractions_%s_protons.gif", outDir, endName));
+  }
+
+  TFile* outFile = new TFile(outFileName, "RECREATE");
+  hPionFraction->Write();
+  hSystFraction->Write();
+  outFile->Close();
+}
+
+//__________________________________________________________________________________
+TH1D* GetSystErrorHist(TH1D* hRatio, Int_t centBin, TF1* electronFraction)
+{
+  TFile* fileSyst = FindFile("syst_vs_pt.root");
+  
+  TF1* fSyst = (TF1*)fileSyst->Get(Form("systHigh%d", centBin));
+  fSyst->SetRange(2.0, 20.0);
+  fSyst->Print();
+  
+  Double_t syst_error_mc = 0.03; // pp
+  if (centBin>0)
+    syst_error_mc = 0.05; // Pb+Pb
+  
+  Double_t syst_error_correction = 0.01; // pp
+  if (centBin>0)
+    syst_error_correction = 0.03; // Pb+Pb
+
+  TH1D* hSystError = (TH1D*)hRatio->Clone("hPionFractionSyst");
+  hSystError->Multiply(fSyst);
+
+  const Int_t nBins = hSystError->GetNbinsX();
+  for(Int_t bin = 1; bin <= nBins; bin++) {
+  
+    Double_t value      = hRatio->GetBinContent(bin);
+    Double_t stat_error = hSystError->GetBinContent(bin);
+
+    if(value==0)
+      continue;
+
+    Double_t syst_error = stat_error*stat_error;
+    syst_error += value*value*syst_error_mc*syst_error_mc;
+    syst_error += value*value*syst_error_correction*syst_error_correction;
+    
+    
+    if (electronFraction) {
+      
+      Double_t systEandMu = electronFraction->Eval(hRatio->GetXaxis()->GetBinCenter(bin));
+      syst_error += systEandMu*systEandMu;
+    }
+
+    syst_error = TMath::Sqrt(syst_error);
+    hSystError->SetBinContent(bin, value);
+    hSystError->SetBinError(bin, syst_error);
+  }
+
+  return hSystError;
+}
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/corrected_fraction/syst_vs_pt.root b/PWGLF/SPECTRA/IdentifiedHighPt/corrected_fraction/syst_vs_pt.root
new file mode 100644 (file)
index 0000000..bbfe6da
Binary files /dev/null and b/PWGLF/SPECTRA/IdentifiedHighPt/corrected_fraction/syst_vs_pt.root differ
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/createEfficiency.C b/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/createEfficiency.C
new file mode 100644 (file)
index 0000000..1b48ea7
--- /dev/null
@@ -0,0 +1,697 @@
+#include <TFile.h>
+#include <TH1.h>
+#include <TF1.h>
+#include <TCanvas.h>
+#include <TAxis.h>
+#include <TStyle.h>
+#include <TChain.h>
+#include <TTree.h>
+#include <TMath.h>
+#include <TClonesArray.h>
+#include <TLegend.h>
+
+#include <AliXRDPROOFtoolkit.h>
+
+#include "DebugClasses.C"
+#include "my_tools.C"
+
+#include <iostream>
+
+using namespace std;
+
+/*
+  To run code:
+  ============
+
+  Info:
+  * I did not recheck this code. For now I would just use the efficiency values I have.
+  * The code could be made nicer. Esepcially some plots could be put in folders.
+
+  Use AliRoot because of AliXRDPROOFtoolkit:
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TPC")
+  gSystem->AddIncludePath("-I../lib")
+  gSystem->AddIncludePath("-I../grid")
+  gSystem->AddIncludePath("-I../macros")
+  gROOT->SetMacroPath(".:../macros:../grid:../lib/")
+  .L my_tools.C+
+  .L DebugClasses.C+
+  .L createEfficiency.C+
+
+  Examples of visualization:
+  DrawEfficiency("lhc10d_eff_pythia.root", "eff.root")
+
+  // This is the correction I did for the low pT guys
+  DrawCorrection("lhc10d_eff_pythia.root", "lhc10d_eff_phojet.root")
+
+
+
+  CreateEff("lhc10d_mc_all.dat", 0, "lhc10d_eff_all.root")
+
+  
+*/
+
+void DrawEfficiency(const Char_t* fileName, const Char_t* effFileName);
+void DrawCorrection(const Char_t* fileNamePYTHIA, const Char_t* fileNamePHOJET);
+TH1D* HistInvert(TH1D* hist);
+
+
+void CreateEff(const Char_t* mcFileName, Int_t maxEvents, const Char_t* mcOutFileName,
+              Float_t centLow=-20, Float_t centHigh=-5)
+{  
+  gStyle->SetOptStat(0);
+  //
+  // Create output
+  //
+  TFile* outFile = new TFile(mcOutFileName, "RECREATE");
+
+  const Int_t nPid = 7;
+  TH1D* hMcIn[nPid]     = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcOut[nPid]    = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcSec[nPid]    = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcEff[nPid]     = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcInNeg[nPid]  = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcOutNeg[nPid] = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcSecNeg[nPid] = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcEffNeg[nPid]     = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcInPos[nPid]  = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcOutPos[nPid] = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcSecPos[nPid] = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hMcEffPos[nPid]     = {0, 0, 0, 0, 0, 0, 0 };
+
+  Int_t color[nPid] = {1, 2, 3, 4, 5, 1, 1};
+
+  const Int_t nPtBins = 68;
+  Double_t xBins[nPtBins+1] = {0. ,  0.05, 0.1,  0.15, 0.2,  0.25, 0.3,  0.35, 0.4,  0.45,
+                              0.5,  0.55, 0.6,  0.65, 0.7,  0.75, 0.8,  0.85, 0.9,  0.95,
+                              1.0,  1.1 , 1.2,  1.3 , 1.4,  1.5 , 1.6,  1.7 , 1.8,  1.9 ,
+                              2.0,  2.2 , 2.4,  2.6 , 2.8,  3.0 , 3.2,  3.4 , 3.6,  3.8 ,
+                              4.0,  4.5 , 5.0,  5.5 , 6.0,  6.5 , 7.0,  8.0 , 9.0,  10.0,
+                              11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0, 22.0, 24.0,
+                              26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 40.0, 45.0, 50.0 };
+  
+  for(Int_t pid = 0; pid < nPid; pid++) {
+    
+    hMcIn[pid] = new TH1D(Form("hIn%d", pid), Form("Efficiency (pid %d)", pid), 
+                         nPtBins, xBins); 
+    hMcInNeg[pid] = new TH1D(Form("hInNeg%d", pid), Form("Efficiency (pid %d, q < 0)", pid), 
+                            nPtBins, xBins); 
+    hMcInPos[pid] = new TH1D(Form("hInPos%d", pid), Form("Efficiency (pid %d, q < 0)", pid), 
+                            nPtBins, xBins); 
+
+    hMcIn[pid]->Sumw2();
+    hMcIn[pid]->SetMarkerStyle(29);
+    hMcIn[pid]->SetMarkerColor(color[pid]);
+    hMcInNeg[pid]->Sumw2();
+    hMcInNeg[pid]->SetMarkerStyle(24);
+    hMcInNeg[pid]->SetMarkerColor(color[pid]);
+    hMcInPos[pid]->Sumw2();
+    hMcInPos[pid]->SetMarkerStyle(20);
+    hMcInPos[pid]->SetMarkerColor(color[pid]);
+
+    hMcOut[pid] = new TH1D(Form("hMcOut%d", pid), Form("MC out (pid %d)", pid), 
+                          nPtBins, xBins); 
+    hMcOutNeg[pid] = new TH1D(Form("hMcOutNeg%d", pid), Form("MC out (pid %d, q < 0)", pid), 
+                             nPtBins, xBins); 
+    hMcOutPos[pid] = new TH1D(Form("hMcOutPos%d", pid), Form("MC out (pid %d, q < 0)", pid), 
+                             nPtBins, xBins); 
+
+    hMcOut[pid]->Sumw2();
+    hMcOut[pid]->SetMarkerStyle(29);
+    hMcOut[pid]->SetMarkerColor(color[pid]);
+    hMcOutNeg[pid]->Sumw2();
+    hMcOutNeg[pid]->SetMarkerStyle(24);
+    hMcOutNeg[pid]->SetMarkerColor(color[pid]);
+    hMcOutPos[pid]->Sumw2();
+    hMcOutPos[pid]->SetMarkerStyle(20);
+    hMcOutPos[pid]->SetMarkerColor(color[pid]);
+
+    hMcSec[pid] = new TH1D(Form("hSec%d", pid), Form("Secondaries (pid %d)", pid), 
+                         nPtBins, xBins); 
+    hMcSecNeg[pid] = new TH1D(Form("hSecNeg%d", pid), Form("Secondaries (pid %d, q < 0)", pid), 
+                            nPtBins, xBins); 
+    hMcSecPos[pid] = new TH1D(Form("hSecPos%d", pid), Form("Secondaries (pid %d, q < 0)", pid), 
+                            nPtBins, xBins); 
+
+    hMcSec[pid]->Sumw2();
+    hMcSec[pid]->SetMarkerStyle(29);
+    hMcSec[pid]->SetMarkerColor(color[pid]);
+    hMcSecNeg[pid]->Sumw2();
+    hMcSecNeg[pid]->SetMarkerStyle(24);
+    hMcSecNeg[pid]->SetMarkerColor(color[pid]);
+    hMcSecPos[pid]->Sumw2();
+    hMcSecPos[pid]->SetMarkerStyle(20);
+    hMcSecPos[pid]->SetMarkerColor(color[pid]);
+
+    hMcEff[pid] = new TH1D(Form("hEff%d", pid), Form("Efficiency (pid %d)", pid), 
+                         nPtBins, xBins); 
+    hMcEffNeg[pid] = new TH1D(Form("hEffNeg%d", pid), Form("Efficiency (pid %d, q < 0)", pid), 
+                            nPtBins, xBins); 
+    hMcEffPos[pid] = new TH1D(Form("hEffPos%d", pid), Form("Efficiency (pid %d, q < 0)", pid), 
+                            nPtBins, xBins); 
+
+    hMcEff[pid]->Sumw2();
+    hMcEff[pid]->SetMarkerStyle(29);
+    hMcEff[pid]->SetMarkerColor(color[pid]);
+    hMcEffNeg[pid]->Sumw2();
+    hMcEffNeg[pid]->SetMarkerStyle(24);
+    hMcEffNeg[pid]->SetMarkerColor(color[pid]);
+    hMcEffPos[pid]->Sumw2();
+    hMcEffPos[pid]->SetMarkerStyle(20);
+    hMcEffPos[pid]->SetMarkerColor(color[pid]);
+  }
+      
+  TTree* Tree   = 0;
+  if(strstr(mcFileName, ".dat")) {
+    
+    AliXRDPROOFtoolkit tool;
+    TChain* chain = tool.MakeChain(mcFileName,"tree", 0, 1000);
+    chain->Lookup();
+    Tree = chain;
+  } else {
+    TFile* mcFile = FindFileFresh(mcFileName);
+    if(!mcFile)
+      return;
+    
+    Tree = (TTree*)mcFile->Get("tree");
+  }
+  if(!Tree)
+    return;
+  
+  
+  DeDxEvent* event = 0;
+  TClonesArray* trackArray = 0;
+  TClonesArray* mcTrackArray = 0;
+  Tree->SetBranchAddress("event", &event);
+  Tree->SetBranchAddress("track"  , &trackArray);
+  Tree->SetBranchAddress("trackMC"  , &mcTrackArray);
+  Int_t nEvents = Tree->GetEntries();
+  cout << "Number of events: " << nEvents << endl;
+  
+  if(maxEvents>0 && maxEvents < nEvents) {
+    
+    nEvents = maxEvents;
+    cout << "N events was reduced to: " << maxEvents << endl;
+  }
+  
+  Int_t currentRun = 0;
+
+  for(Int_t n = 0; n < nEvents; n++) {
+    
+    Tree->GetEntry(n);
+    
+    if((n+1)%1000000==0)
+      cout << "Event: " << n+1 << "/" << nEvents << endl;
+    
+    if(event->run != currentRun) {
+      
+      cout << "New run: " << event->run << endl;
+      currentRun = event->run;
+    }
+
+    if(event->cent < centLow || event->cent > centHigh)
+      continue;
+
+    const Int_t nMcTracks = mcTrackArray->GetEntries();
+      
+    for(Int_t i = 0; i < nMcTracks; i++) {
+       
+      DeDxTrackMC* trackMC = (DeDxTrackMC*)mcTrackArray->At(i);
+
+      // if(TMath::Abs(trackMC->pdgMC)==3312 || TMath::Abs(trackMC->pdgMC)==3334) 
+      //       continue; // Xi-!
+       
+      hMcIn[0]->Fill(trackMC->ptMC);
+      hMcIn[trackMC->pidMC]->Fill(trackMC->ptMC);
+       
+      if(trackMC->qMC < 0) {
+         
+       hMcInNeg[0]->Fill(trackMC->ptMC);
+       hMcInNeg[trackMC->pidMC]->Fill(trackMC->ptMC);
+      } else {
+         
+       hMcInPos[0]->Fill(trackMC->ptMC);
+       hMcInPos[trackMC->pidMC]->Fill(trackMC->ptMC);
+      }
+    }
+
+    const Int_t nTracks = trackArray->GetEntries();
+      
+    for(Int_t i = 0; i < nTracks; i++) {
+       
+      DeDxTrack* track = (DeDxTrack*)trackArray->At(i);
+       
+      if(!(track->filter&1))
+       continue;
+      
+      // if(TMath::Abs(track->mother)==3312 || TMath::Abs(track->mother)==3334) 
+      //       continue; // Xi+- or Omega+-!
+
+      hMcOut[0]->Fill(track->pt);
+      hMcOut[track->pid]->Fill(track->pt);
+       
+      if(track->q < 0) {
+         
+       hMcOutNeg[0]->Fill(track->pt);
+       hMcOutNeg[track->pid]->Fill(track->pt);
+      } else {
+         
+       hMcOutPos[0]->Fill(track->pt);
+       hMcOutPos[track->pid]->Fill(track->pt);
+      }
+       
+      if(track->primary==0) {
+       hMcSec[0]->Fill(track->pt);
+       hMcSec[track->pid]->Fill(track->pt);
+         
+       if(track->q < 0) {
+           
+         hMcSecNeg[0]->Fill(track->pt);
+         hMcSecNeg[track->pid]->Fill(track->pt);
+       } else {
+           
+         hMcSecPos[0]->Fill(track->pt);
+         hMcSecPos[track->pid]->Fill(track->pt);
+       }
+      }
+    }
+  }
+
+  TH1D* hMcInPiKP = (TH1D*)hMcIn[1]->Clone("hMcInPiKP");
+  hMcInPiKP->Add(hMcIn[2]);
+  hMcInPiKP->Add(hMcIn[3]);
+  hMcInPiKP->Divide(hMcIn[0]);
+
+  for(Int_t pid = 0; pid < nPid; pid++) {
+    
+    hMcSec[pid]->Divide(hMcSec[pid], hMcOut[pid]); 
+    hMcSecNeg[pid]->Divide(hMcSecNeg[pid], hMcOutNeg[pid]); 
+    hMcSecPos[pid]->Divide(hMcSecPos[pid], hMcOutPos[pid]); 
+
+    hMcEff[pid]   ->Divide(hMcOut[pid], hMcIn[pid]); 
+    hMcEffNeg[pid]->Divide(hMcOutNeg[pid], hMcInNeg[pid]); 
+    hMcEffPos[pid]->Divide(hMcOutPos[pid], hMcInPos[pid]); 
+  }
+
+  outFile->Write();
+  outFile->Close();  
+}
+
+//_______________________________________________________________________
+void DrawEfficiency(const Char_t* fileName, const Char_t* effFileName)
+{
+  TFile* file = FindFileFresh(fileName);
+  if(!file)
+    return;
+  
+  gStyle->SetOptStat(0);
+
+  const Double_t ptmin  =  3.01;
+  const Double_t ptmax  = 19.999;
+  //  const Double_t ptmax  = 49.999;
+  
+  const Double_t effmin = 0.6;
+  const Double_t effmax = 0.9;
+
+  // const Double_t effmin = 0.0;
+  // const Double_t effmax = 1.5;
+
+  const Double_t secmin = 0.0;
+  const Double_t secmax = 0.1;
+
+  const Int_t nPid = 7;
+
+  TH1D* hEff[nPid]     = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hEffNeg[nPid]  = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hEffPos[nPid]  = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hSec[nPid]    = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hSecNeg[nPid] = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hSecPos[nPid] = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hOut[nPid]    = {0, 0, 0, 0, 0, 0, 0 };
+
+  for(Int_t pid = 0; pid < nPid; pid++) {
+
+    hEff[pid] = (TH1D*)file->Get(Form("hEff%d", pid));
+
+    hEffNeg[pid] = (TH1D*)file->Get(Form("hEffNeg%d", pid));
+
+    hEffPos[pid] = (TH1D*)file->Get(Form("hEffPos%d", pid));
+
+    hSec[pid] = (TH1D*)file->Get(Form("hSec%d", pid));
+
+    hSecNeg[pid] = (TH1D*)file->Get(Form("hSecNeg%d", pid));
+
+    hSecPos[pid] = (TH1D*)file->Get(Form("hSecPos%d", pid));
+
+    hOut[pid] = (TH1D*)file->Get(Form("hMcOut%d", pid));
+
+    // hEff[pid]->Rebin(4);
+    // hEffNeg[pid]->Rebin(4);
+    // hEffPos[pid]->Rebin(4);
+
+    // hSec[pid]->Rebin(4);
+    // hSecNeg[pid]->Rebin(4);
+    // hSecPos[pid]->Rebin(4);
+
+    // hOut[pid]->Rebin(4);
+
+    // hEff[pid]->Scale(0.25);
+    // hEffNeg[pid]->Scale(0.25);
+    // hEffPos[pid]->Scale(0.25);
+
+    // hSec[pid]->Scale(0.25);
+    // hSecNeg[pid]->Scale(0.25);
+    // hSecPos[pid]->Scale(0.25);
+
+    // hOut[pid]->Scale(0.25);
+
+    hEff[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hEff[pid]->GetYaxis()->SetRangeUser(effmin, effmax);
+    hEffNeg[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hEffNeg[pid]->GetYaxis()->SetRangeUser(effmin, effmax);
+    hEffPos[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hEffPos[pid]->GetYaxis()->SetRangeUser(effmin, effmax);
+    hSec[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hSec[pid]->GetYaxis()->SetRangeUser(secmin, secmax);
+    hSecNeg[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hSecNeg[pid]->GetYaxis()->SetRangeUser(secmin, secmax);
+    hSecPos[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hSecPos[pid]->GetYaxis()->SetRangeUser(secmin, secmax);
+    hOut[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+  }
+
+  TCanvas* cChEff = new TCanvas("cChEff", "All efficiency", 800, 300);
+  cChEff->Clear();
+  cChEff->Divide(2, 1);
+  cChEff->cd(1);
+  //  TF1* pionEff = new TF1("pionEff", "pol0", 0.0, 50.0);
+  TF1* chEff = new TF1("chEff", "[0]*(1-[1]/x)", 0.0, 50.0);
+  chEff->SetLineColor(1);
+  chEff->SetParameters(0.7, 0.5);
+  hEff[0]->Fit(chEff, "", "", ptmin, ptmax);
+  
+  cChEff->cd(2);
+  hEffPos[0]->Draw();
+  hEffNeg[0]->Draw("SAME");
+  chEff->DrawCopy("SAME");
+  cChEff->SaveAs("eff_charged.gif");
+
+  TCanvas* cPionEff = new TCanvas("cPionEff", "Pion efficiency", 800, 300);
+  cPionEff->Clear();
+  cPionEff->Divide(2, 1);
+  cPionEff->cd(1);
+  //  TF1* pionEff = new TF1("pionEff", "pol0", 0.0, 50.0);
+  TF1* pionEff = new TF1("pionEff", "[0]*(1-[1]/x)", 0.0, 50.0);
+  pionEff->SetLineColor(2);
+  pionEff->SetParameters(0.7, 0.5);
+  hEff[1]->Fit(pionEff, "", "", ptmin, ptmax);
+  
+  cPionEff->cd(2);
+  hEffPos[1]->Draw();
+  hEffNeg[1]->Draw("SAME");
+  pionEff->DrawCopy("SAME");
+  cPionEff->SaveAs("eff_pion.gif");
+
+  TCanvas* cKaonEff = new TCanvas("cKaonEff", "Kaon efficiency", 800, 300);
+  cKaonEff->Clear();
+  cKaonEff->Divide(2, 1);
+  cKaonEff->cd(1);
+  //  TF1* kaonEff = new TF1("kaonEff", "pol0", 0.0, 50.0);
+  TF1* kaonEff = new TF1("kaonEff", "[0]*(1-[1]/x)", 0.0, 50.0);
+  kaonEff->SetLineColor(3);
+  kaonEff->SetParameters(0.7, 0.5);
+  hEff[2]->Fit(kaonEff, "", "", ptmin, ptmax);
+  
+  cKaonEff->cd(2);
+  hEffPos[2]->Draw();
+  hEffNeg[2]->Draw("SAME");
+  kaonEff->DrawCopy("SAME");
+  cKaonEff->SaveAs("eff_kaon.gif");
+
+  TCanvas* cProtonEff = new TCanvas("cProtonEff", "Proton efficiency", 800, 300);
+  cProtonEff->Clear();
+  cProtonEff->Divide(2, 1);
+  cProtonEff->cd(1);
+  //  TF1* protonEff = new TF1("protonEff", "pol0", 0.0, 50.0);
+  TF1* protonEff = new TF1("protonEff", "[0]*(1-[1]/x)", 0.0, 50.0);
+  protonEff->SetLineColor(4);
+  protonEff->SetParameters(0.7, 0.5);
+  hEff[3]->Fit(protonEff, "", "", ptmin, ptmax);
+  
+  cProtonEff->cd(2);
+  hEffPos[3]->Draw();
+  hEffNeg[3]->Draw("SAME");
+  protonEff->DrawCopy("SAME");
+  cProtonEff->SaveAs("eff_proton.gif");
+
+  TCanvas* cAllEff = new TCanvas("cAllEff", "All efficiency", 400, 300);
+  cAllEff->Clear();
+  
+  TH1D* hDummy = (TH1D*)hEff[1]->Clone("hDummy");
+  hDummy->Reset();
+  hDummy->SetTitle("Efficiency vs p_{T}; p_{T} [GeV/c]; Efficiency");
+  hDummy->Draw();
+  
+  chEff->DrawCopy("SAME");
+  pionEff->DrawCopy("SAME");
+  kaonEff->DrawCopy("SAME");
+  protonEff->DrawCopy("SAME");
+  cAllEff->SaveAs("eff_all.gif");
+
+  // TCanvas* cPionSec = new TCanvas("cPionSec", "Pion sec", 800, 300);
+  // cPionSec->Clear();
+  // cPionSec->Divide(2, 1);
+  // cPionSec->cd(1);
+  // TF1* pionSec = new TF1("pionSec", "pol0", 0.0, 50.0);
+  // hSec[1]->Fit(pionSec, "", "", ptmin, ptmax);
+  
+  // cPionSec->cd(2);
+  // hSecPos[1]->Draw();
+  // hSecNeg[1]->Draw("SAME");
+  // pionSec->Draw("SAME");
+  // cPionSec->SaveAs("sec_pion.gif");
+
+  // TCanvas* cKaonSec = new TCanvas("cKaonSec", "Kaon sec", 800, 300);
+  // cKaonSec->Clear();
+  // cKaonSec->Divide(2, 1);
+  // cKaonSec->cd(1);
+  // TF1* kaonSec = new TF1("kaonSec", "pol0", 0.0, 50.0);
+  // hSec[2]->Fit(kaonSec, "", "", ptmin, ptmax);
+  
+  // cKaonSec->cd(2);
+  // hSecPos[2]->Draw();
+  // hSecNeg[2]->Draw("SAME");
+  // kaonSec->Draw("SAME");
+  // cKaonSec->SaveAs("sec_kaon.gif");
+
+  // TCanvas* cProtonSec = new TCanvas("cProtonSec", "Proton sec", 800, 300);
+  // cProtonSec->Clear();
+  // cProtonSec->Divide(2, 1);
+  // cProtonSec->cd(1);
+  // TF1* protonSec = new TF1("protonSec", "pol0", 0.0, 50.0);
+  // hSec[3]->Fit(protonSec, "", "", ptmin, ptmax);
+  
+  // cProtonSec->cd(2);
+  // hSecPos[3]->Draw();
+  // hSecNeg[3]->Draw("SAME");
+  // protonSec->Draw("SAME");
+  // cProtonSec->SaveAs("sec_proton.gif");
+
+
+  TCanvas* cEffRatioPi = new TCanvas("cEffRatioPi", "eff pi / eff all", 400, 300);
+  cEffRatioPi->Clear();
+  //  TF1* pionEff = new TF1("pionEff", "pol0", 0.0, 50.0);
+  TF1* effRatioPi = new TF1("effRatioPi", "pol0", 0.0, 50.0);
+  effRatioPi->SetLineColor(6);
+  effRatioPi->SetParameters(0.7, 0.5);
+  TH1D* hEffRatioPi = (TH1D*)hEff[1]->Clone("hEffRatioPi");
+  hEffRatioPi->SetTitle("; p_{T} [GeV/c]; #epsilon_{ch}/#epsilon_{pi}");
+  hEffRatioPi->Divide(hEff[0], hEff[1], 1, 1, "B");
+  //  hEffRatioPi->Divide(hEff[1], hEff[0]);
+  hEffRatioPi->GetXaxis()->SetRangeUser(0.0, 19.99);
+  hEffRatioPi->GetYaxis()->SetRangeUser(0.8, 1.1);
+  hEffRatioPi->SetStats(kTRUE);
+  hEffRatioPi->Fit(effRatioPi, "", "", ptmin, ptmax);
+  cEffRatioPi->SaveAs("eff_ratio_pi.gif");
+  cEffRatioPi->SaveAs("eff_ratio_pi.pdf");
+
+  TCanvas* cEffRatioK = new TCanvas("cEffRatioK", "eff K / eff all", 400, 300);
+  cEffRatioK->Clear();
+  TF1* effRatioK = new TF1("effRatioK", "exp(-[1]*x)+[0]", 0.0, 50.0);
+  effRatioK->SetParameters(1.0, 1.0);
+  effRatioK->SetLineColor(6);
+  TH1D* hEffChargedRebinned = (TH1D*)hEff[0]->Clone("hEffChargedRebinned");
+  hEffChargedRebinned->Rebin(2);
+  TH1D* hEffRatioK = (TH1D*)hEff[2]->Clone("hEffRatioK");
+  hEffRatioK->Rebin(2);
+  hEffRatioK->SetTitle("; p_{T} [GeV/c]; #epsilon_{ch}/#epsilon_{K}");
+  hEffRatioK->Divide(hEffChargedRebinned, hEffRatioK, 1, 1, "B");
+  //  hEffRatioK->Divide(hEff[1], hEff[0]);
+  hEffRatioK->GetXaxis()->SetRangeUser(0.0, 19.99);
+  hEffRatioK->GetYaxis()->SetRangeUser(0.8, 1.1);
+  hEffRatioK->SetStats(kTRUE);
+  hEffRatioK->Fit(effRatioK, "", "", ptmin, ptmax);
+  cEffRatioK->SaveAs("eff_ratio_K.gif");
+  cEffRatioK->SaveAs("eff_ratio_K.pdf");
+  TCanvas* cEffRatioP = new TCanvas("cEffRatioP", "eff p / eff all", 400, 300);
+  cEffRatioP->Clear();
+  TF1* effRatioP = new TF1("effRatioP", "pol0", 0.0, 50.0);
+  effRatioP->SetLineColor(6);
+  effRatioP->SetParameters(0.7, 0.5);
+  // TH1D* hEffChargedRebinned = (TH1D*)hEff[0]->Clone("hEffChargedRebinned");
+  // hEffChargedRebinned->Rebin(2);
+  TH1D* hEffRatioP = (TH1D*)hEff[3]->Clone("hEffRatioP");
+  hEffRatioP->Rebin(2);
+  hEffRatioP->SetTitle("; p_{T} [GeV/c]; #epsilon_{ch}/#epsilon_{p}");
+  hEffRatioP->Divide(hEffChargedRebinned, hEffRatioP, 1, 1, "B");
+  //  hEffRatioP->Divide(hEff[1], hEff[0]);
+  hEffRatioP->GetXaxis()->SetRangeUser(0.0, 19.99);
+  hEffRatioP->GetYaxis()->SetRangeUser(0.8, 1.1);
+  hEffRatioP->SetStats(kTRUE);
+  hEffRatioP->Fit(effRatioP, "", "", ptmin, ptmax);
+  cEffRatioP->SaveAs("eff_ratio_p.gif");
+  cEffRatioP->SaveAs("eff_ratio_p.pdf");
+
+
+  // TCanvas* cMuonRatio = new TCanvas("cMuonRatio", "muon / all", 400, 300);
+  // cMuonRatio->Clear();
+  // //  TF1* pionMuon = new TF1("pionMuon", "pol0", 0.0, 50.0);
+  // TF1* muonRatio = new TF1("muonRatio", "pol0", 0.0, 50.0);
+  // muonRatio->SetLineColor(1);
+  // muonRatio->SetParameter(0, 0.01);
+  // TH1D* hMuonRatio = (TH1D*)hOut[5]->Clone("hMuonRatio");
+  // hMuonRatio->SetTitle("; p_{T} [GeV/c]; muon/all");
+  // hMuonRatio->Divide(hOut[5], hOut[0], 1, 1, "B");
+  // hMuonRatio->GetYaxis()->SetRangeUser(0.0, 0.05);
+  // hMuonRatio->SetStats(kTRUE);
+  // hMuonRatio->Fit(muonRatio, "", "", ptmin, ptmax);
+  // cMuonRatio->SaveAs("muon_ratio.gif");
+  // cMuonRatio->SaveAs("muon_ratio.pdf");
+
+  // TCanvas* cElectronRatio = new TCanvas("cElectronRatio", "electron / all", 400, 300);
+  // cElectronRatio->Clear();
+  // //  TF1* pionElectron = new TF1("pionElectron", "pol0", 0.0, 50.0);
+  // TF1* electronRatio = new TF1("electronRatio", "pol0", 0.0, 50.0);
+  // electronRatio->SetLineColor(1);
+  // electronRatio->SetParameter(0, 0.01);
+  // TH1D* hElectronRatio = (TH1D*)hOut[4]->Clone("hElectronRatio");
+  // hElectronRatio->SetTitle("; p_{T} [GeV/c]; electron/all");
+  // hElectronRatio->Divide(hOut[4], hOut[0], 1, 1, "B");
+  // hElectronRatio->GetYaxis()->SetRangeUser(0.0, 0.05);
+  // hElectronRatio->SetStats(kTRUE);
+  // hElectronRatio->SetMarkerColor(6);
+  // hElectronRatio->Fit(electronRatio, "", "", ptmin, ptmax);
+  // cElectronRatio->SaveAs("electron_ratio.gif");
+  // cElectronRatio->SaveAs("electron_ratio.pdf");
+  
+
+  TFile* effFile = new TFile(effFileName, "RECREATE");
+  chEff->Write();
+  pionEff->Write();
+  kaonEff->Write();
+  protonEff->Write();
+  effFile->Close();
+}
+
+
+//_______________________________________________________________________
+void DrawCorrection(const Char_t* fileNamePYTHIA, const Char_t* fileNamePHOJET)
+{
+  TFile* filePYTHIA = FindFileFresh(fileNamePYTHIA);
+  if(!filePYTHIA)
+    return;
+
+  TFile* filePHOJET = FindFileFresh(fileNamePHOJET);
+  if(!filePHOJET)
+    return;
+  
+  gStyle->SetOptStat(0);
+
+  const Double_t ptmin  =  0.0;
+  const Double_t ptmax  = 4.999;
+  //  const Double_t ptmax  = 49.999;
+  
+  const Double_t effmin = 0.95;
+  const Double_t effmax = 1.12;
+
+  const Int_t nPid = 7;
+
+  TH1D* hInPYTHIA[nPid]     = {0, 0, 0, 0, 0, 0, 0 };
+  TH1D* hInPHOJET[nPid]     = {0, 0, 0, 0, 0, 0, 0 };
+
+  for(Int_t pid = 0; pid < nPid; pid++) {
+
+    hInPYTHIA[pid] = (TH1D*)filePYTHIA->Get(Form("hIn%d", pid));
+    hInPYTHIA[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hInPYTHIA[pid]->GetYaxis()->SetRangeUser(effmin, effmax);
+
+    hInPHOJET[pid] = (TH1D*)filePHOJET->Get(Form("hIn%d", pid));
+    hInPHOJET[pid]->GetXaxis()->SetRangeUser(ptmin, ptmax);
+    hInPHOJET[pid]->GetYaxis()->SetRangeUser(effmin, effmax);
+  }
+
+  hInPYTHIA[1]->Add(hInPYTHIA[2]);
+  hInPYTHIA[1]->Add(hInPYTHIA[3]);
+  hInPYTHIA[0]->Divide(hInPYTHIA[1], hInPYTHIA[0], 1, 1, "B");
+
+  TH1D* histPYTHIA = HistInvert(hInPYTHIA[0]);
+  histPYTHIA->SetLineColor(2);
+  histPYTHIA->SetMarkerColor(2);
+
+  hInPHOJET[1]->Add(hInPHOJET[2]);
+  hInPHOJET[1]->Add(hInPHOJET[3]);
+  hInPHOJET[0]->Divide(hInPHOJET[1], hInPHOJET[0], 1, 1, "B");
+
+  TH1D* histPHOJET = HistInvert(hInPHOJET[0]);
+  histPHOJET->SetLineColor(4);
+  histPHOJET->SetMarkerColor(4);
+
+  TCanvas* cChCorrection = new TCanvas("cChCorrection", "All efficiency", 400, 300);
+  cChCorrection->Clear();
+
+  cChCorrection->SetGridy();
+
+  histPYTHIA->GetYaxis()->SetRangeUser(effmin, effmax);
+  histPYTHIA->SetTitle("N_{ch}/(#pi + K + p) for primaries at generator level; p_{T} [GeV/c]; Ratio");
+  histPYTHIA->Draw();
+
+  histPHOJET->Draw("SAME");
+
+  TLegend* legend = new TLegend(0.55, 0.22, 0.79, 0.42);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(histPYTHIA, "PYTHIA", "P");
+  legend->AddEntry(histPHOJET, "PHOJET", "P");
+  legend->Draw();
+  
+  cChCorrection->SaveAs("charged_over_piKp.gif");
+
+  TFile* file = new TFile("correction.root", "RECREATE");
+  histPYTHIA->SetName("histPYTHIA");
+  histPHOJET->SetName("histPHOJET");
+  histPYTHIA->Write();
+  histPHOJET->Write();
+  file->Close();
+}
+
+//_______________________________________________________________________
+TH1D* HistInvert(TH1D* hist)
+{
+  TH1D* histNew = new TH1D(*hist);
+  histNew->Reset();
+  histNew->SetName(Form("%s_inv", hist->GetName()));
+  histNew->SetTitle(Form("%s (inverted)", hist->GetTitle()));
+  
+  const Int_t nBins = hist->GetNbinsX();
+  
+  for(Int_t i = 1; i <= nBins; i++) {
+    
+    if(hist->GetBinContent(i) == 0)
+      continue;
+
+    histNew->SetBinContent(i, 1.0/hist->GetBinContent(i));
+    histNew->SetBinError(i, hist->GetBinError(i)/hist->GetBinContent(i)/hist->GetBinContent(i));
+  }
+
+  return histNew;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_phojet.root b/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_phojet.root
new file mode 100644 (file)
index 0000000..94cf9cb
Binary files /dev/null and b/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_phojet.root differ
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_pythia.root b/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_pythia.root
new file mode 100644 (file)
index 0000000..7ee4a33
Binary files /dev/null and b/PWGLF/SPECTRA/IdentifiedHighPt/efficiency/lhc10d_eff_pythia.root differ
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_2.76TeV.root b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_2.76TeV.root
new file mode 100644 (file)
index 0000000..c93dc0c
Binary files /dev/null and b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_2.76TeV.root differ
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_7TeV.root b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_7TeV.root
new file mode 100644 (file)
index 0000000..3633cd4
Binary files /dev/null and b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_7TeV.root differ
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_900GeV.root b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_900GeV.root
new file mode 100644 (file)
index 0000000..465ec8c
Binary files /dev/null and b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/charged_spectra/dNdPt_pp_900GeV.root differ
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/convertToMyBins.C b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/convertToMyBins.C
new file mode 100644 (file)
index 0000000..9499d88
--- /dev/null
@@ -0,0 +1,343 @@
+#include <TFile.h>
+#include <TH1.h>
+#include <TMath.h>
+#include <TGraphErrors.h>
+
+#include "my_tools.C"
+
+#include <iostream>
+
+using namespace std;
+
+/*
+  Info:
+
+  Method to convert charged pT histograms to have the same histogram binning
+  as our histograms have.  They in general go to 100 GeV/c in pT while we only
+  go to 50. In that range the binning is EXACTLY the same (and the code checks
+  it).
+
+  In charged spectra there is NO NORMALIZATION uncertainty. We add it by hand
+  to the syst error.
+
+  * Need at some point to get the final spectra
+  * Need at some point to get the final normalization uncertainty
+
+  
+  To run:
+  
+  gSystem->AddIncludePath("-I../macros")
+  gSystem->AddIncludePath("-I../lib")
+  gROOT->SetMacroPath(".:../macros")
+  .L my_tools.C+
+  .L convertToMyBins.C+
+
+
+  ConvertPPfile("charged_spectra/dNdPt_pp_7TeV.root",    "NOPID_pp_7TeV.root", 0.034);
+  ConvertPPfile("charged_spectra/dNdPt_pp_2.76TeV.root", "NOPID_pp_2.76TeV.root", 0.034);
+  ConvertPPfile("charged_spectra/dNdPt_pp_900GeV.root",  "NOPID_pp_900GeV.root", 0.034);
+
+
+
+
+  Older methods that can be useful for AA:
+  The method convertToMyBinsAA is for pp and AA spectra.
+  The method convertToMyBinsRaa is for RAA.
+  The method convertToMyBinsOld is for AA data when the centralities had to be merged.
+
+ */
+
+
+
+TH1D* Convert(TH1D* histIn, Double_t addSyst=0);
+TH1D* ConvertGraph(TGraphErrors* graphIn);
+void convertToMyBinsAA();
+void convertToMyBinsRaa(const Char_t* fileName = "PbPb_RAA_2760GeV_200511.root");
+void convertToMyBinsOld(const Char_t* fileName = "dndpt_all_2011-05-15.root");
+
+
+void  ConvertPPfile(const Char_t* inFileName, const Char_t* outFileName, Double_t normSyst=0.0)
+{
+  TFile* fileDataCharged = FindFileFresh(inFileName);
+  
+  if(!fileDataCharged)
+    return;
+  
+  TH1D* hPtHelp = (TH1D*)fileDataCharged->Get("dNdPt_stat");
+  TH1D* hPtCharged = Convert(hPtHelp);
+  hPtCharged->SetName("hDnDptCharged_PP");
+  hPtCharged->SetMarkerStyle(29);
+
+  hPtHelp = (TH1D*)fileDataCharged->Get("dNdPt_syst");
+  TH1D* hPtChargedSyst = Convert(hPtHelp, normSyst);
+  hPtChargedSyst->SetName("hDnDptChargedSyst_PP");
+  hPtChargedSyst->SetMarkerStyle(29);
+
+  TFile* fileOut = new TFile(outFileName, "RECREATE");
+  hPtCharged->Write();
+  hPtChargedSyst->Write();
+  fileOut->Close();  
+}
+
+//________________________________________________________________________________________
+TH1D* Convert(TH1D* histIn, Double_t addSyst)
+{
+  const Int_t nPtBins = 68;
+  Double_t xBins[nPtBins+1] = {0. ,  0.05, 0.1,  0.15, 0.2,  0.25, 0.3,  0.35, 0.4,  0.45,
+                              0.5,  0.55, 0.6,  0.65, 0.7,  0.75, 0.8,  0.85, 0.9,  0.95,
+                              1.0,  1.1 , 1.2,  1.3 , 1.4,  1.5 , 1.6,  1.7 , 1.8,  1.9 ,
+                              2.0,  2.2 , 2.4,  2.6 , 2.8,  3.0 , 3.2,  3.4 , 3.6,  3.8 ,
+                              4.0,  4.5 , 5.0,  5.5 , 6.0,  6.5 , 7.0,  8.0 , 9.0,  10.0,
+                              11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0, 22.0, 24.0,
+                              26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 40.0, 45.0, 50.0 };
+  
+
+  TH1D* hist = new TH1D("hist", "", nPtBins, xBins);
+  hist->SetTitle(histIn->GetTitle());
+  hist->GetXaxis()->SetTitle(histIn->GetXaxis()->GetTitle());
+  hist->GetYaxis()->SetTitle(histIn->GetYaxis()->GetTitle());
+
+  const Double_t deltapt = 0.0001;
+
+  for(Int_t bin = 1; bin <= nPtBins; bin++) {
+
+    // check bin size
+    if(TMath::Abs(hist->GetXaxis()->GetBinLowEdge(bin) -
+                 histIn->GetXaxis()->GetBinLowEdge(bin)) > deltapt) {
+      cout << "pt edge low does not agree!!!!!!!!!!!!!!!" << endl;
+      return 0;
+    }
+    if(TMath::Abs(hist->GetXaxis()->GetBinUpEdge(bin) -
+                 histIn->GetXaxis()->GetBinUpEdge(bin)) > deltapt) {
+      cout << "pt edge high does not agree!!!!!!!!!!!!!!!" << endl;
+      return 0;
+    }
+    if(TMath::Abs(hist->GetXaxis()->GetBinCenter(bin) -
+                 histIn->GetXaxis()->GetBinCenter(bin)) > deltapt) {
+      cout << "pt center does not agree!!!!!!!!!!!!!!!" << endl;
+      return 0;
+    }
+
+
+    hist->SetBinContent(bin, histIn->GetBinContent(bin)); 
+
+    Double_t error = histIn->GetBinError(bin); 
+    if(addSyst) {
+
+      Double_t extra_error = addSyst*histIn->GetBinContent(bin);
+      error = TMath::Sqrt(error*error + extra_error*extra_error);
+    }
+    hist->SetBinError(bin, error);
+  }
+
+  return hist;
+}
+
+//________________________________________________________________________________________
+TH1D* ConvertGraph(TGraphErrors* graphIn)
+{
+  const Int_t nPtBins = 68;
+  Double_t xBins[nPtBins+1] = {0. ,  0.05, 0.1,  0.15, 0.2,  0.25, 0.3,  0.35, 0.4,  0.45,
+                              0.5,  0.55, 0.6,  0.65, 0.7,  0.75, 0.8,  0.85, 0.9,  0.95,
+                              1.0,  1.1 , 1.2,  1.3 , 1.4,  1.5 , 1.6,  1.7 , 1.8,  1.9 ,
+                              2.0,  2.2 , 2.4,  2.6 , 2.8,  3.0 , 3.2,  3.4 , 3.6,  3.8 ,
+                              4.0,  4.5 , 5.0,  5.5 , 6.0,  6.5 , 7.0,  8.0 , 9.0,  10.0,
+                              11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0, 22.0, 24.0,
+                              26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 40.0, 45.0, 50.0 };
+  
+
+  TH1D* hist = new TH1D("hist", "", nPtBins, xBins);
+  // hist->SetTitle(graphIn->GetTitle());
+  // hist->GetXaxis()->SetTitle(graphIn->GetXaxis()->GetTitle());
+  // hist->GetYaxis()->SetTitle(graphIn->GetYaxis()->GetTitle());
+
+  const Double_t deltapt = 0.0001;
+
+  // Jacek does not fill the first 3 bins of his graph?
+  for(Int_t bin = 4; bin <= nPtBins; bin++) {
+
+    // check bin size
+    if(TMath::Abs(hist->GetXaxis()->GetBinCenter(bin) -
+                 graphIn->GetX()[bin-1]) > deltapt) {
+      cout << "pt center does not agree!!!!!!!!!!!!!!!" << endl;
+      return 0;
+    }
+
+
+    hist->SetBinContent(bin, graphIn->GetY()[bin-1]); 
+    hist->SetBinError(bin, graphIn->GetEY()[bin-1]); 
+  }
+
+  return hist;
+}
+
+//________________________________________________________________________________________
+void convertToMyBinsAA()
+{
+  const Int_t nCent = 7;
+  const Int_t cent[nCent+1] = {-5, 0, 5, 10, 20, 40, 60, 80};
+  const Int_t colors[nCent] = {kBlack, kRed+1, kOrange+7, kOrange, kGreen+2, kCyan+2, kBlue+1};  
+
+  TH1D* hPtCharged[nCent] = {0, 0, 0, 0, 0, 0, 0};
+  TH1D* hPtChargedSyst[nCent] = {0, 0, 0, 0, 0, 0, 0};
+
+  for (Int_t i = 0; i < nCent; i++) {
+    
+    if(cent[i]==-5) {
+
+      TFile* fileDataCharged = FindFileFresh("dNdPt_pp_2.76TeV.root");
+      
+      if(!fileDataCharged)
+       return;
+      
+      TH1D* hPtHelp = (TH1D*)fileDataCharged->Get("dNdPt_stat");
+      hPtCharged[i] = Convert(hPtHelp);
+      hPtCharged[i]->SetName("hDnDptCharged_PP");
+      hPtCharged[i]->SetMarkerColor(colors[i]);
+      hPtCharged[i]->SetMarkerStyle(29);
+      hPtHelp = (TH1D*)fileDataCharged->Get("dNdPt_syst");
+      hPtChargedSyst[i] = Convert(hPtHelp, 0.034); // 3.4 % norm error
+      /*
+       Dear Peter,
+       
+       for 2.76TeV the systematic error for MB->INEL is 3.40%,, we decided to 
+       drop the uncertainty from VdM scan since we don't really use it...
+       
+       Michael 
+      */
+      hPtChargedSyst[i]->SetName("hDnDptChargedSyst_PP");
+      hPtChargedSyst[i]->SetMarkerColor(colors[i]);
+      hPtChargedSyst[i]->SetMarkerStyle(29);
+    } else {
+
+      TFile* fileDataCharged = FindFileFresh(Form("dNdPt_PbPb_2.76ATeV_centrality_%d-%d.root", cent[i], cent[i+1]));
+      
+      if(!fileDataCharged)
+       return;
+
+      TH1D* hPtHelp = (TH1D*)fileDataCharged->Get("dNdPt_stat");
+      hPtCharged[i] = Convert(hPtHelp);
+      hPtCharged[i]->SetName(Form("hDnDptCharged_%d_%d", cent[i], cent[i+1]));
+      hPtCharged[i]->SetMarkerColor(colors[i]);
+      hPtCharged[i]->SetMarkerStyle(29);
+      hPtHelp = (TH1D*)fileDataCharged->Get("dNdPt_syst");
+      hPtChargedSyst[i] = Convert(hPtHelp);
+      hPtChargedSyst[i]->SetName(Form("hDnDptChargedSyst_%d_%d", cent[i], cent[i+1]));
+      hPtChargedSyst[i]->SetMarkerColor(colors[i]);
+      hPtChargedSyst[i]->SetMarkerStyle(29);
+    }
+  }
+
+  TFile* fileOut = new TFile("dNdPt_Charged.root", "RECREATE");
+  for (Int_t i = 0; i < nCent; i++) {
+    hPtCharged[i]->Write();
+    hPtChargedSyst[i]->Write();
+  }
+  fileOut->Close();  
+}
+
+//________________________________________________________________________________________
+void convertToMyBinsRaa(const Char_t* fileName)
+{
+  TFile* fileData = FindFileFresh(fileName);
+
+  if(!fileData)
+    return;
+  
+  TGraphErrors* hRaa_0_5 = (TGraphErrors*)fileData->Get("raa_c0_5_stat");
+  TH1D* hRaaCharged_0_5 = ConvertGraph(hRaa_0_5);
+  hRaaCharged_0_5->SetName("hRaaCharged_0_5");
+
+  TGraphErrors* hRaa_5_10 = (TGraphErrors*)fileData->Get("raa_c5_10_stat");
+  TH1D* hRaaCharged_5_10 = ConvertGraph(hRaa_5_10);
+  hRaaCharged_5_10->SetName("hRaaCharged_5_10");
+
+  TGraphErrors* hRaa_10_20 = (TGraphErrors*)fileData->Get("raa_c10_20_stat");
+  TH1D* hRaaCharged_10_20 = ConvertGraph(hRaa_10_20);
+  hRaaCharged_10_20->SetName("hRaaCharged_10_20");
+
+  TGraphErrors* hRaa_20_40 = (TGraphErrors*)fileData->Get("raa_c20_40_stat");
+  TH1D* hRaaCharged_20_40 = ConvertGraph(hRaa_20_40);
+  hRaaCharged_20_40->SetName("hRaaCharged_20_40");
+
+  TGraphErrors* hRaa_40_60 = (TGraphErrors*)fileData->Get("raa_c40_60_stat");
+  TH1D* hRaaCharged_40_60 = ConvertGraph(hRaa_40_60);
+  hRaaCharged_40_60->SetName("hRaaCharged_40_60");
+
+  TGraphErrors* hRaa_60_80 = (TGraphErrors*)fileData->Get("raa_c60_80_stat");
+  TH1D* hRaaCharged_60_80 = ConvertGraph(hRaa_60_80);
+  hRaaCharged_60_80->SetName("hRaaCharged_60_80");
+
+  TGraphErrors* hRaa_0_20 = (TGraphErrors*)fileData->Get("raa_c0_20_stat");
+  TH1D* hRaaCharged_0_20 = ConvertGraph(hRaa_0_20);
+  hRaaCharged_0_20->SetName("hRaaCharged_0_20");
+
+  TGraphErrors* hRaa_40_80 = (TGraphErrors*)fileData->Get("raa_c40_80_stat");
+  TH1D* hRaaCharged_40_80 = ConvertGraph(hRaa_40_80);
+  hRaaCharged_40_80->SetName("hRaaCharged_40_80");
+
+
+  TFile* fileOut = new TFile("Raa_Charged.root", "RECREATE");
+  hRaaCharged_0_5->Write();
+  hRaaCharged_5_10->Write();
+  hRaaCharged_10_20->Write();
+  hRaaCharged_20_40->Write();
+  hRaaCharged_40_60->Write();
+  hRaaCharged_60_80->Write();
+  hRaaCharged_0_20->Write();
+  hRaaCharged_40_80->Write();
+  fileOut->Close();  
+}
+
+//________________________________________________________________________________________
+
+void convertToMyBinsOld(const Char_t* fileName)
+{
+  TFile* fileData = FindFileFresh(fileName);
+
+  if(!fileData)
+    return;
+
+  TH1D* hDnDPt_0_5 = (TH1D*)fileData->Get("dNdPt_PbPb_c0_5");
+  TH1D* hDnDptCharged_0_5 = Convert(hDnDPt_0_5);
+  hDnDptCharged_0_5->SetName("hDnDptCharged_0_5");
+
+  TH1D* hDnDPt_5_10 = (TH1D*)fileData->Get("dNdPt_PbPb_c5_10");
+  TH1D* hDnDptCharged_5_10 = Convert(hDnDPt_5_10);
+  hDnDptCharged_5_10->SetName("hDnDptCharged_5_10");
+
+  TH1D* hDnDPt_10_20 = (TH1D*)fileData->Get("dNdPt_PbPb_c10_20");
+  TH1D* hDnDptCharged_10_20 = Convert(hDnDPt_10_20);
+  hDnDptCharged_10_20->SetName("hDnDptCharged_10_20");
+
+  TH1D* hDnDPt_20_40 = (TH1D*)fileData->Get("dNdPt_PbPb_c20_30");
+  TH1D* hHelp =  (TH1D*)fileData->Get("dNdPt_PbPb_c30_40");
+  hDnDPt_20_40->Add(hHelp);
+  hDnDPt_20_40->Scale(1.0/2.0);
+  TH1D* hDnDptCharged_20_40 = Convert(hDnDPt_20_40);
+  hDnDptCharged_20_40->SetName("hDnDptCharged_20_40");
+
+  TH1D* hDnDPt_40_60 = (TH1D*)fileData->Get("dNdPt_PbPb_c40_50");
+  hHelp =  (TH1D*)fileData->Get("dNdPt_PbPb_c50_60");
+  hDnDPt_40_60->Add(hHelp);
+  hDnDPt_40_60->Scale(1.0/2.0);
+  TH1D* hDnDptCharged_40_60 = Convert(hDnDPt_40_60);
+  hDnDptCharged_40_60->SetName("hDnDptCharged_40_60");
+
+  TH1D* hDnDPt_60_80 = (TH1D*)fileData->Get("dNdPt_PbPb_c60_70");
+  hHelp =  (TH1D*)fileData->Get("dNdPt_PbPb_c70_80");
+  hDnDPt_60_80->Add(hHelp);
+  hDnDPt_60_80->Scale(1.0/2.0);
+  TH1D* hDnDptCharged_60_80 = Convert(hDnDPt_60_80);
+  hDnDptCharged_60_80->SetName("hDnDptCharged_60_80");
+
+
+  TFile* fileOut = new TFile("dNdPt_Charged.root", "RECREATE");
+  hDnDptCharged_0_5->Write();
+  hDnDptCharged_5_10->Write();
+  hDnDptCharged_10_20->Write();
+  hDnDptCharged_20_40->Write();
+  hDnDptCharged_40_60->Write();
+  hDnDptCharged_60_80->Write();
+  fileOut->Close();  
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/makeSpectra.C b/PWGLF/SPECTRA/IdentifiedHighPt/final_spectra/makeSpectra.C
new file mode 100644 (file)
index 0000000..a9f29cf
--- /dev/null
@@ -0,0 +1,112 @@
+#include <TFile.h>
+#include <TH1.h>
+#include <TF1.h>
+#include <TCanvas.h>
+#include <TList.h>
+#include <TLegend.h>
+#include <TStyle.h>
+#include <TMath.h>
+#include <TSystem.h>
+#include <TLatex.h>
+#include <TASImage.h>
+#include <TLine.h>
+#include <TBox.h>
+
+#include "my_tools.C"
+
+
+/*
+  Info:
+  Multiplies the fraction with the charged spectrum. 
+  Applies a rapidity correction in case of K and p.
+
+  To run:
+
+  gSystem->AddIncludePath("-I../macros")
+  gSystem->AddIncludePath("-I../lib")
+  gROOT->SetMacroPath(".:../macros")
+  .L my_tools.C+
+  .L makeSpectra.C+
+
+  MakeSpectra("../corrected_fraction/fraction_7tev_b_all.root", "NOPID_pp_7TeV.root", "final_spectra_7tev_b.root");
+
+
+ */
+
+Double_t rap_correction(Double_t* x, Double_t* par);
+
+void MakeSpectra(const Char_t* fileName,
+                const Char_t* fileNameCharged,
+                const Char_t* outFileName,
+                const Char_t* endName="PP")
+{
+  TFile* fileData = FindFileFresh(fileName);
+
+  if(!fileData)
+    return;
+
+  TFile* fileDataCharged = FindFileFresh(fileNameCharged);
+  
+  if(!fileDataCharged)
+    return;
+  
+  const Int_t nPid = 3;
+  const Char_t* pidNames[nPid] = {"Pion", "Kaon", "Proton"}; 
+  const Char_t* titleNames[nPid] = {"#pi^{+} + #pi^{-}", "K^{+} + K^{-}", "p + #bar{p}"}; 
+  const Double_t mass[nPid] = {0.140, 0.494, 0.938};
+
+  TH1D* hPtSpectrum[nPid] = {0, 0, 0};
+  TH1D* hPtSpectrumSyst[nPid] = {0, 0, 0};
+
+  TH1D* hPtCharged = (TH1D*)fileDataCharged->Get(Form("hDnDptCharged_%s", endName));
+  TH1D* hPtChargedSyst = (TH1D*)fileDataCharged->Get(Form("hDnDptChargedSyst_%s", endName));
+
+  TF1* fRap = new TF1("fRap", rap_correction, 0.0, 50.0, 2);
+
+  for(Int_t pid = 0; pid < nPid; pid++) {
+    
+    // Pions
+    TH1D* hFraction     = (TH1D*)fileData->Get(Form("h%sFraction_%s", pidNames[pid], endName));
+    TH1D* hFractionSyst = (TH1D*)fileData->Get(Form("h%sFractionSyst_%s", pidNames[pid], endName));
+    
+    hPtSpectrum[pid] = (TH1D*)hFraction->Clone(Form("h%sSpectrum_%s", pidNames[pid], endName));
+    hPtSpectrum[pid]->GetYaxis()->SetTitle(Form("1/N_{evt} 1/(2#pi p_{T}) (d^{2}N_{%s})/(dy dp_{T}) (GeV/c)^{-2}", titleNames[pid]));
+    hPtSpectrum[pid]->Multiply(hPtCharged);
+
+    hPtSpectrumSyst[pid] = (TH1D*)hFractionSyst->Clone(Form("h%sSpectrumSyst_%s", pidNames[pid], endName));
+    hPtSpectrumSyst[pid]->SetMarkerStyle(1);
+    hPtSpectrum[pid]->GetYaxis()->SetTitle(Form("1/N_{evt} 1/(2#pi p_{T}) (d^{2}N_{%s})/(dy dp_{T}) (GeV/c)^{-2}", titleNames[pid]));
+    hPtSpectrumSyst[pid]->Multiply(hPtChargedSyst);
+    hPtSpectrumSyst[pid]->SetFillStyle(1001);
+    hPtSpectrumSyst[pid]->SetFillColor(kGray);
+
+    //
+    // Rapidity correction
+    //
+    fRap->SetParameters(0.8, mass[pid]);
+    hPtSpectrum[pid]->Divide(fRap);
+    hPtSpectrumSyst[pid]->Divide(fRap);
+  }
+
+  TFile* fileOut = new TFile(outFileName, "RECREATE");
+  for(Int_t pid = 0; pid < nPid; pid++) {
+    hPtSpectrumSyst[pid]->Write();
+    hPtSpectrum[pid]->Write();
+  }
+  fileOut->Close();
+}
+
+//______________________________________________________________________________
+Double_t rap_correction(Double_t* x, Double_t* par)
+{
+  Double_t pt = x[0];  
+
+  Double_t eta  = par[0];
+  Double_t mass = par[1];
+
+  const Double_t mt = TMath::Sqrt(pt*pt + mass*mass);
+  
+  const Double_t rap = TMath::ASinH(pt/mt*TMath::SinH(eta));
+  
+  return rap/eta;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/AddTaskHighPtDeDx.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/AddTaskHighPtDeDx.C
new file mode 100644 (file)
index 0000000..ae28a2e
--- /dev/null
@@ -0,0 +1,185 @@
+AliAnalysisTask* AddTask(Bool_t AnalysisMC, const Char_t* taskname, Int_t typerun, UInt_t kTriggerInt[], Float_t minc[], Float_t maxc[] )
+{
+  // Creates a pid task and adds it to the analysis manager
+  
+  // Get the pointer to the existing analysis manager via the static
+  //access method
+  //=========================================================================
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) {
+    Error("AddTaskHighPtDeDx", "No analysis manager to connect to.");
+    return NULL;
+  }  
+  
+  // Check the analysis type using the event handlers connected to the
+  // analysis manager The availability of MC handler can also be
+  // checked here.
+  // =========================================================================
+  if (!mgr->GetInputEventHandler()) {
+    Error("AddTaskHighPtDeDx", "This task requires an input event handler");
+    return NULL;
+  }  
+  
+
+
+  //
+  // Add track filters, with Golden Cuts
+  //
+  AliAnalysisFilter* trackFilterGolden = new AliAnalysisFilter("trackFilter");
+  AliESDtrackCuts* esdTrackCutsGolden = 
+    AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE);
+  trackFilterGolden->AddCuts(esdTrackCutsGolden);
+
+  
+  //old cuts without golden cut
+  AliAnalysisFilter* trackFilter0 = new AliAnalysisFilter("trackFilter");
+  Bool_t clusterCut=0;
+  Bool_t selPrimaries=kTRUE;
+  AliESDtrackCuts* esdTrackCutsL0 = new AliESDtrackCuts;
+ // TPC  
+  if(clusterCut == 0)  esdTrackCutsL0->SetMinNClustersTPC(70);
+  else if (clusterCut == 1) {
+    esdTrackCutsL0->SetMinNCrossedRowsTPC(70);
+    esdTrackCutsL0->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
+  }
+  else {
+    AliWarningClass(Form("Wrong value of the clusterCut parameter (%d), using cut on Nclusters",clusterCut));
+    esdTrackCutsL0->SetMinNClustersTPC(70);
+  }
+  esdTrackCutsL0->SetMaxChi2PerClusterTPC(4);
+  esdTrackCutsL0->SetAcceptKinkDaughters(kFALSE);
+  esdTrackCutsL0->SetRequireTPCRefit(kTRUE);
+  // ITS
+  esdTrackCutsL0->SetRequireITSRefit(kTRUE);
+  esdTrackCutsL0->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
+                                        AliESDtrackCuts::kAny);
+  if(selPrimaries) {
+    // 7*(0.0026+0.0050/pt^1.01)
+    esdTrackCutsL0->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
+  }
+  esdTrackCutsL0->SetMaxDCAToVertexZ(2);
+  esdTrackCutsL0->SetDCAToVertex2D(kFALSE);
+  esdTrackCutsL0->SetRequireSigmaToVertex(kFALSE);
+  esdTrackCutsL0->SetMaxChi2PerClusterITS(1e10);
+  esdTrackCutsL0->SetMaxChi2TPCConstrainedGlobal(1e10);
+
+
+  trackFilter0->AddCuts(esdTrackCutsL0);
+
+  
+  
+  AliAnalysisFilter* trackFilterTPC = new AliAnalysisFilter("trackFilterTPC");
+  AliESDtrackCuts* esdTrackCutsTPC = 
+    AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+  trackFilterTPC->AddCuts(esdTrackCutsTPC);
+
+
+
+  // Create the task and configure it 
+  //========================================================================
+  if(typerun==2){//heavy ion analysis
+    
+    
+    AliAnalysisTaskHighPtDeDx* taskHighPtDeDx[6];
+    for( Int_t i=0; i<6; ++i ){
+      taskHighPtDeDx[i]=0;
+      Char_t TaskName[256]={0};
+      sprintf(TaskName,"%s_%1.0f_%1.0f",taskname,minc[i],maxc[i]);
+      
+      taskHighPtDeDx[i] = new AliAnalysisTaskHighPtDeDx(TaskName);
+      TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
+      taskHighPtDeDx[i]->SetAnalysisType(type);
+      taskHighPtDeDx[i]->SetAnalysisMC(AnalysisMC);
+      taskHighPtDeDx[i]->SetAnalysisPbPb(kTRUE);
+      taskHighPtDeDx[i]->SetProduceTPCBranch(kFALSE);
+      taskHighPtDeDx[i]->SetDebugLevel(0);
+      taskHighPtDeDx[i]->SetEtaCut(0.8);
+      taskHighPtDeDx[i]->SetVtxCut(10.0);
+      taskHighPtDeDx[i]->SetMinPt(0.0); // default 2.0
+      taskHighPtDeDx[i]->SetLowPtFraction(0.01); // keep 1% of tracks below min pt
+      taskHighPtDeDx[i]->SetTreeOption(1);
+      taskHighPtDeDx[i]->SetTrigger1(kTriggerInt[0]);
+      taskHighPtDeDx[i]->SetTrigger2(kTriggerInt[1]);
+      taskHighPtDeDx[i]->SetMinCent(minc[i]);
+      taskHighPtDeDx[i]->SetMaxCent(maxc[i]);
+      //Set Filtesr
+      taskHighPtDeDx[i]->SetTrackFilterGolden(trackFilterGolden);
+      taskHighPtDeDx[i]->SetTrackFilter(trackFilter0);
+      taskHighPtDeDx[i]->SetTrackFilterTPC(trackFilterTPC);
+      
+      mgr->AddTask(taskHighPtDeDx[i]);
+      
+    }
+    
+    // Create ONLY the output containers for the data produced by the
+    // task.  Get and connect other common input/output containers via
+    // the manager as below
+    //=======================================================================
+    AliAnalysisDataContainer *cout_hist[6];
+    for( Int_t i=0; i<6; ++i ){
+      
+      cout_hist[i]=0;
+      Char_t outFileName[256]={0};
+      sprintf(outFileName,"%s_Tree_%1.0f_%1.0f.root",taskname,minc[i],maxc[i]);
+      //AliAnalysisDataContainer *cout_hist    = 0;
+      
+      cout_hist[i] = mgr->CreateContainer(Form("output_%1.0f_%1.0f",minc[i],maxc[i]), TList::Class(), AliAnalysisManager::kOutputContainer, outFileName);
+      mgr->ConnectInput (taskHighPtDeDx[i], 0, mgr->GetCommonInputContainer());
+      mgr->ConnectOutput(taskHighPtDeDx[i], 1, cout_hist[i]);
+      
+    }  
+    
+    // Return task pointer at the end
+    return taskHighPtDeDx[0];
+  }
+  if(typerun==3){//pp analysis
+  
+    
+    AliAnalysisTaskHighPtDeDx* taskHighPtDeDx = new AliAnalysisTaskHighPtDeDx("taskHighPtDeDxpp");
+    TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
+    taskHighPtDeDx->SetAnalysisType(type);
+    taskHighPtDeDx->SetAnalysisMC(AnalysisMC);
+    taskHighPtDeDx->SetAnalysisPbPb(kFALSE);
+    taskHighPtDeDx->SetProduceTPCBranch(kFALSE);
+    taskHighPtDeDx->SetDebugLevel(0);
+    taskHighPtDeDx->SetEtaCut(0.8);
+    taskHighPtDeDx->SetVtxCut(10.0);
+    taskHighPtDeDx->SetMinPt(0.0); // default 2.0
+    taskHighPtDeDx->SetLowPtFraction(0.01); // keep 1% of tracks below min pt
+    taskHighPtDeDx->SetTreeOption(1);
+    taskHighPtDeDx->SetTrigger1(kTriggerInt[0]);
+    taskHighPtDeDx->SetTrigger2(kTriggerInt[1]);
+    //Set Filtesr
+    taskHighPtDeDx->SetTrackFilterGolden(trackFilterGolden);
+    taskHighPtDeDx->SetTrackFilter(trackFilter0);
+    taskHighPtDeDx->SetTrackFilterTPC(trackFilterTPC);
+    
+    mgr->AddTask(taskHighPtDeDx);
+      
+    // Create ONLY the output containers for the data produced by the
+    // task.  Get and connect other common input/output containers via
+    // the manager as below
+    //=======================================================================
+  
+    AliAnalysisDataContainer *cout_histdedx;
+
+    cout_histdedx=0;
+    Char_t outFileName[256]={0};
+    sprintf(outFileName,"%s_Tree.root",taskname);
+    //AliAnalysisDataContainer *cout_hist    = 0;
+    cout_histdedx = mgr->CreateContainer("outputdedx", TList::Class(), AliAnalysisManager::kOutputContainer, outFileName);
+    mgr->ConnectInput (taskHighPtDeDx, 0, mgr->GetCommonInputContainer());
+    mgr->ConnectOutput(taskHighPtDeDx, 1, cout_histdedx);
+    // Return task pointer at the end
+    return taskHighPtDeDx;
+    
+
+    
+    
+    
+  }
+  
+  
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/AddTaskHighPtDeDxV0.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/AddTaskHighPtDeDxV0.C
new file mode 100644 (file)
index 0000000..14ff6c1
--- /dev/null
@@ -0,0 +1,190 @@
+AliAnalysisTask* AddTask(Bool_t AnalysisMC, const Char_t* taskname, Int_t typerun,  UInt_t kTriggerInt[], Float_t minc[], Float_t maxc[] )
+{
+  // Creates a pid task and adds it to the analysis manager
+  
+  // Get the pointer to the existing analysis manager via the static
+  //access method
+  //=========================================================================
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) {
+    Error("AddTaskHighPtDeDx", "No analysis manager to connect to.");
+    return NULL;
+  }  
+  
+  // Check the analysis type using the event handlers connected to the
+  // analysis manager The availability of MC handler can also be
+  // checked here.
+  // =========================================================================
+  if (!mgr->GetInputEventHandler()) {
+    Error("AddTaskHighPtDeDx", "This task requires an input event handler");
+    return NULL;
+  }  
+  
+ //
+  // Add track filters, with Golden Cuts
+  //
+  AliAnalysisFilter* trackFilterGolden = new AliAnalysisFilter("trackFilter");
+  AliESDtrackCuts* esdTrackCutsGolden = 
+    AliESDtrackCuts::GetStandardITSTPCTrackCuts2010(kTRUE);
+  trackFilterGolden->AddCuts(esdTrackCutsGolden);
+
+  
+  //old cuts without golden cut
+  AliAnalysisFilter* trackFilter0 = new AliAnalysisFilter("trackFilter");
+  Bool_t clusterCut=0;
+  Bool_t selPrimaries=kTRUE;
+  AliESDtrackCuts* esdTrackCutsL0 = new AliESDtrackCuts;
+ // TPC  
+  if(clusterCut == 0)  esdTrackCutsL0->SetMinNClustersTPC(70);
+  else if (clusterCut == 1) {
+    esdTrackCutsL0->SetMinNCrossedRowsTPC(70);
+    esdTrackCutsL0->SetMinRatioCrossedRowsOverFindableClustersTPC(0.8);
+  }
+  else {
+    AliWarningClass(Form("Wrong value of the clusterCut parameter (%d), using cut on Nclusters",clusterCut));
+    esdTrackCutsL0->SetMinNClustersTPC(70);
+  }
+  esdTrackCutsL0->SetMaxChi2PerClusterTPC(4);
+  esdTrackCutsL0->SetAcceptKinkDaughters(kFALSE);
+  esdTrackCutsL0->SetRequireTPCRefit(kTRUE);
+  // ITS
+  esdTrackCutsL0->SetRequireITSRefit(kTRUE);
+  esdTrackCutsL0->SetClusterRequirementITS(AliESDtrackCuts::kSPD,
+                                        AliESDtrackCuts::kAny);
+  if(selPrimaries) {
+    // 7*(0.0026+0.0050/pt^1.01)
+    esdTrackCutsL0->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
+  }
+  esdTrackCutsL0->SetMaxDCAToVertexZ(2);
+  esdTrackCutsL0->SetDCAToVertex2D(kFALSE);
+  esdTrackCutsL0->SetRequireSigmaToVertex(kFALSE);
+  esdTrackCutsL0->SetMaxChi2PerClusterITS(1e10);
+  esdTrackCutsL0->SetMaxChi2TPCConstrainedGlobal(1e10);
+
+
+  trackFilter0->AddCuts(esdTrackCutsL0);
+
+  
+  
+  AliAnalysisFilter* trackFilterTPC = new AliAnalysisFilter("trackFilterTPC");
+  AliESDtrackCuts* esdTrackCutsTPC = 
+    AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+  trackFilterTPC->AddCuts(esdTrackCutsTPC);
+
+
+  // Create the task and configure it 
+  //========================================================================
+  if(typerun==2){//heavy ion analysis
+
+    AliAnalysisTaskHighPtDeDxV0* taskHighPtDeDxV0[6];
+    for( Int_t i=0; i<6; ++i ){
+      taskHighPtDeDxV0[i]=0;
+      Char_t TaskName[256]={0};
+      sprintf(TaskName,"%s_%1.0f_%1.0f",taskname,minc[i],maxc[i]);
+      
+      taskHighPtDeDxV0[i] = new AliAnalysisTaskHighPtDeDxV0(TaskName);
+      TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
+      
+      taskHighPtDeDxV0[i]->SetAnalysisType(type);
+      taskHighPtDeDxV0[i]->SetAnalysisMC(AnalysisMC);
+      taskHighPtDeDxV0[i]->SetAnalysisPbPb(kTRUE);
+      taskHighPtDeDxV0[i]->SetProduceTPCBranch(kFALSE);
+      taskHighPtDeDxV0[i]->SetDebugLevel(0);
+      taskHighPtDeDxV0[i]->SetEtaCut(0.8);
+      taskHighPtDeDxV0[i]->SetVtxCut(10.0);
+      taskHighPtDeDxV0[i]->SetMinPt(0.0);           // def: 2.0
+      taskHighPtDeDxV0[i]->SetMassCut(0.1);         // def: 0.03
+      taskHighPtDeDxV0[i]->SetTreeOption(1);
+      taskHighPtDeDxV0[i]->SetRequireRecV0(kFALSE); // def: kTRUE
+      taskHighPtDeDxV0[i]->SetStoreMcIn(kTRUE);     // def: kFALSE
+      taskHighPtDeDxV0[i]->SetTrigger1(kTriggerInt[0]);
+      taskHighPtDeDxV0[i]->SetTrigger2(kTriggerInt[1]);
+      taskHighPtDeDxV0[i]->SetMinCent(minc[i]);
+      taskHighPtDeDxV0[i]->SetMaxCent(maxc[i]);
+      //Set Filtesr
+      taskHighPtDeDxV0[i]->SetTrackFilterGolden(trackFilterGolden);
+      taskHighPtDeDxV0[i]->SetTrackFilter(trackFilter0);
+      taskHighPtDeDxV0[i]->SetTrackFilterTPC(trackFilterTPC);
+      
+      mgr->AddTask(taskHighPtDeDxV0[i]);
+      
+      
+    }
+    
+    // Create ONLY the output containers for the data produced by the
+    // task.  Get and connect other common input/output containers via
+    // the manager as below
+    //=======================================================================
+    AliAnalysisDataContainer *cout_hist[6];
+    for( Int_t i=0; i<6; ++i ){
+      
+      cout_hist[i]=0;
+      Char_t outFileName[256]={0};
+      sprintf(outFileName,"%s_Tree_%1.0f_%1.0f.root",taskname,minc[i],maxc[i]);
+      //AliAnalysisDataContainer *cout_hist    = 0;
+      
+      cout_hist[i] = mgr->CreateContainer(Form("output_%1.0f_%1.0f",minc[i],maxc[i]), TList::Class(), AliAnalysisManager::kOutputContainer, outFileName);
+      mgr->ConnectInput (taskHighPtDeDxV0[i], 0, mgr->GetCommonInputContainer());
+      mgr->ConnectOutput(taskHighPtDeDxV0[i], 1, cout_hist[i]);
+      
+    }  
+    
+    // Return task pointer at the end
+    return taskHighPtDeDxV0[0];
+  }
+  
+  if(typerun==3){//pp analysis
+
+    AliAnalysisTaskHighPtDeDxV0* taskHighPtDeDxV0 = new AliAnalysisTaskHighPtDeDxV0("taskHighPtDeDxV0pp");
+    TString type = mgr->GetInputEventHandler()->GetDataType(); // can be "ESD" or "AOD"
+    
+    taskHighPtDeDxV0->SetAnalysisType(type);
+    taskHighPtDeDxV0->SetAnalysisMC(AnalysisMC);
+    taskHighPtDeDxV0->SetAnalysisPbPb(kFALSE);
+    taskHighPtDeDxV0->SetProduceTPCBranch(kFALSE);
+    taskHighPtDeDxV0->SetDebugLevel(0);
+    taskHighPtDeDxV0->SetEtaCut(0.8);
+    taskHighPtDeDxV0->SetVtxCut(10.0);
+    taskHighPtDeDxV0->SetMinPt(0.0);           // def: 2.0
+    taskHighPtDeDxV0->SetMassCut(0.03);         // def: 0.03
+    taskHighPtDeDxV0->SetTreeOption(1);
+    taskHighPtDeDxV0->SetRequireRecV0(kTRUE); // def: kTRUE
+    taskHighPtDeDxV0->SetStoreMcIn(kFALSE);     // def: kFALSE
+    taskHighPtDeDxV0->SetTrigger1(kTriggerInt[0]);
+    taskHighPtDeDxV0->SetTrigger2(kTriggerInt[1]);
+    //Set Filtesr
+    taskHighPtDeDxV0->SetTrackFilterGolden(trackFilterGolden);
+    taskHighPtDeDxV0->SetTrackFilter(trackFilter0);
+    taskHighPtDeDxV0->SetTrackFilterTPC(trackFilterTPC);
+    
+    mgr->AddTask(taskHighPtDeDxV0);
+      
+   
+    
+    // Create ONLY the output containers for the data produced by the
+    // task.  Get and connect other common input/output containers via
+    // the manager as below
+    //=======================================================================
+    AliAnalysisDataContainer *cout_histdedxv0;
+
+    cout_histdedxv0=0;
+    Char_t outFileName[256]={0};
+    sprintf(outFileName,"%s_Tree.root",taskname);
+    //AliAnalysisDataContainer *cout_hist    = 0;
+    
+    cout_histdedxv0 = mgr->CreateContainer("output", TList::Class(), AliAnalysisManager::kOutputContainer, outFileName);
+    mgr->ConnectInput (taskHighPtDeDxV0, 0, mgr->GetCommonInputContainer());
+    mgr->ConnectOutput(taskHighPtDeDxV0, 1, cout_histdedxv0);
+    
+    // Return task pointer at the end
+    return taskHighPtDeDxV0;
+
+
+  }
+
+
+
+
+
+
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDx.cxx b/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDx.cxx
new file mode 100644 (file)
index 0000000..096f51e
--- /dev/null
@@ -0,0 +1,1705 @@
+#include "AliAnalysisTaskHighPtDeDx.h"
+
+// ROOT includes
+#include <TList.h>
+#include <TTree.h>
+#include <TMath.h>
+#include <TH1.h>
+#include <TParticle.h>
+#include <TFile.h>
+
+// AliRoot includes
+#include <AliAnalysisManager.h>
+#include <AliAnalysisFilter.h>
+#include <AliESDInputHandler.h>
+#include <AliESDEvent.h>
+#include <AliESDVertex.h>
+#include <AliLog.h>
+#include <AliExternalTrackParam.h>
+#include <AliESDtrackCuts.h>
+#include <AliESDVZERO.h>
+#include <AliAODVZERO.h>
+
+#include <AliMCEventHandler.h>
+#include <AliMCEvent.h>
+#include <AliStack.h>
+
+#include <TTreeStream.h>
+
+#include <AliHeader.h>
+#include <AliGenPythiaEventHeader.h>
+#include <AliGenDPMjetEventHeader.h>
+
+#include "AliCentrality.h" 
+
+#include <AliAODTrack.h> 
+#include <AliAODPid.h> 
+#include <AliAODMCHeader.h> 
+
+
+// STL includes
+#include <iostream>
+using namespace std;
+
+
+//
+// Responsible:
+// Alexandru Dobrin (Wayne State) 
+// Peter Christiansen (Lund)
+//
+
+/* 
+To do:
+
+Separate the code into two
+
+*/
+
+
+
+
+ClassImp(AliAnalysisTaskHighPtDeDx)
+
+const Double_t AliAnalysisTaskHighPtDeDx::fgkClight = 2.99792458e-2;
+
+//_____________________________________________________________________________
+AliAnalysisTaskHighPtDeDx::AliAnalysisTaskHighPtDeDx():
+  AliAnalysisTaskSE(),
+  fESD(0x0),
+  fAOD(0x0),
+  fMC(0x0),
+  fMCStack(0x0),
+  fMCArray(0x0),
+  fTrackFilter(0x0),
+  fTrackFilterGolden(0x0),
+  fTrackFilterTPC(0x0),
+  fAnalysisType("ESD"),
+  fAnalysisMC(kFALSE),
+  fAnalysisPbPb(kFALSE),
+  fTPCBranch(kFALSE),
+  ftrigBit1(0x0),
+  ftrigBit2(0x0),
+  fRandom(0x0),
+  fEvent(0x0),
+  fTrackArrayGlobalPar(0x0),
+  fTrackArrayTPCPar(0x0),
+  fTrackArrayMC(0x0),
+  fVZEROArray(0x0),
+  fVtxCut(10.0),  
+  fEtaCut(0.9),  
+  fMinPt(0.1),
+  fMinCent(0.0),
+  fMaxCent(100.0),
+  fLowPtFraction(0.01),
+  fTreeOption(0),
+  fMcProcessType(-999),
+  fTriggeredEventMB(-999),
+  fVtxStatus(-999),
+  fZvtx(-999),
+  fZvtxMC(-999),
+  fRun(-999),
+  fEventId(-999),
+  fListOfObjects(0), 
+  fEvents(0x0), fVtx(0x0), fVtxMC(0x0), fVtxBeforeCuts(0x0), fVtxAfterCuts(0x0),
+  fTree(0x0),
+  fn1(0),
+  fn2(0),
+  fcent(0)
+
+
+{
+  // Default constructor (should not be used)
+
+  //  fRandom = new TRandom(0); // 0 means random seed
+}
+
+//______________________________________________________________________________
+AliAnalysisTaskHighPtDeDx::AliAnalysisTaskHighPtDeDx(const char *name):
+  AliAnalysisTaskSE(name),
+  fESD(0x0),
+  fAOD(0x0),
+  fMC(0x0),
+  fMCStack(0x0),
+  fMCArray(0x0),
+  fTrackFilter(0x0),
+  fTrackFilterGolden(0x0),
+  fTrackFilterTPC(0x0),
+  fAnalysisType("ESD"),
+  fAnalysisMC(kFALSE),
+  fAnalysisPbPb(kFALSE),
+  fTPCBranch(kFALSE),
+  ftrigBit1(0x0),
+  ftrigBit2(0x0),
+  fRandom(0x0),
+  fEvent(0x0),
+  fTrackArrayGlobalPar(0x0),
+  fTrackArrayMC(0x0),
+  fVtxCut(10.0),  
+  fEtaCut(0.9),  
+  fMinPt(0.1),
+  fLowPtFraction(0.01),
+  fTreeOption(0),
+  fMcProcessType(-999),
+  fTriggeredEventMB(-999),
+  fVtxStatus(-999),
+  fZvtx(-999),
+  fZvtxMC(-999),
+  fRun(-999),
+  fEventId(-999),
+  fListOfObjects(0), 
+  fEvents(0x0), fVtx(0x0), fVtxMC(0x0), fVtxBeforeCuts(0x0), fVtxAfterCuts(0x0),
+  fTree(0x0),
+  fn1(0),
+  fn2(0),
+  fcent(0)
+
+{
+
+  if(fTree)fTree=0;
+  // Output slot #1 writes into a TList
+  DefineOutput(1, TList::Class());
+}
+
+//_____________________________________________________________________________
+AliAnalysisTaskHighPtDeDx::~AliAnalysisTaskHighPtDeDx()
+{
+  // Destructor
+  // histograms are in the output list and deleted when the output
+  // list is deleted by the TSelector dtor
+  if (fListOfObjects && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
+    delete fListOfObjects;
+    fListOfObjects = 0;
+  }
+  if (fRandom) delete fRandom;
+  fRandom=0;
+  
+  // //for proof running; I cannot create tree do to memory limitations -> work with THnSparse 
+  // if (fListOfObjects  && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) delete fOutputList;
+  
+  
+  
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::UserCreateOutputObjects()
+{ 
+  // This method is called once per worker node
+  // Here we define the output: histograms and debug tree if requested 
+  // We also create the random generator here so it might get different seeds...
+  fRandom = new TRandom(0); // 0 means random seed
+
+  OpenFile(1);
+  fListOfObjects = new TList();
+  fListOfObjects->SetOwner();
+  
+  //
+  // Histograms
+  //  
+  fEvents = new TH1I("fEvents","Number of analyzed events; Events; Counts", 3, 0, 3);
+  fListOfObjects->Add(fEvents);
+
+  fn1=new TH1F("fn1","fn1",5001,-1,5000);
+  fListOfObjects->Add(fn1);
+
+  fn2=new TH1F("fn2","fn2",5001,-1,5000);
+  fListOfObjects->Add(fn2);
+
+  fcent=new TH1F("fcent","fcent",104,-2,102);
+  fListOfObjects->Add(fcent);
+
+  fVtx = new TH1I("fVtx","Vtx info (0=no, 1=yes); Vtx; Counts", 2, -0.5, 1.5);
+  fListOfObjects->Add(fVtx);
+
+  fVtxBeforeCuts = new TH1F("fVtxBeforeCuts", "Vtx distribution (before cuts); Vtx z [cm]; Counts", 120, -30, 30);
+  fListOfObjects->Add(fVtxBeforeCuts);
+  
+  fVtxAfterCuts = new TH1F("fVtxAfterCuts", "Vtx distribution (before cuts); Vtx z [cm]; Counts", 120, -30, 30);
+  fListOfObjects->Add(fVtxAfterCuts);
+
+  if (fAnalysisMC) {    
+    fVtxMC = new TH1I("fVtxMC","Vtx info - no trigger cut (0=no, 1=yes); Vtx; Counts", 2, -0.5, 1.5);
+    fListOfObjects->Add(fVtxMC);
+  }
+
+  if (fTreeOption) {
+
+    fTree = new TTree("tree","Event data");
+    fEvent = new DeDxEvent();
+    fTree->Branch("event", &fEvent);
+
+    fTrackArrayGlobalPar = new TClonesArray("DeDxTrack", 1000);
+    fTree->Bronch("trackGlobalPar", "TClonesArray", &fTrackArrayGlobalPar);
+    if(fTPCBranch){
+      fTrackArrayTPCPar = new TClonesArray("DeDxTrack", 1000);
+      fTree->Bronch("trackTPCPar", "TClonesArray", &fTrackArrayTPCPar);
+    }
+
+    fVZEROArray = new TClonesArray("VZEROCell", 1000);
+    fTree->Bronch("cellVZERO", "TClonesArray", &fVZEROArray);
+
+    if (fAnalysisMC) {    
+      fTrackArrayMC = new TClonesArray("DeDxTrackMC", 1000);
+      fTree->Bronch("trackMC", "TClonesArray", &fTrackArrayMC);
+    }
+
+    fTree->SetDirectory(0);
+
+    fListOfObjects->Add(fTree);
+
+  }
+
+  // Post output data.
+  PostData(1, fListOfObjects);
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::UserExec(Option_t *) 
+{
+  // Main loop
+
+  //
+  // First we make sure that we have valid input(s)!
+  //
+  AliVEvent *event = InputEvent();
+  if (!event) {
+     Error("UserExec", "Could not retrieve event");
+     return;
+  }
+
+
+  if (fAnalysisType == "ESD"){
+    fESD = dynamic_cast<AliESDEvent*>(event);
+    if(!fESD){
+      Printf("%s:%d ESDEvent not found in Input Manager",(char*)__FILE__,__LINE__);
+      this->Dump();
+      return;
+    }    
+  } else {
+    fAOD = dynamic_cast<AliAODEvent*>(event);
+    if(!fAOD){
+      Printf("%s:%d AODEvent not found in Input Manager",(char*)__FILE__,__LINE__);
+      this->Dump();
+      return;
+    }    
+  }
+
+
+
+  if (fAnalysisMC) {
+
+    if (fAnalysisType == "ESD"){
+      fMC = dynamic_cast<AliMCEvent*>(MCEvent());
+      if(!fMC){
+       Printf("%s:%d MCEvent not found in Input Manager",(char*)__FILE__,__LINE__);
+       this->Dump();
+       return;
+      }    
+
+      fMCStack = fMC->Stack();
+      
+      if(!fMCStack){
+       Printf("%s:%d MCStack not found in Input Manager",(char*)__FILE__,__LINE__);
+       this->Dump();
+       return;
+      }    
+    } else { // AOD
+
+      fMC = dynamic_cast<AliMCEvent*>(MCEvent());
+      if(fMC)
+       fMC->Dump();
+
+      fMCArray = (TClonesArray*)fAOD->FindListObject("mcparticles");
+      if(!fMCArray){
+       Printf("%s:%d AOD MC array not found in Input Manager",(char*)__FILE__,__LINE__);
+       this->Dump();
+       return;
+      }    
+    }
+  }
+
+  
+  // Get trigger decision
+  fTriggeredEventMB = 0; //init
+
+  if(((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))
+     ->IsEventSelected() & ftrigBit1 ){
+    fn1->Fill(1);
+    fTriggeredEventMB = 1;  //event triggered as minimum bias
+  }
+  if(((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))
+     ->IsEventSelected() & ftrigBit2 ){
+    // From AliVEvent:
+    //    kINT7         = BIT(1), // V0AND trigger, offline V0 selection
+    fTriggeredEventMB += 2;  
+    fn2->Fill(1);
+  }
+
+
+  // Get process type for MC
+  fMcProcessType = 0; // -1=invalid, 0=data, 1=ND, 2=SD, 3=DD
+
+  // real data that are not triggered we skip
+  if(!fAnalysisMC && !fTriggeredEventMB)
+    return; 
+  
+  if (fAnalysisMC) {
+    
+    if (fAnalysisType == "ESD"){
+
+      AliHeader* headerMC = fMC->Header();
+      if (headerMC) {
+       
+       AliGenEventHeader* genHeader = headerMC->GenEventHeader();
+       TArrayF vtxMC(3); // primary vertex  MC 
+       vtxMC[0]=9999; vtxMC[1]=9999;  vtxMC[2]=9999; //initialize with dummy
+       if (genHeader) {
+         genHeader->PrimaryVertex(vtxMC);
+       }
+       fZvtxMC = vtxMC[2];
+       
+       // PYTHIA:
+       AliGenPythiaEventHeader* pythiaGenHeader =
+         dynamic_cast<AliGenPythiaEventHeader*>(headerMC->GenEventHeader());
+       if (pythiaGenHeader) {  //works only for pythia
+         fMcProcessType =  GetPythiaEventProcessType(pythiaGenHeader->ProcessType());
+       }
+       // PHOJET:
+       AliGenDPMjetEventHeader* dpmJetGenHeader =
+         dynamic_cast<AliGenDPMjetEventHeader*>(headerMC->GenEventHeader());
+       if (dpmJetGenHeader) {
+         fMcProcessType = GetDPMjetEventProcessType(dpmJetGenHeader->ProcessType());
+       }
+      }
+    } else { // AOD
+      
+      AliAODMCHeader* mcHeader = dynamic_cast<AliAODMCHeader*>(fAOD->FindListObject("mcHeader")); 
+      if(mcHeader) {
+       fZvtxMC = mcHeader->GetVtxZ();
+       
+       if(strstr(mcHeader->GetGeneratorName(), "Pythia")) {
+         fMcProcessType =  GetPythiaEventProcessType(mcHeader->GetEventType());
+       } else {
+         fMcProcessType =  GetDPMjetEventProcessType(mcHeader->GetEventType());
+       }
+      }
+    }
+  }
+  
+  // There are 3 cases
+  // Vertex: NO  - status -1
+  // Vertex: YES : outside cut - status 0
+  //             : inside cut  - status 1
+  // We have to be careful how we normalize because we probably want to
+  // normalize to:
+  // Nevents=(No vertex + outside + inside)/(out + in)*in
+  
+  
+  if (fAnalysisType == "ESD")
+    fZvtx = GetVertex(fESD);
+  else // AOD
+    fZvtx = GetVertex(fAOD);
+    
+  fVtxStatus = -999;
+  
+  if(fZvtx<-990) {
+    
+    fVtxStatus = -1;
+    if(fTriggeredEventMB)
+      fVtx->Fill(0);
+    if(fAnalysisMC)
+      fVtxMC->Fill(0);
+  } else {
+    
+    if(fTriggeredEventMB)
+      fVtx->Fill(1);
+    if(fAnalysisMC)
+      fVtxMC->Fill(1);
+    fVtxBeforeCuts->Fill(fZvtx);
+    fVtxStatus = 0;
+    if (TMath::Abs(fZvtx) < fVtxCut) { 
+      fVtxAfterCuts->Fill(fZvtx);
+      fVtxStatus = 1;
+    }
+  }
+  
+  // store MC event data no matter what
+  if(fAnalysisMC) {
+
+    if (fAnalysisType == "ESD") {
+      ProcessMCTruthESD();
+    } else { // AOD
+      ProcessMCTruthAOD();
+    }
+  }      
+  
+
+
+  Float_t centrality = -10;
+  // only analyze triggered events
+  if(fTriggeredEventMB) {
+    
+    if (fAnalysisType == "ESD"){
+      if(fAnalysisPbPb){
+       AliCentrality *centObject = fESD->GetCentrality();
+       centrality = centObject->GetCentralityPercentile("V0M"); 
+       if((centrality>fMaxCent)||(centrality<fMinCent))return;
+      }
+      fcent->Fill(centrality);
+      AnalyzeESD(fESD);
+    } else { // AOD
+      if(fAnalysisPbPb){
+       AliCentrality *centObject = fAOD->GetCentrality();
+       if(centObject)
+         centrality = centObject->GetCentralityPercentile("V0M"); 
+       if((centrality>fMaxCent)||(centrality<fMinCent))return;
+      }
+      fcent->Fill(centrality);
+      AnalyzeAOD(fAOD);
+    }
+  }
+
+  if( fTreeOption) {
+    
+    fEvent->process = fMcProcessType;
+    fEvent->trig    = fTriggeredEventMB;
+    fEvent->zvtxMC  = fZvtxMC;
+    fEvent->cent      = centrality;
+
+    fTree->Fill();
+    fTrackArrayGlobalPar->Clear();
+    if(fTPCBranch)
+      fTrackArrayTPCPar->Clear();
+    fVZEROArray->Clear();
+
+    if (fAnalysisMC)    
+      fTrackArrayMC->Clear();
+  }
+  
+  // Post output data.
+  PostData(1, fListOfObjects);
+}
+
+//________________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::AnalyzeESD(AliESDEvent* esdEvent)
+{
+  fRun  = esdEvent->GetRunNumber();
+  fEventId = 0;
+  if(esdEvent->GetHeader())
+    fEventId = GetEventIdAsLong(esdEvent->GetHeader());
+  
+  Short_t isPileup = esdEvent->IsPileupFromSPD();
+  
+  //  Int_t     event     = esdEvent->GetEventNumberInFile();
+  UInt_t    time      = esdEvent->GetTimeStamp();
+  //  ULong64_t trigger   = esdEvent->GetTriggerMask();
+  Float_t   magf      = esdEvent->GetMagneticField();
+
+
+
+
+
+  if(fTriggeredEventMB) {// Only MC case can we have not triggered events
+    
+    // accepted event
+    fEvents->Fill(0);
+    
+    
+    if(fVtxStatus!=1) return; // accepted vertex
+    Int_t nESDTracks = esdEvent->GetNumberOfTracks();
+    
+    if(nESDTracks<1)return;
+    cout<<"Multiplicity="<<nESDTracks<<endl;
+    
+    ProduceArrayTrksESD( esdEvent, kGlobalTrk );//produce array with global track parameters
+    if(fTPCBranch)
+      ProduceArrayTrksESD( esdEvent, kTPCTrk );//array with tpc track parametes
+
+    fEvents->Fill(1);
+    AliESDVZERO *esdV0 = esdEvent->GetVZEROData();// loop sobre canales del V0 para obtener las multiplicidad
+
+    for (Int_t iCh=0; iCh<64; ++iCh) { 
+      Float_t multv=esdV0->GetMultiplicity(iCh); 
+      Int_t intexv=iCh;
+      VZEROCell* cellv0 = new((*fVZEROArray)[iCh]) VZEROCell();
+      cellv0->cellindex=intexv;
+      cellv0->cellmult= multv;
+    }   
+
+
+
+  } // end if triggered
+  
+  if(fTreeOption) {
+
+    fEvent->run       = fRun;
+    fEvent->eventid   = fEventId;
+    fEvent->time      = time;
+    //fEvent->cent      = centrality;
+    fEvent->mag       = magf;
+    fEvent->zvtx      = fZvtx;
+    fEvent->vtxstatus = fVtxStatus;
+    fEvent->pileup    = isPileup;
+
+  }
+
+
+
+
+}
+
+//________________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::AnalyzeAOD(AliAODEvent* aodEvent)
+{
+  fRun  = aodEvent->GetRunNumber();
+  fEventId = 0;
+  if(aodEvent->GetHeader())
+    fEventId = GetEventIdAsLong(aodEvent->GetHeader());
+   
+  UInt_t    time      = 0; // Missing AOD info? aodEvent->GetTimeStamp();
+  Float_t   magf      = aodEvent->GetMagneticField();
+
+  //Int_t     trackmult = 0; // no pt cuts
+  //Int_t     nadded    = 0;
+
+  Short_t isPileup = aodEvent->IsPileupFromSPD();
+
+
+
+
+  if(fTriggeredEventMB) {// Only MC case can we have not triggered events
+    
+    // accepted event
+    fEvents->Fill(0);
+    
+    if(fVtxStatus!=1) return; // accepted vertex
+    Int_t nAODTracks = aodEvent->GetNumberOfTracks();
+    if(nAODTracks<1)return;      
+
+    ProduceArrayTrksAOD( aodEvent, kGlobalTrk );
+    if(fTPCBranch)
+      ProduceArrayTrksAOD( aodEvent, kTPCTrk );
+    fEvents->Fill(1);
+
+    AliAODVZERO *esdV0 = aodEvent->GetVZEROData();// loop sobre canales del V0 para obtener las multiplicidad
+
+    for (Int_t iCh=0; iCh<64; ++iCh) { 
+      Float_t multv=esdV0->GetMultiplicity(iCh); 
+      Int_t intexv=iCh;
+      VZEROCell* cellv0 = new((*fVZEROArray)[iCh]) VZEROCell();
+      cellv0->cellindex=intexv;
+      cellv0->cellmult= multv;
+    }   
+
+
+
+
+  } // end if triggered
+  
+  if(fTreeOption) {
+
+    //Sort(fTrackArrayGlobalPar, kFALSE);
+
+    fEvent->run       = fRun;
+    fEvent->eventid   = fEventId;
+    fEvent->time      = time;
+    //fEvent->cent      = centrality;
+    fEvent->mag       = magf;
+    fEvent->zvtx      = fZvtx;
+    fEvent->vtxstatus = fVtxStatus;
+    //fEvent->trackmult = trackmult;
+    //fEvent->n         = nadded;
+    fEvent->pileup    = isPileup;
+  }
+}
+
+//_____________________________________________________________________________
+Float_t AliAnalysisTaskHighPtDeDx::GetVertex(const AliVEvent* event) const
+{
+  Float_t zvtx = -999;
+  
+  const AliVVertex* primaryVertex = event->GetPrimaryVertex(); 
+  
+  if(primaryVertex->GetNContributors()>0)
+    zvtx = primaryVertex->GetZ();
+
+  return zvtx;
+}
+
+//_____________________________________________________________________________
+Short_t AliAnalysisTaskHighPtDeDx::GetPidCode(Int_t pdgCode) const 
+{
+  // return our internal code for pions, kaons, and protons
+  
+  Short_t pidCode = 6;
+  
+  switch (TMath::Abs(pdgCode)) {
+  case 211:
+    pidCode = 1; // pion
+    break;
+  case 321:
+    pidCode = 2; // kaon
+    break;
+  case 2212:
+    pidCode = 3; // proton
+    break;
+  case 11:
+    pidCode = 4; // electron
+    break;
+  case 13:
+    pidCode = 5; // muon
+    break;
+  default:
+    pidCode = 6;  // something else?
+  };
+  
+  return pidCode;
+}
+
+
+//_____________________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::ProcessMCTruthESD() 
+{
+  // Fill the special MC histogram with the MC truth info
+  
+  Short_t trackmult = 0;
+  Short_t nadded    = 0;
+  const Int_t nTracksMC = fMCStack->GetNtrack();
+  
+  for (Int_t iTracks = 0; iTracks < nTracksMC; iTracks++) {
+    
+    //Cuts
+    if(!(fMCStack->IsPhysicalPrimary(iTracks)))
+      continue;
+    
+    TParticle* trackMC = fMCStack->Particle(iTracks);
+    
+    Double_t chargeMC = trackMC->GetPDG()->Charge();
+    if (chargeMC == 0)
+      continue;
+    
+    if (TMath::Abs(trackMC->Eta()) > fEtaCut )
+      continue;
+    
+    trackmult++;
+    
+    //   "charge:pt:p:eta:phi:pidCode"
+    Float_t ptMC      = trackMC->Pt();
+    Float_t pMC       = trackMC->P();
+    Float_t etaMC     = trackMC->Eta();
+    Float_t phiMC     = trackMC->Phi();
+    
+    Int_t pdgCode = trackMC->GetPdgCode();
+    Short_t pidCodeMC = 0;
+    pidCodeMC = GetPidCode(pdgCode);
+    
+    // Here we want to add some of the MC histograms!
+    
+    // And therefore we first cut here!
+    if (trackMC->Pt() < fMinPt) {
+      
+      // Keep small fraction of low pT tracks
+      if(fRandom->Rndm() > fLowPtFraction)
+       continue;
+    } // else {
+    // Here we want to add the high pt part of the MC histograms!
+    //    }
+    
+    if(fTreeOption) {
+      
+      DeDxTrackMC* track = new((*fTrackArrayMC)[nadded]) DeDxTrackMC();
+      nadded++;
+      
+      track->pMC   = pMC;
+      track->ptMC  = ptMC;
+      track->etaMC = etaMC;
+      track->phiMC = phiMC;
+      track->qMC   = Short_t(chargeMC);
+      track->pidMC = pidCodeMC;
+      track->pdgMC = pdgCode;
+    }
+    
+  }//MC track loop
+  
+  if(fTreeOption) {
+    
+    Sort(fTrackArrayMC, kTRUE);
+
+    fEvent->trackmultMC = trackmult;
+    fEvent->nMC         = nadded;
+  }
+  
+}
+
+//_____________________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::ProcessMCTruthAOD() 
+{
+  // Fill the special MC histogram with the MC truth info
+
+  Short_t trackmult = 0;
+  Short_t nadded    = 0;
+  const Int_t nTracksMC = fMCArray->GetEntriesFast();
+  
+  for (Int_t iTracks = 0; iTracks < nTracksMC; iTracks++) {
+    
+    AliAODMCParticle* trackMC = dynamic_cast<AliAODMCParticle*>(fMCArray->At(iTracks));
+    
+    //Cuts
+    if(!(trackMC->IsPhysicalPrimary()))
+      continue;
+    
+    
+    Double_t chargeMC = trackMC->Charge();
+    if (chargeMC == 0)
+      continue;
+    
+    if (TMath::Abs(trackMC->Eta()) > fEtaCut )
+      continue;
+    
+    trackmult++;
+    
+    //   "charge:pt:p:eta:phi:pidCode"
+    Float_t ptMC      = trackMC->Pt();
+    Float_t pMC       = trackMC->P();
+    Float_t etaMC     = trackMC->Eta();
+    Float_t phiMC     = trackMC->Phi();
+    
+    Int_t pdgCode = trackMC->PdgCode();
+    Short_t pidCodeMC = 0;
+    pidCodeMC = GetPidCode(pdgCode);
+    
+    // Here we want to add some of the MC histograms!
+    
+    // And therefore we first cut here!
+    if (trackMC->Pt() < fMinPt) {
+      
+      // Keep small fraction of low pT tracks
+      if(fRandom->Rndm() > fLowPtFraction)
+       continue;
+    } // else {
+    // Here we want to add the high pt part of the MC histograms!
+    //    }
+    
+    if(fTreeOption) {
+      
+      DeDxTrackMC* track = new((*fTrackArrayMC)[nadded]) DeDxTrackMC();
+      nadded++;
+      
+      track->pMC   = pMC;
+      track->ptMC  = ptMC;
+      track->etaMC = etaMC;
+      track->phiMC = phiMC;
+      track->qMC   = Short_t(chargeMC);
+      track->pidMC = pidCodeMC;
+      track->pdgMC = pdgCode;
+    }
+    
+  }//MC track loop
+  
+  if(fTreeOption) {
+    
+    Sort(fTrackArrayMC, kTRUE);
+
+    fEvent->trackmultMC = trackmult;
+    fEvent->nMC         = nadded;
+  }
+  
+}
+
+//_____________________________________________________________________________
+Short_t AliAnalysisTaskHighPtDeDx::GetPythiaEventProcessType(Int_t pythiaType) {
+  //
+  // Get the process type of the event.  PYTHIA
+  //
+  // source PWG0   dNdpt 
+
+  Short_t globalType = -1; //init
+      
+  if(pythiaType==92||pythiaType==93){
+    globalType = 2; //single diffractive
+  }
+  else if(pythiaType==94){
+    globalType = 3; //double diffractive
+  }
+  //else if(pythiaType != 91){ // also exclude elastic to be sure... CKB??
+  else {
+    globalType = 1;  //non diffractive
+  }
+  return globalType;
+}
+
+//_____________________________________________________________________________
+Short_t AliAnalysisTaskHighPtDeDx::GetDPMjetEventProcessType(Int_t dpmJetType) {
+  //
+  // get the process type of the event.  PHOJET
+  //
+  //source PWG0   dNdpt 
+  // can only read pythia headers, either directly or from cocktalil header
+  Short_t globalType = -1;
+  
+  if (dpmJetType == 1 || dpmJetType == 4) { // explicitly inelastic plus central diffraction
+    globalType = 1;
+  }
+  else if (dpmJetType==5 || dpmJetType==6) {
+    globalType = 2;
+  }
+  else if (dpmJetType==7) {
+    globalType = 3;
+  }
+  return globalType;
+}
+
+//_____________________________________________________________________________
+ULong64_t AliAnalysisTaskHighPtDeDx::GetEventIdAsLong(AliVHeader* header) const
+{
+  // To have a unique id for each event in a run!
+  // Modified from AliRawReader.h
+  return ((ULong64_t)header->GetBunchCrossNumber()+
+         (ULong64_t)header->GetOrbitNumber()*3564+
+         (ULong64_t)header->GetPeriodNumber()*16777215*3564);
+}
+
+
+//____________________________________________________________________
+TParticle* AliAnalysisTaskHighPtDeDx::FindPrimaryMother(AliStack* stack, Int_t label)
+{
+  //
+  // Finds the first mother among the primary particles of the particle identified by <label>,
+  // i.e. the primary that "caused" this particle
+  //
+  // Taken from AliPWG0Helper class
+  //
+
+  Int_t motherLabel = FindPrimaryMotherLabel(stack, label);
+  if (motherLabel < 0)
+    return 0;
+
+  return stack->Particle(motherLabel);
+}
+
+//____________________________________________________________________
+Int_t AliAnalysisTaskHighPtDeDx::FindPrimaryMotherLabel(AliStack* stack, Int_t label)
+{
+  //
+  // Finds the first mother among the primary particles of the particle identified by <label>,
+  // i.e. the primary that "caused" this particle
+  //
+  // returns its label
+  //
+  // Taken from AliPWG0Helper class
+  //
+  const Int_t nPrim  = stack->GetNprimary();
+  
+  while (label >= nPrim) {
+
+    //printf("Particle %d (pdg %d) is not a primary. Let's check its mother %d\n", label, mother->GetPdgCode(), mother->GetMother(0));
+
+    TParticle* particle = stack->Particle(label);
+    if (!particle) {
+      
+      AliDebugGeneral("FindPrimaryMotherLabel", AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack.", label));
+      return -1;
+    }
+    
+    // find mother
+    if (particle->GetMother(0) < 0) {
+
+      AliDebugGeneral("FindPrimaryMotherLabel", AliLog::kError, Form("UNEXPECTED: Could not find mother of secondary particle %d.", label));
+      return -1;
+    }
+    
+    label = particle->GetMother(0);
+  }
+  
+  return label;
+}
+
+//____________________________________________________________________
+AliAODMCParticle* AliAnalysisTaskHighPtDeDx::FindPrimaryMotherAOD(AliAODMCParticle* startParticle)
+{
+  //
+  // Finds the first mother among the primary particles of the particle identified by <label>,
+  // i.e. the primary that "caused" this particle
+  //
+  // Taken from AliPWG0Helper class
+  //
+
+  AliAODMCParticle* mcPart = startParticle;
+
+  while (mcPart)
+    {
+      
+      if(mcPart->IsPrimary())
+       return mcPart;
+      
+      Int_t mother = mcPart->GetMother();
+
+      mcPart = dynamic_cast<AliAODMCParticle*>(fMCArray->At(mother));
+    }
+
+  return 0;
+}
+//_____________________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::Sort(TClonesArray* array, Bool_t isMC) 
+{
+  const Int_t n = array->GetEntriesFast(); 
+  if(n==0) {
+
+    if(isMC) 
+      fEvent->ptmaxMC = 0;
+    else
+      fEvent->ptmax   = 0;
+      
+    return;
+  }
+
+  Float_t ptArray[n];
+  Int_t   indexArray[n];
+  
+  for(Int_t i = 0; i < n; i++) {
+
+    Float_t pt = 0;
+    if(isMC) {
+      DeDxTrackMC* track = (DeDxTrackMC*)array->At(i);
+      pt = track->ptMC;
+    } else {
+      DeDxTrack* track = (DeDxTrack*)array->At(i);
+      pt = track->pt;
+    }
+    ptArray[i]    = pt;
+    indexArray[i] = i;
+  }
+
+  TMath::Sort(n, ptArray, indexArray);
+  
+  // set max pt
+  if(isMC) {
+    DeDxTrackMC* track = (DeDxTrackMC*)array->At(indexArray[0]);
+    fEvent->ptmaxMC = track->ptMC;
+  } else {
+    DeDxTrack* track = (DeDxTrack*)array->At(indexArray[0]);
+    fEvent->ptmax   = track->pt;
+  }
+  
+  // set order of each track
+  for(Int_t i = 0; i < n; i++) {
+    
+    if(isMC) {
+      DeDxTrackMC* track = (DeDxTrackMC*)array->At(indexArray[i]);
+      track->orderMC = i;
+    } else {
+      DeDxTrack* track = (DeDxTrack*)array->At(indexArray[i]);
+      track->order = i;
+    }
+  }
+}
+//__________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::ProduceArrayTrksESD( AliESDEvent *ESDevent, AnalysisMode analysisMode ){
+  
+  const Int_t nESDTracks = ESDevent->GetNumberOfTracks();
+  Int_t trackmult=0;
+  Int_t nadded=0;
+  if( analysisMode == kGlobalTrk ){
+    if(fTrackArrayGlobalPar)
+      fTrackArrayGlobalPar->Clear();
+  } else if( analysisMode == kTPCTrk ){
+    if(fTrackArrayTPCPar)
+      fTrackArrayTPCPar->Clear();
+  }
+  
+  if( analysisMode==kGlobalTrk ){  
+    
+    for(Int_t iT = 0; iT < nESDTracks; iT++) {
+      
+      AliESDtrack* esdTrack = ESDevent->GetTrack(iT);
+      
+      
+      if(TMath::Abs(esdTrack->Eta()) > fEtaCut)
+       continue;
+      
+      UShort_t filterFlag = 0;
+      Bool_t filterCut_Set1 = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+      Bool_t filterCut_Set2 = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+      Bool_t filterCut_Set3 = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+      
+      UInt_t selectDebug = 0;
+      if (fTrackFilterGolden) {
+       selectDebug = fTrackFilterGolden->IsSelected(esdTrack);
+       if (selectDebug) {
+         filterFlag +=1;
+         filterCut_Set3=kTRUE;
+       }
+      }
+      
+      if (fTrackFilterTPC) {
+       
+       selectDebug = fTrackFilterTPC->IsSelected(esdTrack);
+       if (selectDebug){//only tracks which pass the TPC-only track cuts
+         trackmult++;
+         filterFlag +=2;
+         filterCut_Set1=kTRUE;
+         
+       }
+       
+      }
+      
+      if (fTrackFilter) {
+       selectDebug = fTrackFilter->IsSelected(esdTrack);
+       if (selectDebug) {
+         filterCut_Set2=kTRUE;
+       }
+      }
+      
+     
+      if(filterFlag==0)
+       continue;
+      
+      
+      //
+      // Track was accepted
+      //      
+      
+      // Here we want to add histograms!
+      
+      if (esdTrack->Pt() < fMinPt) {
+       
+       // Keep small fraction of low pT tracks
+       if(fRandom->Rndm() > fLowPtFraction)
+         continue;
+      } // else {
+      // Here we want to add the high pt part of the histograms!
+      //    }
+    
+      Short_t charge  = esdTrack->Charge();
+      Float_t pt      = esdTrack->Pt();
+      Float_t p       = esdTrack->P(); 
+      Float_t eta     = esdTrack->Eta();
+      Float_t phi     = esdTrack->Phi();
+      Short_t ncl     = esdTrack->GetTPCsignalN();
+      Short_t neff    = Short_t(esdTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      //         Short_t nclf    = esdTrack->GetTPCNclsF();
+      Float_t dedx    = esdTrack->GetTPCsignal();
+      Float_t tpcchi  = 0;
+      if(esdTrack->GetTPCNcls() > 0)
+       tpcchi = esdTrack->GetTPCchi2()/Float_t(esdTrack->GetTPCNcls());
+      Float_t b[2];
+      Float_t bCov[3];
+      esdTrack->GetImpactParameters(b,bCov);
+      Float_t dcaxy   = b[0];
+      Float_t dcaz    = b[1];
+      Double_t p_con[3] = {0, 0, 0};
+      esdTrack->GetConstrainedPxPyPz(p_con);
+      
+      
+      //       Float_t pt_con = (Float_t)TMath::Sqrt(p_con[0]*p_con[0] + p_con[1]*p_con[1]);
+      // const AliExternalTrackParam* tpcParam = esdTrack->GetTPCInnerParam();
+      // Float_t pttpc   = tpcParam->Pt();
+      // Float_t ptpc    = tpcParam->P();
+      
+      Float_t ptMC        = 0;
+      Short_t pidCode     = 0; // 0 = real data / no mc track!
+      Short_t primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   pdgMother   = 0;
+      
+      
+      //with Globaltrack parameters????
+      if(fAnalysisMC) {
+       
+       const Int_t label = TMath::Abs(esdTrack->GetLabel());
+       TParticle* mcTrack = fMCStack->Particle(label);     
+       if (mcTrack){
+         
+         if(fMCStack->IsPhysicalPrimary(label))
+           primaryFlag = 1;
+         
+         Int_t pdgCode = mcTrack->GetPdgCode();
+         pidCode = GetPidCode(pdgCode);
+         
+         ptMC      = mcTrack->Pt();
+         
+         TParticle* mother = FindPrimaryMother(fMCStack, label);
+         pdgMother = mother->GetPdgCode();
+       }
+      }
+      
+    
+      //TOF
+      Float_t beta = -99;
+      if (esdTrack->GetStatus()&AliESDtrack::kTOFpid){
+       if ((esdTrack->GetIntegratedLength() != 0) && (esdTrack->GetTOFsignal() != 0))
+         beta = esdTrack->GetIntegratedLength()/esdTrack->GetTOFsignal()/fgkClight;
+      }
+      
+      if(fTreeOption) {
+       
+       DeDxTrack* track = new((*fTrackArrayGlobalPar)[nadded]) DeDxTrack();
+       nadded++;
+       
+       track->p          = p;
+       track->pt         = pt;
+       //        track->ptcon   = pt_con;
+       //        track->tpcchi  = tpcchi;
+       track->eta        = eta;
+       track->phi        = phi;
+       track->q          = charge;
+       track->filter     = filterFlag;
+       track->ncl        = ncl;
+       track->neff       = neff;
+       track->dedx       = dedx;
+       track->beta       = beta;
+       track->dcaxy      = dcaxy;
+       track->dcaz       = dcaz;
+       track->pid        = pidCode;
+       track->primary    = primaryFlag;
+       track->pttrue     = ptMC;
+       track->mother     = pdgMother;
+       track->filterset1 = filterCut_Set1;
+       track->filterset2 = filterCut_Set2;
+       track->filterset3 = filterCut_Set3;
+       
+       
+      }
+    }//end of track loop
+
+  }//end global
+  
+  else if( analysisMode==kTPCTrk ){  
+    const AliESDVertex *vtxSPD = ESDevent->GetPrimaryVertexSPD();
+    if( vtxSPD->GetNContributors() < 1 || TMath::Abs(vtxSPD->GetZ()) > 10.0 ) return;
+
+    for(Int_t iT = 0; iT < nESDTracks; iT++) {
+      
+      AliESDtrack* esdTrack = ESDevent->GetTrack(iT);
+
+      AliESDtrack *trackTPC = AliESDtrackCuts::GetTPCOnlyTrack(dynamic_cast<AliESDEvent*>(ESDevent),esdTrack->GetID());
+      
+      if(!trackTPC) continue;
+    
+      UInt_t selectDebug = 0;
+      selectDebug = fTrackFilterTPC->IsSelected(trackTPC);
+      if(selectDebug==0) continue;
+    
+      if(trackTPC->Pt()>0.){
+       // only constrain tracks above threshold
+       AliExternalTrackParam exParam;
+       // take the B-field from the ESD, no 3D fieldMap available at this point
+       Bool_t relate = false;
+       relate = trackTPC->RelateToVertexTPC(vtxSPD,ESDevent->GetMagneticField(),
+                                          kVeryBig,&exParam);
+       if(!relate){
+         delete trackTPC;
+         continue;
+       }
+       trackTPC->Set(exParam.GetX(),exParam.GetAlpha(),exParam.GetParameter(),
+                     exParam.GetCovariance());
+      }
+      else continue;     
+      
+
+
+      if(TMath::Abs(trackTPC->Eta()) > fEtaCut)
+       continue;
+      
+      //
+      // Track was accepted
+      //      
+      
+      // Here we want to add histograms!
+      
+      if (trackTPC->Pt() < fMinPt) {
+       
+       // Keep small fraction of low pT tracks
+       if(fRandom->Rndm() > fLowPtFraction)
+         continue;
+      } // else {
+      // Here we want to add the high pt part of the histograms!
+      //    }
+      
+      Short_t charge  = trackTPC->Charge();
+      Float_t pt      = trackTPC->Pt();
+      Float_t p       = trackTPC->P(); 
+      Float_t eta     = trackTPC->Eta();
+      Float_t phi     = trackTPC->Phi();
+      Short_t ncl     = trackTPC->GetTPCsignalN();
+      Short_t neff    = Short_t(trackTPC->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      //         Short_t nclf    = esdTrack->GetTPCNclsF();
+      Float_t dedx    = trackTPC->GetTPCsignal();
+      Float_t tpcchi  = 0;
+      if(trackTPC->GetTPCNcls() > 0)
+       tpcchi = trackTPC->GetTPCchi2()/Float_t(trackTPC->GetTPCNcls());
+      //Float_t b[2];
+      //Float_t bCov[3];
+      //trackTPC->GetImpactParameters(b,bCov);
+      //Float_t dcaxy   = b[0];
+      //Float_t dcaz    = b[1];
+
+      Float_t dcaxy = 0.;
+      Float_t dcaz = 0.;
+      trackTPC->GetImpactParameters(dcaxy,dcaz);
+
+
+      Double_t p_con[3] = {0, 0, 0};
+      trackTPC->GetConstrainedPxPyPz(p_con);
+      
+    
+      // Float_t pt_con = (Float_t)TMath::Sqrt(p_con[0]*p_con[0] + p_con[1]*p_con[1]);
+      // const AliExternalTrackParam* tpcParam = esdTrack->GetTPCInnerParam();
+      // Float_t pttpc   = tpcParam->Pt();
+      // Float_t ptpc    = tpcParam->P();
+      
+      Float_t ptMC        = 0;
+      Short_t pidCode     = 0; // 0 = real data / no mc track!
+      Short_t primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   pdgMother   = 0;
+      
+      
+      //with Globaltrack parameters????
+      if(fAnalysisMC) {
+       
+       const Int_t label = TMath::Abs(esdTrack->GetLabel());
+       TParticle* mcTrack = fMCStack->Particle(label);     
+       if (mcTrack){
+         
+         if(fMCStack->IsPhysicalPrimary(label))
+           primaryFlag = 1;
+         
+         Int_t pdgCode = mcTrack->GetPdgCode();
+         pidCode = GetPidCode(pdgCode);
+         
+         ptMC      = mcTrack->Pt();
+         
+         TParticle* mother = FindPrimaryMother(fMCStack, label);
+         pdgMother = mother->GetPdgCode();
+       }
+      }
+    
+    
+      //TOF
+      Float_t beta = -99;
+      if (esdTrack->GetStatus()&AliESDtrack::kTOFpid){
+       if ((esdTrack->GetIntegratedLength() != 0) && (esdTrack->GetTOFsignal() != 0))
+         beta = esdTrack->GetIntegratedLength()/esdTrack->GetTOFsignal()/fgkClight;
+      }
+      
+      if(fTreeOption) {
+       
+       DeDxTrack* tracktpc = new((*fTrackArrayTPCPar)[nadded]) DeDxTrack();
+       nadded++;
+       
+       tracktpc->p          = p;
+       tracktpc->pt         = pt;
+       //        track->ptcon   = pt_con;
+       //        track->tpcchi  = tpcchi;
+       tracktpc->eta        = eta;
+       tracktpc->phi        = phi;
+       tracktpc->q          = charge;
+       tracktpc->filter     = 1;
+       tracktpc->ncl        = ncl;
+       tracktpc->neff       = neff;
+       tracktpc->dedx       = dedx;
+       tracktpc->beta       = beta;//computed with Global tracks
+       tracktpc->dcaxy      = dcaxy;
+       tracktpc->dcaz       = dcaz;
+       tracktpc->pid        = pidCode;
+       tracktpc->primary    = primaryFlag;
+       tracktpc->pttrue     = ptMC;
+       tracktpc->mother     = pdgMother;
+       tracktpc->filterset1 = 0;
+       tracktpc->filterset2 = 0;
+       tracktpc->filterset3 = 0;
+       
+      }
+
+
+      if(trackTPC)
+       delete trackTPC;
+
+
+    }//end of track loop
+  }//end of: if isglobal==kFALSE
+
+
+  if(fTreeOption) {
+
+    if( analysisMode==kGlobalTrk ){
+      Sort(fTrackArrayGlobalPar, kFALSE);
+      
+      fEvent->trackmult = trackmult;
+      fEvent->n         = nadded;
+    }
+    else if( analysisMode==kTPCTrk ){
+      Sort(fTrackArrayTPCPar, kFALSE);
+    }
+
+  }
+
+
+}
+//__________________________________________________________________
+void AliAnalysisTaskHighPtDeDx::ProduceArrayTrksAOD( AliAODEvent *AODevent, AnalysisMode analysisMode ){
+
+
+  Int_t     trackmult = 0; // no pt cuts
+  Int_t     nadded    = 0;
+  Int_t nAODTracks = AODevent->GetNumberOfTracks();
+  if( analysisMode == kGlobalTrk ){
+    
+    if(fTrackArrayGlobalPar)
+      fTrackArrayGlobalPar->Clear();
+    
+  } 
+  if( analysisMode == kTPCTrk ){
+    if(fTrackArrayTPCPar)
+      fTrackArrayTPCPar->Clear();
+  }
+
+
+
+
+  //const AliAODVertex*        vertexSPD= (AliAODVertex*)AODevent->GetPrimaryVertexSPD();//GetPrimaryVertex()
+  //if( vertexSPD->GetNContributors() < 1 || TMath::Abs( vertexSPD->GetZ()) > 10.0 ) return;
+
+
+  
+  if( analysisMode==kGlobalTrk ){  
+
+     const AliAODVertex* vertex = AODevent->GetPrimaryVertex();
+    for(Int_t iT = 0; iT < nAODTracks; iT++) {
+      
+      AliAODTrack* aodTrack = AODevent->GetTrack(iT);
+      
+      
+      UShort_t filterFlag = 0;
+      Bool_t filterCut_Set1 = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+      Bool_t filterCut_Set2 = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+      Bool_t filterCut_Set3 = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+  
+      
+      
+      if (fTrackFilterGolden) {
+       
+       // ITSTPC2010 cuts is bit 32 according to above macro, new versions of aliroot includes the golden cuts
+       if(aodTrack->TestFilterBit(32)) {
+         filterFlag +=1;
+         filterCut_Set3 = kTRUE;
+       }
+      }
+      
+      
+      if (fTrackFilterTPC) {
+       // TPC only cuts is bit 1 according to above macro
+       // Alex always uses 128, NOTE: FILTER 128 ARE TPC TRACKS (TPC PARAMETERS) CONTRAINED TO THE SPD VERTEX, 
+       if(aodTrack->TestFilterBit(1)){
+         filterFlag +=2;
+         filterCut_Set1 = kTRUE;
+         trackmult++;
+
+       }
+      }
+      
+      
+      
+      if(filterFlag==0)
+       continue;
+      
+      
+      Double_t b[2], cov[3];
+      if (!(aodTrack->PropagateToDCA(vertex, AODevent->GetMagneticField(), kVeryBig, b, cov)))
+       filterFlag = 32; // propagation failed!!!!!;
+      Float_t dcaxy   = b[0];
+      Float_t dcaz    = b[1];
+      
+
+
+
+
+      // As I understand this routine recalculates the momentum so it should be called first!
+      //Double_t b[2], cov[3];
+  
+      
+      //if(!aodTrack->PropagateToDCA(vertex, AODevent->GetMagneticField(), kVeryBig, b, cov))
+      //       filterFlag = 32; // propagation failed!!!!!
+      
+      if(TMath::Abs(aodTrack->Eta()) > fEtaCut)
+       continue;
+      if (aodTrack->Pt() < fMinPt) {
+       
+       // Keep small fraction of low pT tracks
+       if(fRandom->Rndm() > fLowPtFraction)
+         continue;
+      } // else {
+      // Here we want to add the high pt part of the histograms!
+      //    }
+     
+     
+
+      
+      Short_t charge  = aodTrack->Charge();
+      Float_t pt      = aodTrack->Pt();
+      Float_t p       = aodTrack->P(); 
+      Float_t eta     = aodTrack->Eta();
+      Float_t phi     = aodTrack->Phi();
+      AliAODPid* aodPid = aodTrack->GetDetPid();
+      Short_t ncl     = -10;
+      Short_t neff    = 0; // This is not yet there! Short_t(aodTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      //         Short_t nclf    = aodTrack->GetTPCNclsF();
+      Float_t dedx    = -10;
+      Float_t beta = -99;
+      if(aodPid) {
+       ncl     = aodPid->GetTPCsignalN();
+       dedx    = aodPid->GetTPCsignal();
+       //TOF
+       if (aodTrack->GetStatus()&AliESDtrack::kTOFpid){
+         Double_t tof[5];
+         aodPid->GetIntegratedTimes(tof);
+         beta = tof[0]/aodPid->GetTOFsignal();
+       }
+      }
+      //       Float_t tpcchi = aodTrack->Chi2perNDF();
+      
+      // Double_t p_con[3] = {0, 0, 0};
+      // aodTrack->GetConstrainedPxPyPz(p_con);
+      //       Float_t pt_con = 0; // This is not there! (Float_t)TMath::Sqrt(p_con[0]*p_con[0] + p_con[1]*p_con[1]);
+      // const AliExternalTrackParam* tpcParam = aodTrack->GetTPCInnerParam();
+      // Float_t pttpc   = tpcParam->Pt();
+      // Float_t ptpc    = tpcParam->P();
+      
+      Float_t ptMC        = 0;
+      Short_t pidCode     = 0; // 0 = real data / no mc track!
+      Short_t primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   pdgMother   = 0;
+      
+      if(fAnalysisMC) {
+       
+       const Int_t label = TMath::Abs(aodTrack->GetLabel());
+       
+       AliAODMCParticle* mcTrack = dynamic_cast<AliAODMCParticle*>(fMCArray->At(label));
+       if (mcTrack){
+         
+         if(mcTrack->IsPhysicalPrimary())
+           primaryFlag = 1;
+         
+         Int_t pdgCode = mcTrack->GetPdgCode();
+         pidCode = GetPidCode(pdgCode);
+         
+         ptMC      = mcTrack->Pt();
+         
+         AliAODMCParticle* mother = FindPrimaryMotherAOD(mcTrack);
+         pdgMother = mother->GetPdgCode();         
+       }
+      }
+    
+    
+      if(fTreeOption) {
+       
+       DeDxTrack* track = new((*fTrackArrayGlobalPar)[nadded]) DeDxTrack();
+       nadded++;
+       
+       track->p          = p;
+       track->pt         = pt;
+       //        track->ptcon   = pt_con;
+       //        track->tpcchi  = tpcchi;
+       track->eta        = eta;
+       track->phi        = phi;
+       track->q          = charge;
+       track->filter     = filterFlag;
+       track->ncl        = ncl;
+       track->neff       = neff;
+       track->dedx       = dedx;
+       track->beta       = beta;
+       track->dcaxy      = dcaxy;
+       track->dcaz       = dcaz;
+       track->pid        = pidCode;
+       track->primary    = primaryFlag;
+       track->pttrue     = ptMC;
+       track->mother     = pdgMother;
+       track->filterset1 = filterCut_Set1;
+       track->filterset2 = filterCut_Set2;
+       track->filterset3 = filterCut_Set3;
+      }
+    }//end of track loop
+
+
+  }//end of global track analysis
+  
+
+
+  else if( analysisMode==kTPCTrk ){  
+    const AliAODVertex*        vertexSPD= (AliAODVertex*)AODevent->GetPrimaryVertexSPD();//GetPrimaryVertex()
+    if( vertexSPD->GetNContributors() < 1 || TMath::Abs(vertexSPD->GetZ()) > 10.0 ) return;
+
+
+    //const AliAODVertex* vertex = AODevent->GetPrimaryVertex();
+    for(Int_t iT = 0; iT < nAODTracks; iT++) {
+      
+      AliAODTrack* aodTrack = AODevent->GetTrack(iT);
+      
+      
+      UShort_t filterFlag = 0;
+      Bool_t filterCut_Set1 = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+      Bool_t filterCut_Set2 = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+      Bool_t filterCut_Set3 = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+  
+      
+     
+      // TPC only cuts is bit 1 according to above macro
+      // Alex always uses 128, NOTE: FILTER 128 ARE TPC TRACKS (TPC PARAMETERS) CONTRAINED TO THE SPD VERTEX, 
+      if(aodTrack->TestFilterBit(128)){
+       filterFlag +=2;
+       trackmult++;
+      }
+      
+      
+      if(filterFlag==0)
+       continue;
+      
+      
+      Double_t b[2], cov[3];
+      //AliAODVertex* vertex = AODevent->GetPrimaryVertex();
+      //Double_t b[2] = {-99., -99.};
+      //Double_t bCov[3] = {-99., -99., -99.};
+      //aodTrack->PropagateToDCA(aod->GetPrimaryVertex(), aod->GetMagneticField(), 100., b, bCov);
+      if (!(aodTrack->PropagateToDCA(vertexSPD, AODevent->GetMagneticField(), kVeryBig, b, cov)))
+       filterFlag = 32; // propagation failed!!!!!;
+      Float_t dcaxy   = b[0];
+      Float_t dcaz    = b[1];
+
+
+
+
+      // As I understand this routine recalculates the momentum so it should be called first!
+      //Double_t b[2], cov[3];
+  
+      
+      //if(!aodTrack->PropagateToDCA(vertex, AODevent->GetMagneticField(), kVeryBig, b, cov))
+      //       filterFlag = 32; // propagation failed!!!!!
+      
+      if(TMath::Abs(aodTrack->Eta()) > fEtaCut)
+       continue;
+      if (aodTrack->Pt() < fMinPt) {
+       
+       // Keep small fraction of low pT tracks
+       if(fRandom->Rndm() > fLowPtFraction)
+         continue;
+      } // else {
+      // Here we want to add the high pt part of the histograms!
+      //    }
+     
+     
+
+      
+      Short_t charge  = aodTrack->Charge();
+      Float_t pt      = aodTrack->Pt();
+      Float_t p       = aodTrack->P(); 
+      Float_t eta     = aodTrack->Eta();
+      Float_t phi     = aodTrack->Phi();
+      AliAODPid* aodPid = aodTrack->GetDetPid();
+      Short_t ncl     = -10;
+      Short_t neff    = 0; // This is not yet there! Short_t(aodTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      //         Short_t nclf    = aodTrack->GetTPCNclsF();
+      Float_t dedx    = -10;
+      Float_t beta = -99;
+      if(aodPid) {
+       ncl     = aodPid->GetTPCsignalN();
+       dedx    = aodPid->GetTPCsignal();
+       //TOF
+       if (aodTrack->GetStatus()&AliESDtrack::kTOFpid){
+         Double_t tof[5];
+         aodPid->GetIntegratedTimes(tof);
+         beta = tof[0]/aodPid->GetTOFsignal();
+       }
+      }
+      //       Float_t tpcchi = aodTrack->Chi2perNDF();
+      
+      // Double_t p_con[3] = {0, 0, 0};
+      // aodTrack->GetConstrainedPxPyPz(p_con);
+      //       Float_t pt_con = 0; // This is not there! (Float_t)TMath::Sqrt(p_con[0]*p_con[0] + p_con[1]*p_con[1]);
+      // const AliExternalTrackParam* tpcParam = aodTrack->GetTPCInnerParam();
+      // Float_t pttpc   = tpcParam->Pt();
+      // Float_t ptpc    = tpcParam->P();
+      
+      Float_t ptMC        = 0;
+      Short_t pidCode     = 0; // 0 = real data / no mc track!
+      Short_t primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   pdgMother   = 0;
+      
+      if(fAnalysisMC) {
+       
+       const Int_t label = TMath::Abs(aodTrack->GetLabel());
+       
+       AliAODMCParticle* mcTrack = dynamic_cast<AliAODMCParticle*>(fMCArray->At(label));
+       if (mcTrack){
+         
+         if(mcTrack->IsPhysicalPrimary())
+           primaryFlag = 1;
+         
+         Int_t pdgCode = mcTrack->GetPdgCode();
+         pidCode = GetPidCode(pdgCode);
+         
+         ptMC      = mcTrack->Pt();
+         
+         AliAODMCParticle* mother = FindPrimaryMotherAOD(mcTrack);
+         pdgMother = mother->GetPdgCode();         
+       }
+      }
+    
+    
+      if(fTreeOption) {
+       
+       DeDxTrack* tracktpc = new((*fTrackArrayTPCPar)[nadded]) DeDxTrack();
+       nadded++;
+       
+       tracktpc->p          = p;
+       tracktpc->pt         = pt;
+       //        track->ptcon   = pt_con;
+       //        track->tpcchi  = tpcchi;
+       tracktpc->eta        = eta;
+       tracktpc->phi        = phi;
+       tracktpc->q          = charge;
+       tracktpc->filter     = filterFlag;
+       tracktpc->ncl        = ncl;
+       tracktpc->neff       = neff;
+       tracktpc->dedx       = dedx;
+       tracktpc->beta       = beta;
+       tracktpc->dcaxy      = dcaxy;
+       tracktpc->dcaz       = dcaz;
+       tracktpc->pid        = pidCode;
+       tracktpc->primary    = primaryFlag;
+       tracktpc->pttrue     = ptMC;
+       tracktpc->mother     = pdgMother;
+       tracktpc->filterset1 = filterCut_Set1;
+       tracktpc->filterset2 = filterCut_Set2;
+       tracktpc->filterset3 = filterCut_Set3;
+      }
+    }//end of track loop
+
+
+  }//end of global track analysis
+
+
+  if(fTreeOption) {
+    
+    if( analysisMode==kGlobalTrk ){
+      Sort(fTrackArrayGlobalPar, kFALSE);
+      
+      fEvent->trackmult = trackmult;
+      fEvent->n         = nadded;
+
+
+    }
+    if( analysisMode==kTPCTrk ){
+      Sort(fTrackArrayTPCPar, kFALSE);
+    }
+    
+  }
+  
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDx.h b/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDx.h
new file mode 100644 (file)
index 0000000..c01ed87
--- /dev/null
@@ -0,0 +1,141 @@
+#ifndef ALIANALYSISTASKHIGHPTDEDX_H
+#define ALIANALYSISTASKHIGHPTDEDX_H
+
+// ROOT includes
+#include <TList.h>
+#include <TH1.h>
+#include <TTreeStream.h>
+#include <TRandom.h>
+#include <TObject.h>
+
+// AliRoot includes
+#include <AliAnalysisTaskSE.h>
+#include <AliESDEvent.h>
+#include <AliAODEvent.h>
+#include <AliMCEvent.h>
+#include <AliAnalysisFilter.h>
+#include <AliStack.h>
+#include <AliGenEventHeader.h>
+#include <AliVHeader.h>
+#include <AliAODMCParticle.h> 
+
+#include "DebugClasses.C"
+
+
+
+class AliAnalysisTaskHighPtDeDx : public AliAnalysisTaskSE {
+ public:
+  enum AnalysisMode { kInvalid = -1, kGlobalTrk = 0x1, kTPCTrk = 0x2 }; 
+  AliAnalysisTaskHighPtDeDx();
+  AliAnalysisTaskHighPtDeDx(const char *name);
+
+  virtual ~AliAnalysisTaskHighPtDeDx();
+
+  virtual void   UserCreateOutputObjects();
+  virtual void   UserExec(Option_t *option);
+
+  Bool_t   GetAnalysisMC() { return fAnalysisMC; }   
+  Double_t GetVtxCut() { return fVtxCut; }   
+  Double_t GetEtaCut() { return fEtaCut; }     
+  Double_t GetMinPt() { return fMinPt; }   
+  Int_t    GetTreeOption() { return fTreeOption; }  
+
+  virtual void  SetTrigger1(UInt_t ktriggerInt1) {ftrigBit1 = ktriggerInt1;}
+  virtual void  SetTrigger2(UInt_t ktriggerInt2) {ftrigBit2 = ktriggerInt2;}
+  virtual void  SetTrackFilter(AliAnalysisFilter* trackF) {fTrackFilter = trackF;}
+  virtual void  SetTrackFilterGolden(AliAnalysisFilter* trackF) {fTrackFilterGolden = trackF;}
+  virtual void  SetTrackFilterTPC(AliAnalysisFilter* trackF) {fTrackFilterTPC = trackF;}
+  virtual void  SetProduceTPCBranch(Bool_t prodtpcb) {fTPCBranch = prodtpcb;}
+  virtual void  SetAnalysisType(const char* analysisType) {fAnalysisType = analysisType;}
+  virtual void  SetAnalysisMC(Bool_t isMC) {fAnalysisMC = isMC;}
+  virtual void  SetVtxCut(Double_t vtxCut){fVtxCut = vtxCut;}
+  virtual void  SetEtaCut(Double_t etaCut){fEtaCut = etaCut;}
+  virtual void  SetMinPt(Double_t value) {fMinPt = value;}   
+  virtual void  SetMinCent(Float_t minvalc) {fMinCent = minvalc;}
+  virtual void  SetMaxCent(Float_t maxvalc) {fMaxCent = maxvalc;}
+  virtual void  SetLowPtFraction(Double_t value) {fLowPtFraction = value;}   
+  virtual void  SetTreeOption(Int_t value) {fTreeOption = value;}    
+  virtual void  SetAnalysisPbPb(Bool_t isanaPbPb) {fAnalysisPbPb = isanaPbPb;}
+
+ private:
+  virtual Float_t GetVertex(const AliVEvent* event) const;
+  virtual void AnalyzeESD(AliESDEvent* esd); 
+  virtual void AnalyzeAOD(AliAODEvent* aod); 
+  virtual void ProduceArrayTrksESD(AliESDEvent* event, AnalysisMode anamode );
+  virtual void ProduceArrayTrksAOD(AliAODEvent* event, AnalysisMode anamode );
+  Short_t   GetPidCode(Int_t pdgCode) const;
+  void      ProcessMCTruthESD();
+  void      ProcessMCTruthAOD(); 
+  void      Sort(TClonesArray* array, Bool_t isMC);
+  Short_t   GetPythiaEventProcessType(Int_t pythiaType);
+  Short_t   GetDPMjetEventProcessType(Int_t dpmJetType);
+  ULong64_t GetEventIdAsLong(AliVHeader* header) const;
+
+  TParticle* FindPrimaryMother(AliStack* stack, Int_t label);
+  Int_t      FindPrimaryMotherLabel(AliStack* stack, Int_t label);
+
+  AliAODMCParticle* FindPrimaryMotherAOD(AliAODMCParticle* startParticle);
+
+  static const Double_t fgkClight;   // Speed of light (cm/ps)
+
+  AliESDEvent* fESD;                  //! ESD object
+  AliAODEvent* fAOD;                  //! AOD object
+  AliMCEvent*  fMC;                   //! MC object
+  AliStack*    fMCStack;              //! MC ESD stack
+  TClonesArray* fMCArray;             //! MC array for AOD
+  AliAnalysisFilter* fTrackFilter;    //  Track Filter, old cuts 2010
+  AliAnalysisFilter* fTrackFilterGolden;    //  Track Filter, set 2010 with golden cuts
+  AliAnalysisFilter* fTrackFilterTPC; // track filter for TPC only tracks
+  TString       fAnalysisType;        //  "ESD" or "AOD"
+  Bool_t        fAnalysisMC;          //  Real(kFALSE) or MC(kTRUE) flag
+  Bool_t        fAnalysisPbPb;        //  true you want to analyze PbPb data, false for pp
+  Bool_t        fTPCBranch;           //tru if you want to produce the TPC branch
+  TRandom*      fRandom;              //! random number generator
+  DeDxEvent*    fEvent;               //! event pointer
+  TClonesArray* fTrackArrayGlobalPar;          //! track array pointer, global tracks
+  TClonesArray* fTrackArrayTPCPar;          //! track array pointer, tpc track parameters
+  TClonesArray* fTrackArrayMC;        //! MC track array pointer
+  TClonesArray* fVZEROArray;          //! array of the v0 cells.
+
+
+  //
+  // Cuts and options
+  //
+  UInt_t       ftrigBit1;
+  UInt_t       ftrigBit2;
+  Double_t     fVtxCut;             // Vtx cut on z position in cm
+  Double_t     fEtaCut;             // Eta cut used to select particles
+  Double_t     fMinPt;              // Min pt - for histogram limits
+  Double_t     fLowPtFraction;      // Fraction of tracks below min pt to keep
+  Int_t        fTreeOption;         // 0: no tree, >0: enable debug tree
+  Float_t      fMinCent; //minimum centrality
+  Float_t      fMaxCent; //maximum centrality
+  //
+  // Help variables
+  //
+  Short_t      fMcProcessType;      // -1=invalid, 0=data, 1=ND, 2=SD, 3=DD
+  Short_t      fTriggeredEventMB;   // 1 = triggered, 0 = not trigged (MC only)
+  Short_t      fVtxStatus;          // -1 = no vtx, 0 = outside cut, 1 = inside cut
+  Float_t      fZvtx;               // z vertex
+  Float_t      fZvtxMC;             // z vertex MC (truth)
+  Int_t        fRun;                // run no
+  ULong64_t    fEventId;            // unique event id
+              
+  //
+  // Output objects
+  //
+  TList*        fListOfObjects;     //! Output list of objects
+  TH1I*         fEvents;            //! No of accepted events
+  TH1I*         fVtx;               //! Event vertex info
+  TH1I*         fVtxMC;             //! Event vertex info for ALL MC events
+  TH1F*         fVtxBeforeCuts;     //! Vertex z dist before cuts
+  TH1F*         fVtxAfterCuts;      //! Vertex z dist after cuts
+  TH1F* fn1;
+  TH1F* fn2;
+  TH1F* fcent;
+  TTree*        fTree;              //! Debug tree 
+
+  ClassDef(AliAnalysisTaskHighPtDeDx, 1);    //Analysis task for high pt analysis 
+};
+
+#endif
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDxV0.cxx b/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDxV0.cxx
new file mode 100644 (file)
index 0000000..0b3fd9a
--- /dev/null
@@ -0,0 +1,2499 @@
+#include "AliAnalysisTaskHighPtDeDxV0.h"
+
+// ROOT includes
+#include <TList.h>
+#include <TTree.h>
+#include <TMath.h>
+#include <TH1.h>
+#include <TParticle.h>
+#include <TFile.h>
+
+// AliRoot includes
+#include <AliAnalysisManager.h>
+#include <AliAnalysisFilter.h>
+#include <AliESDInputHandler.h>
+#include <AliESDEvent.h>
+#include <AliESDVertex.h>
+#include <AliLog.h>
+#include <AliExternalTrackParam.h>
+
+#include <AliMCEventHandler.h>
+#include <AliMCEvent.h>
+#include <AliStack.h>
+
+#include <AliHeader.h>
+#include <AliGenPythiaEventHeader.h>
+#include <AliGenDPMjetEventHeader.h>
+
+#include <AliAODVertex.h>
+#include <AliESDv0.h>
+#include <AliKFVertex.h>
+
+#include "AliCentrality.h" 
+#include "AliESDtrackCuts.h"
+
+#include <AliAODTrack.h> 
+#include <AliAODPid.h> 
+#include <AliAODMCHeader.h> 
+
+// STL includes
+#include <iostream>
+using namespace std;
+
+//_____________________________________________________________________________
+//
+// Responsible:
+// Peter Christiansen (Lund)
+//
+//_____________________________________________________________________________
+
+
+ClassImp(AliAnalysisTaskHighPtDeDxV0)
+
+const Double_t AliAnalysisTaskHighPtDeDxV0::fgkClight = 2.99792458e-2;
+
+//_____________________________________________________________________________
+AliAnalysisTaskHighPtDeDxV0::AliAnalysisTaskHighPtDeDxV0():
+  AliAnalysisTaskSE(),
+  fESD(0x0),
+  fAOD(0x0),
+  fMC(0x0),
+  fMCStack(0x0),
+  fMCArray(0x0),
+  fTrackFilter(0x0),
+  fTrackFilterGolden(0x0),
+  fTrackFilterTPC(0x0),
+  fAnalysisType("ESD"),
+  fAnalysisMC(kFALSE),
+  fAnalysisPbPb(kFALSE),
+  ftrigBit1(0x0),
+  ftrigBit2(0x0),
+  fEvent(0x0),
+  fV0ArrayGlobalPar(0x0),
+  fV0ArrayTPCPar(0x0),
+  fTrackArrayMC(0x0),
+  fVtxCut(10.0),  
+  fEtaCut(0.9),  
+  fMinPt(0.1),
+  fMinCent(0.0),
+  fMaxCent(100.0),
+  fMassCut(0.1),
+  fTreeOption(0),
+  fRequireRecV0(kTRUE),
+  fStoreMcIn(kFALSE),
+  fMcProcessType(-999),
+  fTriggeredEventMB(-999),
+  fVtxStatus(-999),
+  fZvtx(-999),
+  fZvtxMC(-999),
+  fRun(-999),
+  fEventId(-999),
+  fListOfObjects(0), 
+  fEvents(0x0), fVtx(0x0), fVtxMC(0x0), fVtxBeforeCuts(0x0), fVtxAfterCuts(0x0),
+  fTree(0x0),
+  fnv0(0)
+{
+  // Default constructor (should not be used)
+
+}
+
+//______________________________________________________________________________
+AliAnalysisTaskHighPtDeDxV0::AliAnalysisTaskHighPtDeDxV0(const char *name):
+  AliAnalysisTaskSE(name),
+  fESD(0x0),
+  fAOD(0x0),
+  fMC(0x0),
+  fMCStack(0x0),
+  fMCArray(0x0),
+  fTrackFilter(0x0),
+  fTrackFilterGolden(0x0),
+  fTrackFilterTPC(0x0),
+  fAnalysisType("ESD"),
+  fAnalysisMC(kFALSE),
+  fAnalysisPbPb(kFALSE),
+  ftrigBit1(0x0),
+  ftrigBit2(0x0),
+  fEvent(0x0),
+  fV0ArrayGlobalPar(0x0),
+  fV0ArrayTPCPar(0x0),
+  fTrackArrayMC(0x0),
+  fVtxCut(10.0),  
+  fEtaCut(0.9),  
+  fMinPt(0.1),
+  fMinCent(0.0),
+  fMaxCent(100.0),
+  fMassCut(0.1),
+  fTreeOption(0),
+  fRequireRecV0(kTRUE),
+  fStoreMcIn(kFALSE),
+  fMcProcessType(-999),
+  fTriggeredEventMB(-999),
+  fVtxStatus(-999),
+  fZvtx(-999),
+  fZvtxMC(-999),
+  fRun(-999),
+  fEventId(-999),
+  fListOfObjects(0), 
+  fEvents(0x0), fVtx(0x0), fVtxMC(0x0), fVtxBeforeCuts(0x0), fVtxAfterCuts(0x0),
+  fTree(0x0),
+  fnv0(0)
+{
+  // Output slot #1 writes into a TList
+  DefineOutput(1, TList::Class());
+}
+
+//_____________________________________________________________________________
+AliAnalysisTaskHighPtDeDxV0::~AliAnalysisTaskHighPtDeDxV0()
+{
+  // Destructor
+  // histograms are in the output list and deleted when the output
+  // list is deleted by the TSelector dtor
+  if (fListOfObjects && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {
+    delete fListOfObjects;
+    fListOfObjects = 0;
+  }
+  
+  // //for proof running; I cannot create tree do to memory limitations -> work with THnSparse 
+  // if (fListOfObjects  && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) delete fOutputList;
+  
+  
+  
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::UserCreateOutputObjects()
+{ 
+  // This method is called once per worker node
+  // Here we define the output: histograms and debug tree if requested 
+
+  OpenFile(1);
+  fListOfObjects = new TList();
+  fListOfObjects->SetOwner();
+  
+  //
+  // Histograms
+  //  
+  fEvents = new TH1I("fEvents","Number of analyzed events; Events; Counts", 1, 0, 1);
+  fListOfObjects->Add(fEvents);
+  
+  fVtx = new TH1I("fVtx","Vtx info (0=no, 1=yes); Vtx; Counts", 2, -0.5, 1.5);
+  fListOfObjects->Add(fVtx);
+
+  fnv0 = new TH1F("fnv0","# V0's", 10000,0,10000);
+  fListOfObjects->Add(fnv0);
+
+  fVtxBeforeCuts = new TH1F("fVtxBeforeCuts", "Vtx distribution (before cuts); Vtx z [cm]; Counts", 120, -30, 30);
+  fListOfObjects->Add(fVtxBeforeCuts);
+  
+  fVtxAfterCuts = new TH1F("fVtxAfterCuts", "Vtx distribution (before cuts); Vtx z [cm]; Counts", 120, -30, 30);
+  fListOfObjects->Add(fVtxAfterCuts);
+
+  if (fAnalysisMC) {    
+    fVtxMC = new TH1I("fVtxMC","Vtx info - no trigger cut (0=no, 1=yes); Vtx; Counts", 2, -0.5, 1.5);
+    fListOfObjects->Add(fVtxMC);
+  
+  }
+
+  if (fTreeOption) {
+
+    fTree = new TTree("tree","Event data");
+    fEvent = new DeDxEvent();
+    fTree->Branch("event", &fEvent);
+
+    fV0ArrayGlobalPar = new TClonesArray("DeDxV0", 1000);
+    fTree->Bronch("v0GlobalPar", "TClonesArray", &fV0ArrayGlobalPar);
+
+    fV0ArrayTPCPar = new TClonesArray("DeDxV0", 1000);
+    fTree->Bronch("v0TPCPar", "TClonesArray", &fV0ArrayTPCPar);
+
+    if (fAnalysisMC && fStoreMcIn) {    
+      fTrackArrayMC = new TClonesArray("DeDxTrackMC", 1000);
+      fTree->Bronch("trackMC", "TClonesArray", &fTrackArrayMC);
+    }
+
+    fTree->SetDirectory(0);
+
+    fListOfObjects->Add(fTree);
+
+  }
+
+  // Post output data.
+  PostData(1, fListOfObjects);
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::UserExec(Option_t *) 
+{
+  // Main loop
+  
+  //
+  // Comment: This method matches completely the same method for the high pT
+  // tracks
+  //
+
+
+  //
+  // First we make sure that we have valid input(s)!
+  //
+  if (fAnalysisType == "ESD"){
+    fESD = dynamic_cast<AliESDEvent*>(InputEvent());
+    if(!fESD){
+      Printf("%s:%d ESDEvent not found in Input Manager",(char*)__FILE__,__LINE__);
+      this->Dump();
+      return;
+    }    
+  } else {
+    fAOD = dynamic_cast<AliAODEvent*>(InputEvent());
+    if(!fAOD){
+      Printf("%s:%d AODEvent not found in Input Manager",(char*)__FILE__,__LINE__);
+      this->Dump();
+      return;
+    }    
+  }
+
+  if (fAnalysisMC) {
+
+    if (fAnalysisType == "ESD"){
+      fMC = dynamic_cast<AliMCEvent*>(MCEvent());
+      if(!fMC){
+       Printf("%s:%d MCEvent not found in Input Manager",(char*)__FILE__,__LINE__);
+       this->Dump();
+       return;
+      }    
+
+      fMCStack = fMC->Stack();
+      
+      if(!fMCStack){
+       Printf("%s:%d MCStack not found in Input Manager",(char*)__FILE__,__LINE__);
+       this->Dump();
+       return;
+      }    
+    } else { // AOD
+
+      fMC = dynamic_cast<AliMCEvent*>(MCEvent());
+      if(fMC)
+       fMC->Dump();
+
+      fMCArray = (TClonesArray*)fAOD->FindListObject("mcparticles");
+      if(!fMCArray){
+       Printf("%s:%d AOD MC array not found in Input Manager",(char*)__FILE__,__LINE__);
+       this->Dump();
+       return;
+      }    
+    }
+  }
+
+    // Get trigger decision
+  fTriggeredEventMB = 0; //init
+
+
+  if(((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))
+     ->IsEventSelected() & ftrigBit1 ){
+    fTriggeredEventMB = 1;  //event triggered as minimum bias
+  }
+  if(((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))
+     ->IsEventSelected() & ftrigBit2 ){
+    // From AliVEvent:
+    //    kINT7         = BIT(1), // V0AND trigger, offline V0 selection
+    fTriggeredEventMB += 2;  
+  }
+
+  
+  // Get process type for MC
+  fMcProcessType = 0; // -1=invalid, 0=data, 1=ND, 2=SD, 3=DD
+
+  // real data that are not triggered we skip
+  if(!fAnalysisMC && !fTriggeredEventMB)
+    return; 
+  
+  if (fAnalysisMC) {
+    
+    if (fAnalysisType == "ESD"){
+
+      AliHeader* headerMC = fMC->Header();
+      if (headerMC) {
+       
+       AliGenEventHeader* genHeader = headerMC->GenEventHeader();
+       TArrayF vtxMC(3); // primary vertex  MC 
+       vtxMC[0]=9999; vtxMC[1]=9999;  vtxMC[2]=9999; //initialize with dummy
+       if (genHeader) {
+         genHeader->PrimaryVertex(vtxMC);
+       }
+       fZvtxMC = vtxMC[2];
+       
+       // PYTHIA:
+       AliGenPythiaEventHeader* pythiaGenHeader =
+         dynamic_cast<AliGenPythiaEventHeader*>(headerMC->GenEventHeader());
+       if (pythiaGenHeader) {  //works only for pythia
+         fMcProcessType =  GetPythiaEventProcessType(pythiaGenHeader->ProcessType());
+       }
+       // PHOJET:
+       AliGenDPMjetEventHeader* dpmJetGenHeader =
+         dynamic_cast<AliGenDPMjetEventHeader*>(headerMC->GenEventHeader());
+       if (dpmJetGenHeader) {
+         fMcProcessType = GetDPMjetEventProcessType(dpmJetGenHeader->ProcessType());
+       }
+      }
+    } else { // AOD
+      
+      AliAODMCHeader* mcHeader = dynamic_cast<AliAODMCHeader*>(fAOD->FindListObject("mcHeader")); 
+      if(mcHeader) {
+       fZvtxMC = mcHeader->GetVtxZ();
+       
+       if(strstr(mcHeader->GetGeneratorName(), "Pythia")) {
+         fMcProcessType =  GetPythiaEventProcessType(mcHeader->GetEventType());
+       } else {
+         fMcProcessType =  GetDPMjetEventProcessType(mcHeader->GetEventType());
+       }
+      }
+    }
+  }
+  
+  // There are 3 cases
+  // Vertex: NO  - status -1
+  // Vertex: YES : outside cut - status 0
+  //             : inside cut  - status 1
+  // We have to be careful how we normalize because we probably want to
+  // normalize to:
+  // Nevents=(No vertex + outside + inside)/(out + in)*in
+  
+  if (fAnalysisType == "ESD")
+    fZvtx = GetVertex(fESD);
+  else // AOD
+    fZvtx = GetVertex(fAOD);
+    
+  fVtxStatus = -999;
+  
+  if(fZvtx<-990) {
+    
+    fVtxStatus = -1;
+    if(fTriggeredEventMB)
+      fVtx->Fill(0);
+    if(fAnalysisMC)
+      fVtxMC->Fill(0);
+  } else {
+    
+    if(fTriggeredEventMB)
+      fVtx->Fill(1);
+    if(fAnalysisMC)
+      fVtxMC->Fill(1);
+    fVtxBeforeCuts->Fill(fZvtx);
+    fVtxStatus = 0;
+    if (TMath::Abs(fZvtx) < fVtxCut) { 
+      fVtxAfterCuts->Fill(fZvtx);
+      fVtxStatus = 1;
+    }
+  }
+  
+  // store MC event data no matter what
+  if(fAnalysisMC && fStoreMcIn) {
+
+    if (fAnalysisType == "ESD") {
+      ProcessMCTruthESD();
+    } else { // AOD
+      ProcessMCTruthAOD();
+    }
+  }      
+  Float_t centrality = -10;
+  // only analyze triggered events
+  if(fTriggeredEventMB) {
+    
+    if (fAnalysisType == "ESD"){
+      if(fAnalysisPbPb){
+       AliCentrality *centObject = fESD->GetCentrality();
+       centrality = centObject->GetCentralityPercentile("V0M"); 
+       if((centrality>fMaxCent)||(centrality<fMinCent))return;
+      }
+      Int_t nv0test=fESD->GetNumberOfV0s();
+      cout<<"&&&&&&&&&&&&&&&&   hello world"<<endl;
+      fnv0->Fill(nv0test);
+      AnalyzeESD(fESD);
+      
+    } else { // AOD
+      if(fAnalysisPbPb){
+       AliCentrality *centObject = fAOD->GetCentrality();
+       centrality = centObject->GetCentralityPercentile("V0M"); 
+       if((centrality>fMaxCent)||(centrality<fMinCent))return;
+      }
+      Int_t nv0test=fAOD->GetNumberOfV0s();
+      fnv0->Fill(nv0test);
+      AnalyzeAOD(fAOD);
+      
+    }
+  }
+  
+
+
+  if( fTreeOption) {
+
+    fEvent->process = fMcProcessType;
+    fEvent->trig    = fTriggeredEventMB;
+    fEvent->zvtxMC  = fZvtxMC;
+    fEvent->cent      = centrality;
+
+    if(!fRequireRecV0 || fEvent->n > 0) // only fill if there are accepted V0s
+      fTree->Fill();
+    fV0ArrayGlobalPar->Clear();
+    fV0ArrayTPCPar->Clear();
+    if (fAnalysisMC && fStoreMcIn)
+      fTrackArrayMC->Clear();
+  }
+  
+  // Post output data.
+  PostData(1, fListOfObjects);
+}
+
+//________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::AnalyzeESD(AliESDEvent* esdEvent)
+{
+  fRun  = esdEvent->GetRunNumber();
+  fEventId = 0;
+  if(esdEvent->GetHeader())
+    fEventId = GetEventIdAsLong(esdEvent->GetHeader());
+
+  //  Int_t     event     = esdEvent->GetEventNumberInFile();
+  UInt_t    time      = esdEvent->GetTimeStamp();
+  //  ULong64_t trigger   = esdEvent->GetTriggerMask();
+  Float_t   magf      = esdEvent->GetMagneticField();
+
+
+
+  Short_t isPileup = esdEvent->IsPileupFromSPD();
+
+  // centrality
+  Float_t centrality = 120;
+  AliCentrality *centObject = esdEvent->GetCentrality();
+  if(centObject)
+    centrality = centObject->GetCentralityPercentile("V0M"); 
+
+  if(fTriggeredEventMB) {// Only MC case can we have not triggered events
+    
+    if(fVtxStatus==1) { // accepted vertex
+
+      // accepted event
+      fEvents->Fill(0);
+      
+      ProduceArrayTrksESD( esdEvent, kGlobalTrk );//produce array with global track parameters
+      ProduceArrayTrksESD( esdEvent, kTPCTrk );//array with tpc track parametes
+
+
+    } // end if vtx status
+  } // end if triggered
+  
+  if(fTreeOption) {
+
+    fEvent->run       = fRun;
+    fEvent->eventid   = fEventId;
+    fEvent->time      = time;
+    //fEvent->cent      = centrality;
+    fEvent->mag       = magf;
+    fEvent->zvtx      = fZvtx;
+    fEvent->vtxstatus = fVtxStatus;
+    //fEvent->trackmult = trackmult;
+    //fEvent->n         = nadded;
+    fEvent->pileup    = isPileup;
+  }
+}
+
+//________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::AnalyzeAOD(AliAODEvent* aodEvent)
+{
+  fRun  = aodEvent->GetRunNumber();
+  fEventId = 0;
+  if(aodEvent->GetHeader())
+    fEventId = GetEventIdAsLong(aodEvent->GetHeader());
+
+  //  Int_t     event     = aodEvent->GetEventNumberInFile();
+  UInt_t    time      = 0; // Missing AOD info? aodEvent->GetTimeStamp();
+  //  ULong64_t trigger   = aodEvent->GetTriggerMask();
+  Float_t   magf      = aodEvent->GetMagneticField();
+
+  Int_t     trackmult = 0; // no pt cuts
+  Int_t     nadded    = 0;
+
+  Short_t isPileup = aodEvent->IsPileupFromSPD();
+
+  // centrality
+  Float_t centrality = 120;
+  AliCentrality *centObject = aodEvent->GetCentrality();
+  if(centObject)
+    centrality = centObject->GetCentralityPercentile("V0M"); 
+
+  if(fTriggeredEventMB) {// Only MC case can we have not triggered events
+    
+    if(fVtxStatus==1) { // accepted vertex
+
+      // accepted event
+      fEvents->Fill(0);
+      
+      ProduceArrayTrksAOD( aodEvent, kGlobalTrk );//produce array with global track parameters
+      ProduceArrayTrksAOD( aodEvent, kTPCTrk );//array with tpc track parametes
+
+
+    } // end if vtx status
+  } // end if triggered
+  
+  if(fTreeOption) {
+
+    fEvent->run       = fRun;
+    fEvent->eventid   = fEventId;
+    fEvent->time      = time;
+    //fEvent->cent      = centrality;
+    fEvent->mag       = magf;
+    fEvent->zvtx      = fZvtx;
+    fEvent->vtxstatus = fVtxStatus;
+    //fEvent->trackmult = trackmult;
+    //fEvent->n         = nadded;
+    fEvent->pileup    = isPileup;
+  }
+
+
+
+
+
+
+
+}
+
+//_____________________________________________________________________________
+Float_t AliAnalysisTaskHighPtDeDxV0::GetVertex(const AliVEvent* event) const
+{
+  Float_t zvtx = -999;
+  
+  const AliVVertex* primaryVertex = event->GetPrimaryVertex(); 
+  
+  if(primaryVertex->GetNContributors()>0)
+    zvtx = primaryVertex->GetZ();
+
+  return zvtx;
+}
+
+//_____________________________________________________________________________
+Short_t AliAnalysisTaskHighPtDeDxV0::GetPidCode(Int_t pdgCode) const 
+{
+  // return our internal code for pions, kaons, and protons
+  
+  Short_t pidCode = 6;
+  
+  switch (TMath::Abs(pdgCode)) {
+  case 211:
+    pidCode = 1; // pion
+    break;
+  case 321:
+    pidCode = 2; // kaon
+    break;
+  case 2212:
+    pidCode = 3; // proton
+    break;
+  case 11:
+    pidCode = 4; // electron
+    break;
+  case 13:
+    pidCode = 5; // proton
+    break;
+  default:
+    pidCode = 6;  // something else?
+  };
+  
+  return pidCode;
+}
+
+
+//_____________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::ProcessMCTruthESD() 
+{
+  // Fill the special MC histogram with the MC truth info
+  
+  Short_t trackmult = 0;
+  Short_t nadded    = 0;
+  const Int_t nTracksMC = fMCStack->GetNtrack();
+  
+  for (Int_t iTracks = 0; iTracks < nTracksMC; iTracks++) {
+    
+    //Cuts
+    if(!(fMCStack->IsPhysicalPrimary(iTracks)))
+      continue;
+    
+    TParticle* trackMC = fMCStack->Particle(iTracks);
+    
+    Double_t chargeMC = trackMC->GetPDG()->Charge();
+    if (chargeMC != 0) // select charge 0 particles!
+      continue;
+    
+    if (TMath::Abs(trackMC->Eta()) > fEtaCut )
+      continue;
+    
+    trackmult++;
+    
+    //   "charge:pt:p:eta:phi:pidCode"
+    Float_t ptMC      = trackMC->Pt();
+    Float_t pMC       = trackMC->P();
+    Float_t etaMC     = trackMC->Eta();
+    Float_t phiMC     = trackMC->Phi();
+    
+    Int_t pdgCode = trackMC->GetPdgCode();
+    if(!(pdgCode==310 || pdgCode == 3122 || pdgCode == -3122))
+      continue;
+    Short_t pidCodeMC = 0;
+    pidCodeMC = GetPidCode(pdgCode);
+    
+    // Warning: In the data code we cut on the daughters.....
+    if (trackMC->Pt() < fMinPt)
+      continue;
+    
+    if(fTreeOption) {
+      
+      DeDxTrackMC* track = new((*fTrackArrayMC)[nadded]) DeDxTrackMC();
+      nadded++;
+      
+      track->pMC   = pMC;
+      track->ptMC  = ptMC;
+      track->etaMC = etaMC;
+      track->phiMC = phiMC;
+      track->qMC   = Short_t(chargeMC);
+      track->pidMC = pidCodeMC;
+      track->pdgMC = pdgCode;
+    }
+    
+  }//MC track loop
+  
+  if(fTreeOption) {
+    
+    Sort(fTrackArrayMC, kTRUE);
+
+    fEvent->trackmultMC = trackmult;
+    fEvent->nMC         = nadded;
+  }
+  
+}
+
+//_____________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::ProcessMCTruthAOD() 
+{
+  // Fill the special MC histogram with the MC truth info
+
+  Short_t trackmult = 0;
+  Short_t nadded    = 0;
+  const Int_t nTracksMC = fMCArray->GetEntriesFast();
+  
+  for (Int_t iTracks = 0; iTracks < nTracksMC; iTracks++) {
+    
+    AliAODMCParticle* trackMC = dynamic_cast<AliAODMCParticle*>(fMCArray->At(iTracks));
+    
+    //Cuts
+    if(!(trackMC->IsPhysicalPrimary()))
+      continue;
+    
+    
+    Double_t chargeMC = trackMC->Charge();
+    if (chargeMC != 0) // Keep the neutral particles
+      continue;
+    
+    if (TMath::Abs(trackMC->Eta()) > fEtaCut )
+      continue;
+    
+    trackmult++;
+    
+    //   "charge:pt:p:eta:phi:pidCode"
+    Float_t ptMC      = trackMC->Pt();
+    Float_t pMC       = trackMC->P();
+    Float_t etaMC     = trackMC->Eta();
+    Float_t phiMC     = trackMC->Phi();
+    
+    Int_t pdgCode = trackMC->PdgCode();
+    if(!(pdgCode==310 || pdgCode == 3122 || pdgCode == -3122))
+      continue;
+    Short_t pidCodeMC = 0;
+    pidCodeMC = GetPidCode(pdgCode);
+    
+    if (trackMC->Pt() < fMinPt)
+      continue;
+    
+    if(fTreeOption) {
+      
+      DeDxTrackMC* track = new((*fTrackArrayMC)[nadded]) DeDxTrackMC();
+      nadded++;
+      
+      track->pMC   = pMC;
+      track->ptMC  = ptMC;
+      track->etaMC = etaMC;
+      track->phiMC = phiMC;
+      track->qMC   = Short_t(chargeMC);
+      track->pidMC = pidCodeMC;
+      track->pdgMC = pdgCode;
+    }
+    
+  }//MC track loop
+  
+  if(fTreeOption) {
+    
+    Sort(fTrackArrayMC, kTRUE);
+
+    fEvent->trackmultMC = trackmult;
+    fEvent->nMC         = nadded;
+  }
+  
+}
+
+//_____________________________________________________________________________
+Short_t AliAnalysisTaskHighPtDeDxV0::GetPythiaEventProcessType(Int_t pythiaType) {
+  //
+  // Get the process type of the event.  PYTHIA
+  //
+  // source PWG0   dNdpt 
+
+  Short_t globalType = -1; //init
+      
+  if(pythiaType==92||pythiaType==93){
+    globalType = 2; //single diffractive
+  }
+  else if(pythiaType==94){
+    globalType = 3; //double diffractive
+  }
+  //else if(pythiaType != 91){ // also exclude elastic to be sure... CKB??
+  else {
+    globalType = 1;  //non diffractive
+  }
+  return globalType;
+}
+
+//_____________________________________________________________________________
+Short_t AliAnalysisTaskHighPtDeDxV0::GetDPMjetEventProcessType(Int_t dpmJetType) {
+  //
+  // get the process type of the event.  PHOJET
+  //
+  //source PWG0   dNdpt 
+  // can only read pythia headers, either directly or from cocktalil header
+  Short_t globalType = -1;
+  
+  if (dpmJetType == 1 || dpmJetType == 4) { // explicitly inelastic plus central diffraction
+    globalType = 1;
+  }
+  else if (dpmJetType==5 || dpmJetType==6) {
+    globalType = 2;
+  }
+  else if (dpmJetType==7) {
+    globalType = 3;
+  }
+  return globalType;
+}
+
+//_____________________________________________________________________________
+ULong64_t AliAnalysisTaskHighPtDeDxV0::GetEventIdAsLong(AliVHeader* header) const
+{
+  // To have a unique id for each event in a run!
+  // Modified from AliRawReader.h
+  return ((ULong64_t)header->GetBunchCrossNumber()+
+         (ULong64_t)header->GetOrbitNumber()*3564+
+         (ULong64_t)header->GetPeriodNumber()*16777215*3564);
+}
+
+
+//____________________________________________________________________
+TParticle* AliAnalysisTaskHighPtDeDxV0::FindPrimaryMother(AliStack* stack, Int_t label)
+{
+  //
+  // Finds the first mother among the primary particles of the particle identified by <label>,
+  // i.e. the primary that "caused" this particle
+  //
+  // Taken from AliPWG0Helper class
+  //
+
+  Int_t nSteps = 0;
+
+  Int_t motherLabel = FindPrimaryMotherLabel(stack, label, nSteps);
+  if (motherLabel < 0)
+    return 0;
+
+  return stack->Particle(motherLabel);
+}
+
+//____________________________________________________________________
+Int_t AliAnalysisTaskHighPtDeDxV0::FindPrimaryMotherLabel(AliStack* stack, Int_t label, Int_t& nSteps)
+{
+  //
+  // Finds the first mother among the primary particles of the particle identified by <label>,
+  // i.e. the primary that "caused" this particle
+  //
+  // returns its label
+  //
+  // Taken from AliPWG0Helper class
+  //
+  nSteps = 0;
+  const Int_t nPrim  = stack->GetNprimary();
+  
+  while (label >= nPrim) {
+
+    //printf("Particle %d (pdg %d) is not a primary. Let's check its mother %d\n", label, mother->GetPdgCode(), mother->GetMother(0));
+
+    nSteps++; // 1 level down
+    
+    TParticle* particle = stack->Particle(label);
+    if (!particle) {
+      
+      AliDebugGeneral("FindPrimaryMotherLabel", AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack.", label));
+      return -1;
+    }
+    
+    // find mother
+    if (particle->GetMother(0) < 0) {
+
+      AliDebugGeneral("FindPrimaryMotherLabel", AliLog::kError, Form("UNEXPECTED: Could not find mother of secondary particle %d.", label));
+      return -1;
+    }
+    
+    label = particle->GetMother(0);
+  }
+  
+  return label;
+}
+
+//____________________________________________________________________
+AliAODMCParticle* AliAnalysisTaskHighPtDeDxV0::FindPrimaryMotherAOD(AliAODMCParticle* startParticle, Int_t& nSteps)
+{
+  //
+  // Finds the first mother among the primary particles of the particle identified by <label>,
+  // i.e. the primary that "caused" this particle
+  //
+  // Taken from AliPWG0Helper class
+  //
+
+  nSteps = 0;
+
+  AliAODMCParticle* mcPart = startParticle;
+
+  while (mcPart)
+    {
+      
+      if(mcPart->IsPrimary())
+       return mcPart;
+      
+      Int_t mother = mcPart->GetMother();
+
+      mcPart = dynamic_cast<AliAODMCParticle*>(fMCArray->At(mother));
+      nSteps++; // 1 level down
+    }
+
+  return 0;
+}
+
+//_____________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::Sort(TClonesArray* array, Bool_t isMC) 
+{
+  const Int_t n = array->GetEntriesFast(); 
+  if(n==0) {
+
+    if(isMC) 
+      fEvent->ptmaxMC = 0;
+    else
+      fEvent->ptmax   = 0;
+      
+    return;
+  }
+
+  Float_t ptArray[n];
+  Int_t   indexArray[n];
+  
+  for(Int_t i = 0; i < n; i++) {
+
+    Float_t pt = 0;
+    if(isMC) {
+      DeDxTrackMC* track = (DeDxTrackMC*)array->At(i);
+      pt = track->ptMC;
+    } else {
+      DeDxTrack* track = (DeDxTrack*)array->At(i);
+      pt = track->pt;
+    }
+    ptArray[i]    = pt;
+    indexArray[i] = i;
+  }
+
+  TMath::Sort(n, ptArray, indexArray);
+  
+  // set max pt
+  if(isMC) {
+    DeDxTrackMC* track = (DeDxTrackMC*)array->At(indexArray[0]);
+    fEvent->ptmaxMC = track->ptMC;
+  } else {
+    DeDxTrack* track = (DeDxTrack*)array->At(indexArray[0]);
+    fEvent->ptmax   = track->pt;
+  }
+  
+  // set order of each track
+  for(Int_t i = 0; i < n; i++) {
+    
+    if(isMC) {
+      DeDxTrackMC* track = (DeDxTrackMC*)array->At(indexArray[i]);
+      track->orderMC = i;
+    } else {
+      DeDxTrack* track = (DeDxTrack*)array->At(indexArray[i]);
+      track->order = i;
+    }
+  }
+}
+//__________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::ProduceArrayTrksESD( AliESDEvent *ESDevent, AnalysisMode analysisMode ){
+  Int_t nv0s = ESDevent->GetNumberOfV0s();
+  if(nv0s<1)return;
+  Int_t     trackmult = 0; // no pt cuts
+  Int_t     nadded    = 0;
+  const AliESDVertex *myBestPrimaryVertex = ESDevent->GetPrimaryVertex();
+  if (!myBestPrimaryVertex) return;
+  if (!(myBestPrimaryVertex->GetStatus())) return;
+  Double_t  lPrimaryVtxPosition[3];
+  myBestPrimaryVertex->GetXYZ(lPrimaryVtxPosition);
+  
+  Double_t  lPrimaryVtxCov[6];
+  myBestPrimaryVertex->GetCovMatrix(lPrimaryVtxCov);
+  Double_t  lPrimaryVtxChi2 = myBestPrimaryVertex->GetChi2toNDF();
+  
+  AliAODVertex* myPrimaryVertex = new AliAODVertex(lPrimaryVtxPosition, lPrimaryVtxCov, lPrimaryVtxChi2, NULL, -1, AliAODVertex::kPrimary);
+
+
+  if( analysisMode == kGlobalTrk ){
+    if(fV0ArrayGlobalPar)
+      fV0ArrayGlobalPar->Clear();
+  } else if( analysisMode == kTPCTrk ){
+    if(fV0ArrayTPCPar)
+      fV0ArrayTPCPar->Clear();
+  }
+  
+  if( analysisMode==kGlobalTrk ){  
+
+
+
+    
+    // ################################
+    // #### BEGINNING OF V0 CODE ######
+    // ################################
+
+    
+    for (Int_t iV0 = 0; iV0 < nv0s; iV0++) {
+      
+      // This is the begining of the V0 loop  
+      AliESDv0 *esdV0 = ESDevent->GetV0(iV0);
+      if (!esdV0) continue;
+      
+      // AliESDTrack (V0 Daughters)
+      UInt_t lKeyPos = (UInt_t)TMath::Abs(esdV0->GetPindex());
+      UInt_t lKeyNeg = (UInt_t)TMath::Abs(esdV0->GetNindex());
+      
+      AliESDtrack *pTrack = ESDevent->GetTrack(lKeyPos);
+      AliESDtrack *nTrack = ESDevent->GetTrack(lKeyNeg);
+      if (!pTrack || !nTrack) {
+       Printf("ERROR: Could not retreive one of the daughter track");
+       continue;
+      }
+      
+      // Remove like-sign
+      if (pTrack->GetSign() == nTrack->GetSign()) {
+       //cout<< "like sign, continue"<< endl;
+       continue;
+      } 
+      
+      // Eta cut on decay products
+      if(TMath::Abs(pTrack->Eta()) > fEtaCut || TMath::Abs(nTrack->Eta()) > fEtaCut)
+       continue;
+      
+      // Pt cut on decay products
+      if (esdV0->Pt() < fMinPt)
+       //      if (pTrack->Pt() < fMinPt && nTrack->Pt() < fMinPt)
+       continue;
+
+      //filter for positive track
+      UShort_t filterFlag_p = 0;
+      Bool_t filterCut_Set1_p = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+      Bool_t filterCut_Set2_p = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+      Bool_t filterCut_Set3_p = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+      
+      UInt_t selectDebug_p = 0;
+      if (fTrackFilterGolden) {
+       selectDebug_p = fTrackFilterGolden->IsSelected(pTrack);
+       if (selectDebug_p) {
+         filterFlag_p +=1;
+         filterCut_Set3_p=kTRUE;
+       }
+      }
+      
+      if (fTrackFilterTPC) {
+       
+       selectDebug_p = fTrackFilterTPC->IsSelected(pTrack);
+       if (selectDebug_p){//only tracks which pass the TPC-only track cuts
+         filterFlag_p +=2;
+         filterCut_Set1_p=kTRUE;
+         
+       }
+       
+      }
+      
+      if (fTrackFilter) {
+       selectDebug_p = fTrackFilter->IsSelected(pTrack);
+       if (selectDebug_p) {
+         filterCut_Set2_p=kTRUE;
+       }
+      }
+      
+      if(filterFlag_p ==0 )
+       continue;
+      
+
+      //filter for negative track
+      UShort_t filterFlag_n = 0;
+      Bool_t filterCut_Set1_n = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+      Bool_t filterCut_Set2_n = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+      Bool_t filterCut_Set3_n = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+      
+      UInt_t selectDebug_n = 0;
+      if (fTrackFilterGolden) {
+       selectDebug_n = fTrackFilterGolden->IsSelected(nTrack);
+       if (selectDebug_n) {
+         filterFlag_n +=1;
+         filterCut_Set3_n=kTRUE;
+       }
+      }
+      
+      if (fTrackFilterTPC) {
+       
+       selectDebug_n = fTrackFilterTPC->IsSelected(nTrack);
+       if (selectDebug_n){//only tracks which pass the TPC-only track cuts
+         filterFlag_n +=2;
+         filterCut_Set1_n=kTRUE;
+         
+       }
+       
+      }
+      
+      if (fTrackFilter) {
+       selectDebug_n = fTrackFilter->IsSelected(nTrack);
+       if (selectDebug_n) {
+         filterCut_Set2_n=kTRUE;
+       }
+      }
+
+
+      // Check if switch does anything!
+      Bool_t isSwitched = kFALSE;
+      if (pTrack->GetSign() < 0) { // switch
+       
+       isSwitched = kTRUE;
+       AliESDtrack* helpTrack = nTrack;
+       nTrack = pTrack;
+       pTrack = helpTrack;
+      }        
+      
+      Float_t alpha = esdV0->AlphaV0();
+      Float_t ptarm = esdV0->PtArmV0();
+      // Double_t pVtxPos= v0->PrimaryVtxPosition();      
+      
+      Double_t  lV0Position[3];
+      esdV0->GetXYZ(lV0Position[0], lV0Position[1], lV0Position[2]);
+      
+      Double_t lV0Radius      = TMath::Sqrt(lV0Position[0]*lV0Position[0]+lV0Position[1]*lV0Position[1]);
+      Double_t lV0DecayLength = TMath::Sqrt(TMath::Power(lV0Position[0] - lPrimaryVtxPosition[0],2) +
+                                           TMath::Power(lV0Position[1] - lPrimaryVtxPosition[1],2) +
+                                           TMath::Power(lV0Position[2] - lPrimaryVtxPosition[2],2 ));
+      AliKFVertex primaryVtxKF( *myPrimaryVertex );
+      AliKFParticle::SetField(ESDevent->GetMagneticField());
+      
+      // Also implement switch here!!!!!!
+      AliKFParticle* negEKF  = 0; // e-
+      AliKFParticle* posEKF  = 0; // e+
+      AliKFParticle* negPiKF = 0; // pi -
+      AliKFParticle* posPiKF = 0; // pi +
+      AliKFParticle* posPKF  = 0; // p
+      AliKFParticle* negAPKF = 0; // p-bar
+      
+      if(!isSwitched) {
+       negEKF  = new AliKFParticle( *(esdV0->GetParamN()) , 11);
+       posEKF  = new AliKFParticle( *(esdV0->GetParamP()) ,-11);
+       negPiKF = new AliKFParticle( *(esdV0->GetParamN()) ,-211);
+       posPiKF = new AliKFParticle( *(esdV0->GetParamP()) , 211);
+       posPKF  = new AliKFParticle( *(esdV0->GetParamP()) , 2212);
+       negAPKF = new AliKFParticle( *(esdV0->GetParamN()) ,-2212);
+      } else { // switch + and - 
+       negEKF  = new AliKFParticle( *(esdV0->GetParamP()) , 11);
+       posEKF  = new AliKFParticle( *(esdV0->GetParamN()) ,-11);
+       negPiKF = new AliKFParticle( *(esdV0->GetParamP()) ,-211);
+       posPiKF = new AliKFParticle( *(esdV0->GetParamN()) , 211);
+       posPKF  = new AliKFParticle( *(esdV0->GetParamN()) , 2212);
+       negAPKF = new AliKFParticle( *(esdV0->GetParamP()) ,-2212);
+      }
+      
+      AliKFParticle v0GKF;  // Gamma e.g. from pi0
+      v0GKF+=(*negEKF);
+      v0GKF+=(*posEKF);
+      v0GKF.SetProductionVertex(primaryVtxKF);
+      
+      AliKFParticle v0K0sKF; // K0 short
+      v0K0sKF+=(*negPiKF);
+      v0K0sKF+=(*posPiKF);
+      v0K0sKF.SetProductionVertex(primaryVtxKF);
+      
+      AliKFParticle v0LambdaKF; // Lambda
+      v0LambdaKF+=(*negPiKF);
+      v0LambdaKF+=(*posPKF);   
+      v0LambdaKF.SetProductionVertex(primaryVtxKF);
+      
+      AliKFParticle v0AntiLambdaKF; // Lambda-bar
+      v0AntiLambdaKF+=(*posPiKF);
+      v0AntiLambdaKF+=(*negAPKF);
+      v0AntiLambdaKF.SetProductionVertex(primaryVtxKF);
+      
+      Double_t deltaInvMassG     = v0GKF.GetMass();
+      Double_t deltaInvMassK0s   = v0K0sKF.GetMass()-0.498;
+      Double_t deltaInvMassL     = v0LambdaKF.GetMass()-1.116;
+      Double_t deltaInvMassAntiL = v0AntiLambdaKF.GetMass()-1.116;
+      
+      if(TMath::Abs(deltaInvMassK0s) > fMassCut &&
+        TMath::Abs(deltaInvMassL) > fMassCut &&
+        TMath::Abs(deltaInvMassAntiL) > fMassCut)
+       continue;
+      
+      // Extract track information
+      
+      Short_t pcharge  = pTrack->Charge();
+      Float_t ppt      = pTrack->Pt();
+      Float_t pp       = pTrack->P(); 
+      Float_t peta     = pTrack->Eta();
+      Float_t pphi     = pTrack->Phi();
+      Short_t pncl     = pTrack->GetTPCsignalN();
+      Short_t pneff    = Short_t(pTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      Float_t pdedx    = pTrack->GetTPCsignal();
+      
+      Float_t ptpcchi  = 0;
+      if(pTrack->GetTPCNcls() > 0)
+       ptpcchi = pTrack->GetTPCchi2()/Float_t(pTrack->GetTPCNcls());
+      
+      Short_t ncharge  = nTrack->Charge();
+      Float_t npt      = nTrack->Pt();
+      Float_t np       = nTrack->P(); 
+      Float_t neta     = nTrack->Eta();
+      Float_t nphi     = nTrack->Phi();
+      Short_t nncl     = nTrack->GetTPCsignalN();
+      Short_t nneff    = Short_t(nTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      Float_t ndedx    = nTrack->GetTPCsignal();
+      Float_t ntpcchi  = 0;
+      if(nTrack->GetTPCNcls() > 0)
+       ntpcchi = nTrack->GetTPCchi2()/Float_t(nTrack->GetTPCNcls());
+      
+      Float_t b[2];
+      Float_t bCov[3];
+      pTrack->GetImpactParameters(b,bCov);
+      Float_t pdcaxy   = b[0];
+      Float_t pdcaz    = b[1];
+      nTrack->GetImpactParameters(b,bCov);
+      Float_t ndcaxy   = b[0];
+      Float_t ndcaz    = b[1];
+      
+      Int_t   primaryV0     = 0; // 0 means that the tracks are not both daughters of a primary particle (1 means they are)
+      Int_t   pdgV0         = 0; // 0 means that they don't have same origin for MC (1 means they have the same original mother)
+      Float_t p_ptMC        = 0;
+      Short_t p_pidCode     = 0; // 0 = real data / no mc track!
+      Short_t p_primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   p_pdgMother   = 0;
+      Float_t n_ptMC        = 0;
+      Short_t n_pidCode     = 0; // 0 = real data / no mc track!
+      Short_t n_primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   n_pdgMother   = 0;
+      if(fAnalysisMC) {
+       
+       Int_t p_mother_label = 0;
+       Int_t p_mother_steps = 0;
+       Int_t n_mother_label = 0;
+       Int_t n_mother_steps = 0;
+       
+       // positive track
+       const Int_t p_label = TMath::Abs(pTrack->GetLabel());
+       TParticle* p_mcTrack = fMCStack->Particle(p_label);         
+       if (p_mcTrack){
+         
+         if(fMCStack->IsPhysicalPrimary(p_label))
+           p_primaryFlag = 1;
+         
+         Int_t p_pdgCode = p_mcTrack->GetPdgCode();
+         p_pidCode = GetPidCode(p_pdgCode);
+         
+         p_ptMC      = p_mcTrack->Pt();
+         
+         p_mother_label = FindPrimaryMotherLabel(fMCStack, p_label, 
+                                                 p_mother_steps);
+         if(p_mother_label>0) {
+           TParticle* p_mother = fMCStack->Particle(p_mother_label);
+           p_pdgMother = p_mother->GetPdgCode();
+         }
+       }
+       
+       // negative track
+       const Int_t n_label = TMath::Abs(nTrack->GetLabel());
+       TParticle* n_mcTrack = fMCStack->Particle(n_label);         
+       if (n_mcTrack){
+         
+         if(fMCStack->IsPhysicalPrimary(n_label))
+           n_primaryFlag = 1;
+         
+         Int_t n_pdgCode = n_mcTrack->GetPdgCode();
+         n_pidCode = GetPidCode(n_pdgCode);
+         
+         n_ptMC      = n_mcTrack->Pt();
+         
+         n_mother_label = FindPrimaryMotherLabel(fMCStack, n_label, 
+                                                 n_mother_steps);
+         if(n_mother_label>0) {
+           TParticle* n_mother = fMCStack->Particle(n_mother_label);
+           n_pdgMother = n_mother->GetPdgCode();
+         }
+       }
+       
+       // Check if V0 is primary = first and the same mother of both partciles
+       if(p_mother_label>0 && n_mother_label>0 && p_mother_label == n_mother_label) {
+         pdgV0 = p_pdgMother;
+         if(p_mother_steps == 1 && n_mother_steps == 1) {
+           primaryV0 = 1;
+         }
+       }
+      }
+
+    
+      if(fTreeOption) {
+       
+
+
+       DeDxV0* v0data = new((*fV0ArrayGlobalPar)[nadded]) DeDxV0();
+       nadded++;
+       
+       // v0 data
+       v0data->p       = esdV0->P();
+       v0data->pt      = esdV0->Pt();
+       v0data->eta     = esdV0->Eta();
+       v0data->phi     = esdV0->Phi();
+       v0data->pdca    = TMath::Sqrt(pdcaxy*pdcaxy + pdcaz*pdcaz);
+       v0data->ndca    = TMath::Sqrt(ndcaxy*ndcaxy + ndcaz*ndcaz);
+       v0data->dmassG  = deltaInvMassG;
+       v0data->dmassK0 = deltaInvMassK0s;
+       v0data->dmassL  = deltaInvMassL;
+       v0data->dmassAL = deltaInvMassAntiL;
+       v0data->alpha   = alpha;
+       v0data->ptarm   = ptarm;
+       v0data->decayr  = lV0Radius;
+       v0data->decayl  = lV0DecayLength;
+       
+       // New parameters
+       v0data->status  = esdV0->GetOnFlyStatus();
+       v0data->chi2    = esdV0->GetChi2V0();
+       v0data->cospt   = esdV0->GetV0CosineOfPointingAngle(); 
+       // cospt: as I understand this means that the pointing to the vertex
+       // is fine so I remove the dcaxy and dcaz for the V= class
+       v0data->dcadaughters = esdV0->GetDcaV0Daughters();
+       v0data->primary = primaryV0;
+       v0data->pdg     = pdgV0;
+       
+       // positive track
+       v0data->ptrack.p       = pp;
+       v0data->ptrack.pt      = ppt;
+       //        v0data->ptrack.ptcon   = ppt_con;
+       //        v0data->ptrack.tpcchi  = ptpcchi;
+       v0data->ptrack.eta     = peta;
+       v0data->ptrack.phi     = pphi;
+       v0data->ptrack.q       = pcharge;
+       v0data->ptrack.ncl     = pncl;
+       v0data->ptrack.neff    = pneff;
+       v0data->ptrack.dedx    = pdedx;
+       v0data->ptrack.dcaxy   = pdcaxy;
+       v0data->ptrack.dcaz    = pdcaz;
+       v0data->ptrack.pid     = p_pidCode;
+       v0data->ptrack.primary = p_primaryFlag;
+       v0data->ptrack.pttrue  = p_ptMC;
+       v0data->ptrack.mother  = p_pdgMother;
+       v0data->ptrack.filter  = filterFlag_p;
+       v0data->ptrack.filterset1 = filterCut_Set1_p;
+       v0data->ptrack.filterset2 = filterCut_Set2_p;
+       v0data->ptrack.filterset3 = filterCut_Set3_p;
+       
+       // negative track
+       v0data->ntrack.p       = np;
+       v0data->ntrack.pt      = npt;
+       //        v0data->ntrack.ptcon   = npt_con;
+       //        v0data->ntrack.tpcchi  = ntpcchi;
+       v0data->ntrack.eta     = neta;
+       v0data->ntrack.phi     = nphi;
+       v0data->ntrack.q       = ncharge;
+       v0data->ntrack.ncl     = nncl;
+       v0data->ntrack.neff    = nneff;
+       v0data->ntrack.dedx    = ndedx;
+       v0data->ntrack.dcaxy   = ndcaxy;
+       v0data->ntrack.dcaz    = ndcaz;
+       v0data->ntrack.pid     = n_pidCode;
+       v0data->ntrack.primary = n_primaryFlag;
+       v0data->ntrack.pttrue  = n_ptMC;
+       v0data->ntrack.mother  = n_pdgMother;
+       v0data->ntrack.filter  = filterFlag_n;
+       v0data->ntrack.filterset1 = filterCut_Set1_n;
+       v0data->ntrack.filterset2 = filterCut_Set2_n;
+       v0data->ntrack.filterset3 = filterCut_Set3_n;
+
+
+      }
+      
+      // clean up loop over v0
+
+      delete negPiKF;
+      delete posPiKF;
+      delete posPKF;
+      delete negAPKF;
+  
+
+
+    }
+  
+    // clean up event
+    //delete myPrimaryVertex;
+  }
+  else if( analysisMode==kTPCTrk ){  
+    cout<<"&&&&&&&&&&&&&&&&&&&&&                Hello world"<<endl;
+    const AliESDVertex *vtxSPD = ESDevent->GetPrimaryVertexSPD();
+    if( vtxSPD->GetNContributors() < 1 || TMath::Abs(vtxSPD->GetZ()) > 10.0 ) return;
+    
+    
+    // ################################
+    // #### BEGINNING OF V0 CODE ######
+    // ################################
+
+    
+    for (Int_t iV0 = 0; iV0 < nv0s; iV0++) {
+      
+      // This is the begining of the V0 loop  
+      AliESDv0 *esdV0 = ESDevent->GetV0(iV0);
+      if (!esdV0) continue;
+      
+      // AliESDTrack (V0 Daughters)
+      UInt_t lKeyPos = (UInt_t)TMath::Abs(esdV0->GetPindex());
+      UInt_t lKeyNeg = (UInt_t)TMath::Abs(esdV0->GetNindex());
+      
+      AliESDtrack *pTrack = ESDevent->GetTrack(lKeyPos);
+      AliESDtrack *nTrack = ESDevent->GetTrack(lKeyNeg);
+      if (!pTrack || !nTrack) {
+       Printf("ERROR: Could not retreive one of the daughter track");
+       continue;
+      }
+
+      // Remove like-sign
+      if (pTrack->GetSign() == nTrack->GetSign()) {
+       //cout<< "like sign, continue"<< endl;
+       continue;
+      } 
+
+      AliESDtrack *pTrackTPC = AliESDtrackCuts::GetTPCOnlyTrack(dynamic_cast<AliESDEvent*>(ESDevent),pTrack->GetID());
+      AliESDtrack *nTrackTPC = AliESDtrackCuts::GetTPCOnlyTrack(dynamic_cast<AliESDEvent*>(ESDevent),nTrack->GetID());
+
+      if (!pTrackTPC || !nTrackTPC) {
+       Printf("ERROR: Could not retreive one of the daughter TPC track");
+       continue;
+      }
+
+      //filter for positive track
+      UInt_t selectDebug_p = 0;
+      UShort_t filterFlag_p = 0;
+      selectDebug_p = fTrackFilterTPC->IsSelected(pTrackTPC);
+      //if(selectDebug_p==0) continue;
+
+      //filter for negative track
+      UInt_t selectDebug_n = 0;
+      UShort_t filterFlag_n = 0;
+      selectDebug_n = fTrackFilterTPC->IsSelected(nTrackTPC);
+      if(selectDebug_n==0 || selectDebug_p==0) continue;
+
+      if(selectDebug_p)
+       filterFlag_p += 1;
+
+      if(pTrackTPC->Pt()>0.){
+       // only constrain tracks above threshold
+       AliExternalTrackParam exParamp;
+       // take the B-field from the ESD, no 3D fieldMap available at this point
+       Bool_t relate_p = false;
+       relate_p = pTrackTPC->RelateToVertexTPC(vtxSPD,ESDevent->GetMagneticField(),
+                                               kVeryBig,&exParamp);
+       if(!relate_p){
+         delete pTrackTPC;
+         continue;
+       }
+       pTrackTPC->Set(exParamp.GetX(),exParamp.GetAlpha(),exParamp.GetParameter(),
+                      exParamp.GetCovariance());
+      }
+      else continue;     
+      
+
+      //filter for negative track
+      if(selectDebug_n)
+       filterFlag_n += 1;
+
+  
+      if(nTrackTPC->Pt()>0.){
+       // only constrain tracks above threshold
+       AliExternalTrackParam exParamn;
+       // take the B-field from the ESD, no 3D fieldMap available at this point
+       Bool_t relate_n = false;
+       relate_n = nTrackTPC->RelateToVertexTPC(vtxSPD,ESDevent->GetMagneticField(),
+                                               kVeryBig,&exParamn);
+       if(!relate_n){
+         delete nTrackTPC;
+         continue;
+       }
+       nTrackTPC->Set(exParamn.GetX(),exParamn.GetAlpha(),exParamn.GetParameter(),
+                      exParamn.GetCovariance());
+      }
+      else continue;  
+      
+      
+      // Eta cut on decay products
+      if(TMath::Abs(pTrackTPC->Eta()) > fEtaCut || TMath::Abs(nTrackTPC->Eta()) > fEtaCut)
+       continue;
+      
+      // Pt cut on decay products
+      if (esdV0->Pt() < fMinPt)
+       //      if (pTrack->Pt() < fMinPt && nTrack->Pt() < fMinPt)
+       continue;
+      
+      // Check if switch does anything!
+      Bool_t isSwitched = kFALSE;
+      if (pTrackTPC->GetSign() < 0) { // switch
+       
+       isSwitched = kTRUE;
+       AliESDtrack* helpTrack = nTrack;
+       nTrackTPC = pTrackTPC;
+       pTrackTPC = helpTrack;
+      }        
+      
+
+      // Extract track information
+      
+      Short_t pcharge  = pTrackTPC->Charge();
+      Float_t ppt      = pTrackTPC->Pt();
+      Float_t pp       = pTrackTPC->P(); 
+      Float_t peta     = pTrackTPC->Eta();
+      Float_t pphi     = pTrackTPC->Phi();
+      Short_t pncl     = pTrackTPC->GetTPCsignalN();
+      Short_t pneff    = Short_t(pTrackTPC->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      Float_t pdedx    = pTrackTPC->GetTPCsignal();
+      
+      Float_t ptpcchi  = 0;
+      if(pTrackTPC->GetTPCNcls() > 0)
+       ptpcchi = pTrackTPC->GetTPCchi2()/Float_t(pTrackTPC->GetTPCNcls());
+      
+      Short_t ncharge  = nTrackTPC->Charge();
+      Float_t npt      = nTrackTPC->Pt();
+      Float_t np       = nTrackTPC->P(); 
+      Float_t neta     = nTrackTPC->Eta();
+      Float_t nphi     = nTrackTPC->Phi();
+      Short_t nncl     = nTrackTPC->GetTPCsignalN();
+      Short_t nneff    = Short_t(nTrackTPC->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      Float_t ndedx    = nTrackTPC->GetTPCsignal();
+      Float_t ntpcchi  = 0;
+      if(nTrackTPC->GetTPCNcls() > 0)
+       ntpcchi = nTrackTPC->GetTPCchi2()/Float_t(nTrackTPC->GetTPCNcls());
+      
+      Float_t bp[2]={0,0};
+      Float_t bCovp[3]={0,0,0};
+      pTrackTPC->GetImpactParameters(bp,bCovp);
+      Float_t pdcaxy   = bp[0];
+      Float_t pdcaz    = bp[1];
+
+      Float_t bn[2]={0,0};
+      Float_t bCovn[3]={0,0,0};
+      nTrackTPC->GetImpactParameters(bn,bCovn);
+      Float_t ndcaxy   = bn[0];
+      Float_t ndcaz    = bn[1];
+
+
+      Float_t alpha = esdV0->AlphaV0();
+      Float_t ptarm = esdV0->PtArmV0();
+      // Double_t pVtxPos= v0->PrimaryVtxPosition();      
+      
+      Double_t  lV0Position[3];
+      esdV0->GetXYZ(lV0Position[0], lV0Position[1], lV0Position[2]);
+      
+      Double_t lV0Radius      = TMath::Sqrt(lV0Position[0]*lV0Position[0]+lV0Position[1]*lV0Position[1]);
+      Double_t lV0DecayLength = TMath::Sqrt(TMath::Power(lV0Position[0] - lPrimaryVtxPosition[0],2) +
+                                           TMath::Power(lV0Position[1] - lPrimaryVtxPosition[1],2) +
+                                           TMath::Power(lV0Position[2] - lPrimaryVtxPosition[2],2 ));
+      AliKFVertex primaryVtxKF( *myPrimaryVertex );
+      AliKFParticle::SetField(ESDevent->GetMagneticField());
+      
+      // Also implement switch here!!!!!!
+      AliKFParticle* negEKF  = 0; // e-
+      AliKFParticle* posEKF  = 0; // e+
+      AliKFParticle* negPiKF = 0; // pi -
+      AliKFParticle* posPiKF = 0; // pi +
+      AliKFParticle* posPKF  = 0; // p
+      AliKFParticle* negAPKF = 0; // p-bar
+      
+      
+      if(!isSwitched) {
+       /*      
+               negEKF  = new AliKFParticle( *(esdV0->GetParamN()) , 11);
+               posEKF  = new AliKFParticle( *(esdV0->GetParamP()) ,-11);
+               negPiKF = new AliKFParticle( *(esdV0->GetParamN()) ,-211);
+               posPiKF = new AliKFParticle( *(esdV0->GetParamP()) , 211);
+               posPKF  = new AliKFParticle( *(esdV0->GetParamP()) , 2212);
+               negAPKF = new AliKFParticle( *(esdV0->GetParamN()) ,-2212);
+       */
+
+       negEKF  = new AliKFParticle( *(dynamic_cast<AliVTrack*>(nTrackTPC)) , 11);
+       posEKF  = new AliKFParticle( *(dynamic_cast<AliVTrack*>(pTrackTPC)) ,-11);
+       negPiKF = new AliKFParticle( *(dynamic_cast<AliVTrack*>(nTrackTPC)) ,-211);
+       posPiKF = new AliKFParticle( *(dynamic_cast<AliVTrack*>(pTrackTPC)) , 211);
+       posPKF  = new AliKFParticle( *(dynamic_cast<AliVTrack*>(pTrackTPC)) , 2212);
+       negAPKF = new AliKFParticle( *(dynamic_cast<AliVTrack*>(nTrackTPC)) ,-2212);
+
+
+
+      } else { // switch + and - 
+       /*
+       negEKF  = new AliKFParticle( *(esdV0->GetParamP()) , 11);
+       posEKF  = new AliKFParticle( *(esdV0->GetParamN()) ,-11);
+       negPiKF = new AliKFParticle( *(esdV0->GetParamP()) ,-211);
+       posPiKF = new AliKFParticle( *(esdV0->GetParamN()) , 211);
+       posPKF  = new AliKFParticle( *(esdV0->GetParamN()) , 2212);
+       negAPKF = new AliKFParticle( *(esdV0->GetParamP()) ,-2212);
+       */
+
+       negEKF  = new AliKFParticle(  *(dynamic_cast<AliVTrack*>(pTrackTPC)), 11);
+       posEKF  = new AliKFParticle(  *(dynamic_cast<AliVTrack*>(nTrackTPC)),-11);
+       negPiKF = new AliKFParticle(  *(dynamic_cast<AliVTrack*>(pTrackTPC)),-211);
+       posPiKF = new AliKFParticle(  *(dynamic_cast<AliVTrack*>(nTrackTPC)), 211);
+       posPKF  = new AliKFParticle(  *(dynamic_cast<AliVTrack*>(nTrackTPC)), 2212);
+       negAPKF = new AliKFParticle(  *(dynamic_cast<AliVTrack*>(pTrackTPC)),-2212);
+
+
+      }
+   
+
+
+
+      
+      AliKFParticle v0GKF;  // Gamma e.g. from pi0
+      v0GKF+=(*negEKF);
+      v0GKF+=(*posEKF);
+      v0GKF.SetProductionVertex(primaryVtxKF);
+      
+      AliKFParticle v0K0sKF; // K0 short
+      v0K0sKF+=(*negPiKF);
+      v0K0sKF+=(*posPiKF);
+      v0K0sKF.SetProductionVertex(primaryVtxKF);
+      
+      AliKFParticle v0LambdaKF; // Lambda
+      v0LambdaKF+=(*negPiKF);
+      v0LambdaKF+=(*posPKF);   
+      v0LambdaKF.SetProductionVertex(primaryVtxKF);
+      
+      AliKFParticle v0AntiLambdaKF; // Lambda-bar
+      v0AntiLambdaKF+=(*posPiKF);
+      v0AntiLambdaKF+=(*negAPKF);
+      v0AntiLambdaKF.SetProductionVertex(primaryVtxKF);
+      
+      Double_t deltaInvMassG     = v0GKF.GetMass();
+      Double_t deltaInvMassK0s   = v0K0sKF.GetMass()-0.498;
+      Double_t deltaInvMassL     = v0LambdaKF.GetMass()-1.116;
+      Double_t deltaInvMassAntiL = v0AntiLambdaKF.GetMass()-1.116;
+      
+      if(TMath::Abs(deltaInvMassK0s) > fMassCut &&
+        TMath::Abs(deltaInvMassL) > fMassCut &&
+        TMath::Abs(deltaInvMassAntiL) > fMassCut)
+       continue;
+      
+      // TODO: Whe should these be different? Different mass hypothesis = energy loss
+      // This is not important for us as we focus on the decay products!
+      // Double_t ptK0s        = v0K0sKF.GetPt(); 
+      // Double_t ptL          = v0LambdaKF.GetPt();
+      // Double_t ptAntiL      = v0AntiLambdaKF.GetPt();     
+      
+      Int_t   primaryV0     = 0; // 0 means that the tracks are not both daughters of a primary particle (1 means they are)
+      Int_t   pdgV0         = 0; // 0 means that they don't have same origin for MC (1 means they have the same original mother)
+      Float_t p_ptMC        = 0;
+      Short_t p_pidCode     = 0; // 0 = real data / no mc track!
+      Short_t p_primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   p_pdgMother   = 0;
+      Float_t n_ptMC        = 0;
+      Short_t n_pidCode     = 0; // 0 = real data / no mc track!
+      Short_t n_primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   n_pdgMother   = 0;
+      if(fAnalysisMC) {
+       
+       Int_t p_mother_label = 0;
+       Int_t p_mother_steps = 0;
+       Int_t n_mother_label = 0;
+       Int_t n_mother_steps = 0;
+       
+       // positive track
+       const Int_t p_label = TMath::Abs(pTrackTPC->GetLabel());
+       TParticle* p_mcTrack = fMCStack->Particle(p_label);         
+       if (p_mcTrack){
+         
+         if(fMCStack->IsPhysicalPrimary(p_label))
+           p_primaryFlag = 1;
+         
+         Int_t p_pdgCode = p_mcTrack->GetPdgCode();
+         p_pidCode = GetPidCode(p_pdgCode);
+         
+         p_ptMC      = p_mcTrack->Pt();
+         
+         p_mother_label = FindPrimaryMotherLabel(fMCStack, p_label, 
+                                                 p_mother_steps);
+         if(p_mother_label>0) {
+           TParticle* p_mother = fMCStack->Particle(p_mother_label);
+           p_pdgMother = p_mother->GetPdgCode();
+         }
+       }
+       
+       // negative track
+       const Int_t n_label = TMath::Abs(nTrackTPC->GetLabel());
+       TParticle* n_mcTrack = fMCStack->Particle(n_label);         
+       if (n_mcTrack){
+         
+         if(fMCStack->IsPhysicalPrimary(n_label))
+           n_primaryFlag = 1;
+         
+         Int_t n_pdgCode = n_mcTrack->GetPdgCode();
+         n_pidCode = GetPidCode(n_pdgCode);
+         
+         n_ptMC      = n_mcTrack->Pt();
+         
+         n_mother_label = FindPrimaryMotherLabel(fMCStack, n_label, 
+                                                 n_mother_steps);
+         if(n_mother_label>0) {
+           TParticle* n_mother = fMCStack->Particle(n_mother_label);
+           n_pdgMother = n_mother->GetPdgCode();
+         }
+       }
+       
+       // Check if V0 is primary = first and the same mother of both partciles
+       if(p_mother_label>0 && n_mother_label>0 && p_mother_label == n_mother_label) {
+         pdgV0 = p_pdgMother;
+         if(p_mother_steps == 1 && n_mother_steps == 1) {
+           primaryV0 = 1;
+         }
+       }
+      }
+      
+
+      if(fTreeOption) {
+       
+       DeDxV0* v0datatpc = new((*fV0ArrayTPCPar)[nadded]) DeDxV0();
+       nadded++;
+       
+       // v0 data
+       v0datatpc->p       = esdV0->P();
+       v0datatpc->pt      = esdV0->Pt();
+       v0datatpc->eta     = esdV0->Eta();
+       v0datatpc->phi     = esdV0->Phi();
+       v0datatpc->pdca    = TMath::Sqrt(pdcaxy*pdcaxy + pdcaz*pdcaz);
+       v0datatpc->ndca    = TMath::Sqrt(ndcaxy*ndcaxy + ndcaz*ndcaz);
+       v0datatpc->dmassG  = deltaInvMassG;
+       v0datatpc->dmassK0 = deltaInvMassK0s;
+       v0datatpc->dmassL  = deltaInvMassL;
+       v0datatpc->dmassAL = deltaInvMassAntiL;
+       v0datatpc->alpha   = alpha;
+       v0datatpc->ptarm   = ptarm;
+       v0datatpc->decayr  = lV0Radius;
+       v0datatpc->decayl  = lV0DecayLength;
+       
+       // New parameters
+       v0datatpc->status  = esdV0->GetOnFlyStatus();
+       v0datatpc->chi2    = esdV0->GetChi2V0();
+       v0datatpc->cospt   = esdV0->GetV0CosineOfPointingAngle(); 
+       // cospt: as I understand this means that the pointing to the vertex
+       // is fine so I remove the dcaxy and dcaz for the V= class
+       v0datatpc->dcadaughters = esdV0->GetDcaV0Daughters();
+       v0datatpc->primary = primaryV0;
+       v0datatpc->pdg     = pdgV0;
+       
+       // positive track
+       v0datatpc->ptrack.p       = pp;
+       v0datatpc->ptrack.pt      = ppt;
+       //        v0data->ptrack.ptcon   = ppt_con;
+       //        v0data->ptrack.tpcchi  = ptpcchi;
+       v0datatpc->ptrack.eta     = peta;
+       v0datatpc->ptrack.phi     = pphi;
+       v0datatpc->ptrack.q       = pcharge;
+       v0datatpc->ptrack.ncl     = pncl;
+       v0datatpc->ptrack.neff    = pneff;
+       v0datatpc->ptrack.dedx    = pdedx;
+       v0datatpc->ptrack.dcaxy   = pdcaxy;
+       v0datatpc->ptrack.dcaz    = pdcaz;
+       v0datatpc->ptrack.pid     = p_pidCode;
+       v0datatpc->ptrack.primary = p_primaryFlag;
+       v0datatpc->ptrack.pttrue  = p_ptMC;
+       v0datatpc->ptrack.mother  = p_pdgMother;
+       v0datatpc->ptrack.filter  = filterFlag_p;
+       v0datatpc->ptrack.filterset1 = 0;
+       v0datatpc->ptrack.filterset2 = 0;
+       v0datatpc->ptrack.filterset3 = 0;
+       
+       // negative track
+       v0datatpc->ntrack.p       = np;
+       v0datatpc->ntrack.pt      = npt;
+       //        v0data->ntrack.ptcon   = npt_con;
+       //        v0data->ntrack.tpcchi  = ntpcchi;
+       v0datatpc->ntrack.eta     = neta;
+       v0datatpc->ntrack.phi     = nphi;
+       v0datatpc->ntrack.q       = ncharge;
+       v0datatpc->ntrack.ncl     = nncl;
+       v0datatpc->ntrack.neff    = nneff;
+       v0datatpc->ntrack.dedx    = ndedx;
+       v0datatpc->ntrack.dcaxy   = ndcaxy;
+       v0datatpc->ntrack.dcaz    = ndcaz;
+       v0datatpc->ntrack.pid     = n_pidCode;
+       v0datatpc->ntrack.primary = n_primaryFlag;
+       v0datatpc->ntrack.pttrue  = n_ptMC;
+       v0datatpc->ntrack.mother  = n_pdgMother;
+       v0datatpc->ntrack.filter  = filterFlag_n;
+       v0datatpc->ntrack.filterset1 = 0;
+       v0datatpc->ntrack.filterset2 = 0;
+       v0datatpc->ntrack.filterset3 = 0;
+      }
+      
+      // clean up loop over v0
+      
+      delete negPiKF;
+      delete posPiKF;
+      delete posPKF;
+      delete negAPKF;
+
+
+    }
+
+
+
+  }
+  delete myPrimaryVertex;
+
+  if(fTreeOption) {
+    
+    if( analysisMode==kGlobalTrk ){
+
+      
+      fEvent->trackmult = trackmult;
+      fEvent->n         = nadded;
+
+
+    }
+    
+  }
+
+
+  
+}
+//_______________________________________________________________________________________________________________
+void AliAnalysisTaskHighPtDeDxV0::ProduceArrayTrksAOD( AliAODEvent *AODevent, AnalysisMode analysisMode ){
+  Int_t nv0s = AODevent->GetNumberOfV0s();
+  if(nv0s<1)return;
+  Int_t     trackmult = 0; // no pt cuts
+  Int_t     nadded    = 0;
+  
+  AliAODVertex *myBestPrimaryVertex = AODevent->GetPrimaryVertex();
+  if (!myBestPrimaryVertex) return;
+  
+  
+  if( analysisMode == kGlobalTrk ){
+    if(fV0ArrayGlobalPar)
+      fV0ArrayGlobalPar->Clear();
+  } else if( analysisMode == kTPCTrk ){
+    if(fV0ArrayTPCPar)
+      fV0ArrayTPCPar->Clear();
+  }
+  
+  if( analysisMode==kGlobalTrk ){  
+    
+    
+    // ################################
+    // #### BEGINNING OF V0 CODE ######
+    // ################################
+    // This is the begining of the V0 loop  
+    for (Int_t iV0 = 0; iV0 < nv0s; iV0++) {
+      AliAODv0 *aodV0 = AODevent->GetV0(iV0);
+      if (!aodV0) continue;
+      
+      // common part
+      
+      // AliAODTrack (V0 Daughters)
+      AliAODVertex* vertex = aodV0->GetSecondaryVtx();
+      if (!vertex) {
+       Printf("ERROR: Could not retrieve vertex");
+       continue;
+      }
+      
+      AliAODTrack *pTrack = (AliAODTrack*)vertex->GetDaughter(0);
+      AliAODTrack *nTrack = (AliAODTrack*)vertex->GetDaughter(1);
+      if (!pTrack || !nTrack) {
+       Printf("ERROR: Could not retrieve one of the daughter track");
+       continue;
+      }
+      
+      // Remove like-sign
+      if (pTrack->Charge() == nTrack->Charge()) {
+       //cout<< "like sign, continue"<< endl;
+       continue;
+      } 
+      
+      // Make sure charge ordering is ok
+      if (pTrack->Charge() < 0) {
+       AliAODTrack* helpTrack = pTrack;
+       pTrack = nTrack;
+       nTrack = helpTrack;
+      } 
+      
+      // Eta cut on decay products
+      if(TMath::Abs(pTrack->Eta()) > fEtaCut || TMath::Abs(nTrack->Eta()) > fEtaCut)
+       continue;
+      
+      // Pt cut on decay products
+      if (aodV0->Pt() < fMinPt)
+       //      if (pTrack->Pt() < fMinPt && nTrack->Pt() < fMinPt)
+       continue;
+      
+      //check positive tracks
+      UShort_t filterFlag_p = 0;
+      Bool_t filterCut_Set1_p = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+      Bool_t filterCut_Set2_p = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+      Bool_t filterCut_Set3_p = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+      
+      if (fTrackFilterGolden) {  
+       // ITSTPC2010 cuts is bit 32 according to above macro, new versions of aliroot includes the golden cuts
+       
+       if(pTrack->TestFilterBit(32)) {
+         filterFlag_p +=1;
+         filterCut_Set3_p = kTRUE;
+       }
+      }
+      
+      
+      if (fTrackFilterTPC) {
+       // TPC only cuts is bit 1 according to above macro
+       // Alex always uses 128, NOTE: FILTER 128 ARE TPC TRACKS (TPC PARAMETERS) CONTRAINED TO THE SPD VERTEX, 
+       if(pTrack->TestFilterBit(1)){
+         filterFlag_p +=2;
+         filterCut_Set1_p = kTRUE;
+         
+       }
+      }
+      
+      if(filterFlag_p==0)
+       continue;
+      
+      //check negative tracks
+      UShort_t filterFlag_n = 0;
+      Bool_t filterCut_Set1_n = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+      Bool_t filterCut_Set2_n = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+      Bool_t filterCut_Set3_n = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+      
+      
+      if (fTrackFilterGolden) {
+       
+       // ITSTPC2010 cuts is bit 32 according to above macro, new versions of aliroot includes the golden cuts
+       if(nTrack->TestFilterBit(32)) {
+         filterFlag_n +=1;
+         filterCut_Set3_n = kTRUE;
+       }
+      }
+      
+      
+      if (fTrackFilterTPC) {
+       // TPC only cuts is bit 1 according to above macro
+       // Alex always uses 128, NOTE: FILTER 128 ARE TPC TRACKS (TPC PARAMETERS) CONTRAINED TO THE SPD VERTEX, 
+       if(nTrack->TestFilterBit(1)){
+         filterFlag_n +=2;
+         filterCut_Set1_n = kTRUE;
+         
+       }
+      }
+      
+      if(filterFlag_n==0)
+       continue;
+      
+      
+      Float_t alpha = aodV0->AlphaV0();
+      Float_t ptarm = aodV0->PtArmV0();
+      // Double_t pVtxPos= v0->PrimaryVtxPosition();      
+      
+      Double_t lV0Radius      = aodV0->RadiusV0();
+      Double_t lV0DecayLength = aodV0->DecayLength(myBestPrimaryVertex);
+      
+      Double_t deltaInvMassG     = aodV0->InvMass2Prongs(0,1,11,11);
+      Double_t deltaInvMassK0s   = aodV0->MassK0Short()-0.498;
+      Double_t deltaInvMassL     = aodV0->MassLambda()-1.116;
+      Double_t deltaInvMassAntiL = aodV0->MassAntiLambda()-1.116;
+      
+      if(TMath::Abs(deltaInvMassK0s) > fMassCut &&
+        TMath::Abs(deltaInvMassL) > fMassCut &&
+        TMath::Abs(deltaInvMassAntiL) > fMassCut)
+       continue;
+      
+      // TODO: Why should these be different? Different mass hypothesis = energy loss
+      // This is not important for us as we focus on the decay products!
+      // Double_t ptK0s        = v0K0sKF.GetPt(); 
+      // Double_t ptL          = v0LambdaKF.GetPt();
+      // Double_t ptAntiL      = v0AntiLambdaKF.GetPt();     
+      
+      // Extract track information
+      
+      Double_t b[2], cov[3];
+      if(!pTrack->PropagateToDCA(myBestPrimaryVertex, AODevent->GetMagneticField(), kVeryBig, b, cov))
+       filterFlag_p += 32; // propagation failed!!!!!
+      
+      Float_t pdcaxy   = b[0];
+      Float_t pdcaz    = b[1];
+      if(!nTrack->PropagateToDCA(myBestPrimaryVertex, AODevent->GetMagneticField(), kVeryBig, b, cov))
+       filterFlag_n += 32; // propagation failed!!!!!
+      Float_t ndcaxy   = b[0];
+      Float_t ndcaz    = b[1];
+      
+      Short_t pcharge  = pTrack->Charge();
+      Float_t ppt      = pTrack->Pt();
+      Float_t pp       = pTrack->P(); 
+      Float_t peta     = pTrack->Eta();
+      Float_t pphi     = pTrack->Phi();
+      //       Float_t ptpcchi  = pTrack->Chi2perNDF();
+      
+      AliAODPid* pPid = pTrack->GetDetPid();
+      Short_t pncl     = -10;
+      Short_t pneff    = 0; // This is not yet there! Short_t(aodTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      Float_t pdedx    = -10;
+      Float_t pbeta = -99;
+      if(pPid) {
+       pncl     = pPid->GetTPCsignalN();
+       pdedx    = pPid->GetTPCsignal();
+       //TOF
+       if (pTrack->GetStatus()&AliESDtrack::kTOFpid){
+         Double_t tof[5];
+         pPid->GetIntegratedTimes(tof);
+         pbeta = tof[0]/pPid->GetTOFsignal();
+       }
+      }
+      
+      Short_t ncharge  = nTrack->Charge();
+      Float_t npt      = nTrack->Pt();
+      Float_t np       = nTrack->P(); 
+      Float_t neta     = nTrack->Eta();
+      Float_t nphi     = nTrack->Phi();
+      //       Float_t ntpcchi  = nTrack->Chi2perNDF();
+      
+      AliAODPid* nPid = nTrack->GetDetPid();
+      Short_t nncl     = -10;
+      Short_t nneff    = 0; // This is not yet there! Short_t(aodTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+      Float_t ndedx    = -10;
+      Float_t nbeta = -99;
+      if(pPid) {
+       nncl     = nPid->GetTPCsignalN();
+       ndedx    = nPid->GetTPCsignal();
+       //TOF
+       if (nTrack->GetStatus()&AliESDtrack::kTOFpid){
+         Double_t tof[5];
+         nPid->GetIntegratedTimes(tof);
+         nbeta = tof[0]/nPid->GetTOFsignal();
+       }
+      }
+      
+      Int_t   primaryV0     = 0; // 0 means that the tracks are not both daughters of a primary particle (1 means they are)
+      Int_t   pdgV0         = 0; // 0 means that they don't have same origin for MC (1 means they have the same original mother)
+      Float_t p_ptMC        = 0;
+      Short_t p_pidCode     = 0; // 0 = real data / no mc track!
+      Short_t p_primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   p_pdgMother   = 0;
+      Float_t n_ptMC        = 0;
+      Short_t n_pidCode     = 0; // 0 = real data / no mc track!
+      Short_t n_primaryFlag = 0; // 0 = real data / not primary mc track  
+      Int_t   n_pdgMother   = 0;
+      if(fAnalysisMC) {
+       
+       AliAODMCParticle* p_mother = 0;
+       Int_t p_mother_steps = 0;
+       AliAODMCParticle* n_mother = 0;
+       Int_t n_mother_steps = 0;
+       
+       // positive track
+       const Int_t p_label = TMath::Abs(pTrack->GetLabel());
+       
+       AliAODMCParticle* p_mcTrack = dynamic_cast<AliAODMCParticle*>(fMCArray->At(p_label));
+       if (p_mcTrack){
+         
+         if(p_mcTrack->IsPhysicalPrimary())
+           p_primaryFlag = 1;
+         
+         Int_t p_pdgCode = p_mcTrack->GetPdgCode();
+         p_pidCode = GetPidCode(p_pdgCode);
+         
+         p_ptMC      = p_mcTrack->Pt();
+         
+         p_mother = FindPrimaryMotherAOD(p_mcTrack, p_mother_steps);
+         if(p_mother)
+           p_pdgMother = p_mother->GetPdgCode();
+       }
+       
+       // negative track
+       const Int_t n_label = TMath::Abs(pTrack->GetLabel());
+       
+       AliAODMCParticle* n_mcTrack = dynamic_cast<AliAODMCParticle*>(fMCArray->At(n_label));
+       if (n_mcTrack){
+         
+         if(n_mcTrack->IsPhysicalPrimary())
+           n_primaryFlag = 1;
+         
+         Int_t n_pdgCode = n_mcTrack->GetPdgCode();
+         n_pidCode = GetPidCode(n_pdgCode);
+         
+         n_ptMC      = n_mcTrack->Pt();
+         
+         n_mother = FindPrimaryMotherAOD(n_mcTrack, n_mother_steps);
+         if(n_mother)
+           n_pdgMother = n_mother->GetPdgCode();
+       }
+       
+       // Check if V0 is primary = first and the same mother of both partciles
+       if(p_mother && n_mother && p_mother == n_mother) {
+         pdgV0 = p_pdgMother;
+         if(p_mother_steps == 1 && n_mother_steps == 1) {
+           primaryV0 = 1;
+         }
+       }
+      }
+      
+      if(fTreeOption) {
+       
+       DeDxV0* v0data = new((*fV0ArrayGlobalPar)[nadded]) DeDxV0();
+       nadded++;
+       
+       // v0 data
+       v0data->p       = aodV0->P();
+       v0data->pt      = aodV0->Pt();
+       v0data->eta     = aodV0->Eta();
+       v0data->phi     = aodV0->Phi();
+       v0data->pdca    = aodV0->DcaPosToPrimVertex();
+       v0data->ndca    = aodV0->DcaNegToPrimVertex();
+       v0data->dmassG  = deltaInvMassG;
+       v0data->dmassK0 = deltaInvMassK0s;
+       v0data->dmassL  = deltaInvMassL;
+       v0data->dmassAL = deltaInvMassAntiL;
+       v0data->alpha   = alpha;
+       v0data->ptarm   = ptarm;
+       v0data->decayr  = lV0Radius;
+       v0data->decayl  = lV0DecayLength;
+       // v0data->pdca    = TMath::Sqrt(pdcaxy*pdcaxy + pdcaz*pdcaz);
+       // v0data->ndca    = TMath::Sqrt(ndcaxy*ndcaxy + ndcaz*ndcaz);
+       
+       // New parameters
+       v0data->status  = aodV0->GetOnFlyStatus();
+       v0data->chi2    = aodV0->Chi2V0();
+       v0data->cospt   = aodV0->CosPointingAngle(myBestPrimaryVertex);
+       // cospt: as I understand this means that the pointing to the vertex
+       // is fine so I remove the dcaxy and dcaz for the V= class
+       v0data->dcav0   = aodV0->DcaV0ToPrimVertex();
+       v0data->dcadaughters = aodV0->DcaV0Daughters();
+       v0data->primary = primaryV0;
+       v0data->pdg     = pdgV0;
+       
+       // positive track
+       v0data->ptrack.p       = pp;
+       v0data->ptrack.pt      = ppt;
+       //        v0data->ptrack.ptcon   = ppt_con;
+       //        v0data->ptrack.tpcchi  = ptpcchi;
+       v0data->ptrack.eta     = peta;
+       v0data->ptrack.phi     = pphi;
+       v0data->ptrack.q       = pcharge;
+       v0data->ptrack.ncl     = pncl;
+       v0data->ptrack.neff    = pneff;
+       v0data->ptrack.dedx    = pdedx;
+       v0data->ptrack.dcaxy   = pdcaxy;
+       v0data->ptrack.dcaz    = pdcaz;
+       v0data->ptrack.pid     = p_pidCode;
+       v0data->ptrack.primary = p_primaryFlag;
+       v0data->ptrack.pttrue  = p_ptMC;
+       v0data->ptrack.mother  = p_pdgMother;
+       v0data->ptrack.filter  = filterFlag_p;
+       v0data->ptrack.filterset1 = filterCut_Set1_p;
+       v0data->ptrack.filterset2 = filterCut_Set2_p;
+       v0data->ptrack.filterset3 = filterCut_Set3_p;
+       
+       
+       // negative track
+       v0data->ntrack.p       = np;
+       v0data->ntrack.pt      = npt;
+       //        v0data->ntrack.ptcon   = npt_con;
+       //        v0data->ntrack.tpcchi  = ntpcchi;
+       v0data->ntrack.eta     = neta;
+       v0data->ntrack.phi     = nphi;
+       v0data->ntrack.q       = ncharge;
+       v0data->ntrack.ncl     = nncl;
+       v0data->ntrack.neff    = nneff;
+       v0data->ntrack.dedx    = ndedx;
+       v0data->ntrack.dcaxy   = ndcaxy;
+       v0data->ntrack.dcaz    = ndcaz;
+       v0data->ntrack.pid     = n_pidCode;
+       v0data->ntrack.primary = n_primaryFlag;
+       v0data->ntrack.pttrue  = n_ptMC;
+       v0data->ntrack.mother  = n_pdgMother;
+       v0data->ntrack.filter  = filterFlag_n;
+       v0data->ntrack.filterset1 = filterCut_Set1_n;
+       v0data->ntrack.filterset2 = filterCut_Set2_n;
+       v0data->ntrack.filterset3 = filterCut_Set3_n;
+       
+       
+      }
+    }//end loop over v0's
+    
+    
+  }else if( analysisMode==kTPCTrk ){  
+    
+    const AliAODVertex*        vertexSPD= (AliAODVertex*)AODevent->GetPrimaryVertexSPD();//GetPrimaryVertex()
+    cout<<"&&&&&&&&&&&&&&&&&&&&&                Hello world  0"<<endl;
+    if( vertexSPD->GetNContributors() < 1 || TMath::Abs(vertexSPD->GetZ()) > 10.0 ) return;
+    
+    cout<<"&&&&&&&&&&&&&&&&&&&&&                Hello world"<<endl;
+    // ################################
+    // #### BEGINNING OF V0 CODE ######
+    // ################################
+    // This is the begining of the V0 loop  
+
+
+
+     for (Int_t iV0 = 0; iV0 < nv0s; iV0++) {
+       AliAODv0 *aodV0 = AODevent->GetV0(iV0);
+       if (!aodV0) continue;
+       
+       // common part
+       
+       // AliAODTrack (V0 Daughters)
+       AliAODVertex* vertex = aodV0->GetSecondaryVtx();
+       if (!vertex) {
+        Printf("ERROR: Could not retrieve vertex");
+        continue;
+       }
+       
+       AliAODTrack *pTrack = (AliAODTrack*)vertex->GetDaughter(0);
+       AliAODTrack *nTrack = (AliAODTrack*)vertex->GetDaughter(1);
+       if (!pTrack || !nTrack) {
+        Printf("ERROR: Could not retrieve one of the daughter track");
+        continue;
+       }
+       
+       
+       // Remove like-sign
+       if (pTrack->Charge() == nTrack->Charge()) {
+        //cout<< "like sign, continue"<< endl;
+        continue;
+       } 
+       
+       // Make sure charge ordering is ok
+       if (pTrack->Charge() < 0) {
+        AliAODTrack* helpTrack = pTrack;
+        pTrack = nTrack;
+        nTrack = helpTrack;
+       } 
+       
+       // Eta cut on decay products
+       if(TMath::Abs(pTrack->Eta()) > fEtaCut || TMath::Abs(nTrack->Eta()) > fEtaCut)
+        continue;
+
+       cout<<"Eta positive track:"<<pTrack->Eta()<<endl;
+
+       
+       // Pt cut on decay products
+       if (aodV0->Pt() < fMinPt)
+        //     if (pTrack->Pt() < fMinPt && nTrack->Pt() < fMinPt)
+        continue;
+       
+       //check positive tracks
+       UShort_t filterFlag_p = 0;
+       Bool_t filterCut_Set1_p = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+       Bool_t filterCut_Set2_p = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+       Bool_t filterCut_Set3_p = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+       
+       // TPC only cuts is bit 1 according to above macro
+       // Alex always uses 128, NOTE: FILTER 128 ARE TPC TRACKS (TPC PARAMETERS) CONTRAINED TO THE SPD VERTEX, 
+       if(pTrack->TestFilterBit(128)) {
+        cout<<"este track paso el corte bit 128"<<endl;
+        filterFlag_p +=1;
+       }
+       cout<<"filterFlag_p="<<filterFlag_p<<endl;      
+
+
+
+
+       if(filterFlag_p==0)
+        continue;
+
+
+       //check negative tracks
+       UShort_t filterFlag_n = 0;
+       Bool_t filterCut_Set1_n = kFALSE;//parameters from global tracks, with TPC cuts (filter bit =1 in AOD)
+       Bool_t filterCut_Set2_n = kFALSE;//parameters from global tracks, cuts tpc+its 2010 W/O golden cuts
+       Bool_t filterCut_Set3_n = kFALSE;//parameters from global tracks, cuts its+tpc 2010 WITH golden cuts
+       
+       // TPC only cuts is bit 1 according to above macro
+       // Alex always uses 128, NOTE: FILTER 128 ARE TPC TRACKS (TPC PARAMETERS) CONTRAINED TO THE SPD VERTEX, 
+       if(nTrack->TestFilterBit(128)) {
+        filterFlag_n +=1;
+       }
+       
+       if(filterFlag_n==0)
+        continue;
+       
+       
+       Float_t alpha = aodV0->AlphaV0();
+       Float_t ptarm = aodV0->PtArmV0();
+       // Double_t pVtxPos= v0->PrimaryVtxPosition();      
+       
+       Double_t lV0Radius      = aodV0->RadiusV0();
+       Double_t lV0DecayLength = aodV0->DecayLength(myBestPrimaryVertex);
+       
+       Double_t deltaInvMassG     = aodV0->InvMass2Prongs(0,1,11,11);
+       Double_t deltaInvMassK0s   = aodV0->MassK0Short()-0.498;
+       Double_t deltaInvMassL     = aodV0->MassLambda()-1.116;
+       Double_t deltaInvMassAntiL = aodV0->MassAntiLambda()-1.116;
+       
+       if(TMath::Abs(deltaInvMassK0s) > fMassCut &&
+         TMath::Abs(deltaInvMassL) > fMassCut &&
+         TMath::Abs(deltaInvMassAntiL) > fMassCut)
+        continue;
+       
+       // TODO: Why should these be different? Different mass hypothesis = energy loss
+       // This is not important for us as we focus on the decay products!
+       // Double_t ptK0s        = v0K0sKF.GetPt(); 
+       // Double_t ptL          = v0LambdaKF.GetPt();
+       // Double_t ptAntiL      = v0AntiLambdaKF.GetPt();     
+       
+       // Extract track information
+       
+       Double_t b[2], cov[3];
+       if(!pTrack->PropagateToDCA(vertexSPD, AODevent->GetMagneticField(), kVeryBig, b, cov))
+        filterFlag_p += 32; // propagation failed!!!!!
+       
+       Float_t pdcaxy   = b[0];
+       Float_t pdcaz    = b[1];
+       if(!nTrack->PropagateToDCA(vertexSPD, AODevent->GetMagneticField(), kVeryBig, b, cov))
+        filterFlag_n += 32; // propagation failed!!!!!
+       Float_t ndcaxy   = b[0];
+       Float_t ndcaz    = b[1];
+       
+       Short_t pcharge  = pTrack->Charge();
+       Float_t ppt      = pTrack->Pt();
+       Float_t pp       = pTrack->P(); 
+       Float_t peta     = pTrack->Eta();
+       Float_t pphi     = pTrack->Phi();
+       //      Float_t ptpcchi  = pTrack->Chi2perNDF();
+       
+       AliAODPid* pPid = pTrack->GetDetPid();
+       Short_t pncl     = -10;
+       Short_t pneff    = 0; // This is not yet there! Short_t(aodTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+       Float_t pdedx    = -10;
+       Float_t pbeta = -99;
+       if(pPid) {
+        pncl     = pPid->GetTPCsignalN();
+        pdedx    = pPid->GetTPCsignal();
+        //TOF
+        if (pTrack->GetStatus()&AliESDtrack::kTOFpid){
+          Double_t tof[5];
+          pPid->GetIntegratedTimes(tof);
+          pbeta = tof[0]/pPid->GetTOFsignal();
+        }
+       }
+       
+       Short_t ncharge  = nTrack->Charge();
+       Float_t npt      = nTrack->Pt();
+       Float_t np       = nTrack->P(); 
+       Float_t neta     = nTrack->Eta();
+       Float_t nphi     = nTrack->Phi();
+       //      Float_t ntpcchi  = nTrack->Chi2perNDF();
+       
+       AliAODPid* nPid = nTrack->GetDetPid();
+       Short_t nncl     = -10;
+       Short_t nneff    = 0; // This is not yet there! Short_t(aodTrack->GetTPCClusterInfo(2, 1)); // effective track length for pT res
+       Float_t ndedx    = -10;
+       Float_t nbeta = -99;
+       if(pPid) {
+        nncl     = nPid->GetTPCsignalN();
+        ndedx    = nPid->GetTPCsignal();
+        //TOF
+        if (nTrack->GetStatus()&AliESDtrack::kTOFpid){
+          Double_t tof[5];
+          nPid->GetIntegratedTimes(tof);
+          nbeta = tof[0]/nPid->GetTOFsignal();
+        }
+       }
+       
+       Int_t   primaryV0     = 0; // 0 means that the tracks are not both daughters of a primary particle (1 means they are)
+       Int_t   pdgV0         = 0; // 0 means that they don't have same origin for MC (1 means they have the same original mother)
+       Float_t p_ptMC        = 0;
+       Short_t p_pidCode     = 0; // 0 = real data / no mc track!
+       Short_t p_primaryFlag = 0; // 0 = real data / not primary mc track  
+       Int_t   p_pdgMother   = 0;
+       Float_t n_ptMC        = 0;
+       Short_t n_pidCode     = 0; // 0 = real data / no mc track!
+       Short_t n_primaryFlag = 0; // 0 = real data / not primary mc track  
+       Int_t   n_pdgMother   = 0;
+       if(fAnalysisMC) {
+        
+        AliAODMCParticle* p_mother = 0;
+        Int_t p_mother_steps = 0;
+        AliAODMCParticle* n_mother = 0;
+        Int_t n_mother_steps = 0;
+        
+        // positive track
+        const Int_t p_label = TMath::Abs(pTrack->GetLabel());
+        
+        AliAODMCParticle* p_mcTrack = dynamic_cast<AliAODMCParticle*>(fMCArray->At(p_label));
+        if (p_mcTrack){
+          
+          if(p_mcTrack->IsPhysicalPrimary())
+            p_primaryFlag = 1;
+          
+          Int_t p_pdgCode = p_mcTrack->GetPdgCode();
+          p_pidCode = GetPidCode(p_pdgCode);
+          
+          p_ptMC      = p_mcTrack->Pt();
+          
+          p_mother = FindPrimaryMotherAOD(p_mcTrack, p_mother_steps);
+          if(p_mother)
+            p_pdgMother = p_mother->GetPdgCode();
+        }
+        
+        // negative track
+        const Int_t n_label = TMath::Abs(pTrack->GetLabel());
+        
+        AliAODMCParticle* n_mcTrack = dynamic_cast<AliAODMCParticle*>(fMCArray->At(n_label));
+        if (n_mcTrack){
+          
+          if(n_mcTrack->IsPhysicalPrimary())
+            n_primaryFlag = 1;
+          
+          Int_t n_pdgCode = n_mcTrack->GetPdgCode();
+          n_pidCode = GetPidCode(n_pdgCode);
+          
+          n_ptMC      = n_mcTrack->Pt();
+          
+          n_mother = FindPrimaryMotherAOD(n_mcTrack, n_mother_steps);
+          if(n_mother)
+            n_pdgMother = n_mother->GetPdgCode();
+        }
+        
+        // Check if V0 is primary = first and the same mother of both partciles
+        if(p_mother && n_mother && p_mother == n_mother) {
+          pdgV0 = p_pdgMother;
+          if(p_mother_steps == 1 && n_mother_steps == 1) {
+            primaryV0 = 1;
+          }
+        }
+       }
+       
+       if(fTreeOption) {
+        
+        DeDxV0* v0datatpc = new((*fV0ArrayTPCPar)[nadded]) DeDxV0();
+        nadded++;
+        
+        // v0 data
+        v0datatpc->p       = aodV0->P();
+        v0datatpc->pt      = aodV0->Pt();
+        v0datatpc->eta     = aodV0->Eta();
+        v0datatpc->phi     = aodV0->Phi();
+        v0datatpc->pdca    = aodV0->DcaPosToPrimVertex();
+        v0datatpc->ndca    = aodV0->DcaNegToPrimVertex();
+        v0datatpc->dmassG  = deltaInvMassG;
+        v0datatpc->dmassK0 = deltaInvMassK0s;
+        v0datatpc->dmassL  = deltaInvMassL;
+        v0datatpc->dmassAL = deltaInvMassAntiL;
+        v0datatpc->alpha   = alpha;
+        v0datatpc->ptarm   = ptarm;
+        v0datatpc->decayr  = lV0Radius;
+        v0datatpc->decayl  = lV0DecayLength;
+        // v0data->pdca    = TMath::Sqrt(pdcaxy*pdcaxy + pdcaz*pdcaz);
+        // v0data->ndca    = TMath::Sqrt(ndcaxy*ndcaxy + ndcaz*ndcaz);
+        
+        // New parameters
+        v0datatpc->status  = aodV0->GetOnFlyStatus();
+        v0datatpc->chi2    = aodV0->Chi2V0();
+        v0datatpc->cospt   = aodV0->CosPointingAngle(myBestPrimaryVertex);
+        // cospt: as I understand this means that the pointing to the vertex
+        // is fine so I remove the dcaxy and dcaz for the V= class
+        v0datatpc->dcav0   = aodV0->DcaV0ToPrimVertex();
+        v0datatpc->dcadaughters = aodV0->DcaV0Daughters();
+        v0datatpc->primary = primaryV0;
+        v0datatpc->pdg     = pdgV0;
+        
+        // positive track
+        v0datatpc->ptrack.p       = pp;
+        v0datatpc->ptrack.pt      = ppt;
+        //       v0data->ptrack.ptcon   = ppt_con;
+        //       v0data->ptrack.tpcchi  = ptpcchi;
+        v0datatpc->ptrack.eta     = peta;
+        v0datatpc->ptrack.phi     = pphi;
+        v0datatpc->ptrack.q       = pcharge;
+        v0datatpc->ptrack.ncl     = pncl;
+        v0datatpc->ptrack.neff    = pneff;
+        v0datatpc->ptrack.dedx    = pdedx;
+        v0datatpc->ptrack.dcaxy   = pdcaxy;
+        v0datatpc->ptrack.dcaz    = pdcaz;
+        v0datatpc->ptrack.pid     = p_pidCode;
+        v0datatpc->ptrack.primary = p_primaryFlag;
+        v0datatpc->ptrack.pttrue  = p_ptMC;
+        v0datatpc->ptrack.mother  = p_pdgMother;
+        v0datatpc->ptrack.filter  = filterFlag_p;
+        v0datatpc->ptrack.filterset1 = 0;
+        v0datatpc->ptrack.filterset2 = 0;
+        v0datatpc->ptrack.filterset3 = 0;
+        
+        
+        // negative track
+        v0datatpc->ntrack.p       = np;
+        v0datatpc->ntrack.pt      = npt;
+        //       v0data->ntrack.ptcon   = npt_con;
+        //       v0data->ntrack.tpcchi  = ntpcchi;
+        v0datatpc->ntrack.eta     = neta;
+        v0datatpc->ntrack.phi     = nphi;
+        v0datatpc->ntrack.q       = ncharge;
+        v0datatpc->ntrack.ncl     = nncl;
+        v0datatpc->ntrack.neff    = nneff;
+        v0datatpc->ntrack.dedx    = ndedx;
+        v0datatpc->ntrack.dcaxy   = ndcaxy;
+        v0datatpc->ntrack.dcaz    = ndcaz;
+        v0datatpc->ntrack.pid     = n_pidCode;
+        v0datatpc->ntrack.primary = n_primaryFlag;
+        v0datatpc->ntrack.pttrue  = n_ptMC;
+        v0datatpc->ntrack.mother  = n_pdgMother;
+        v0datatpc->ntrack.filter  = filterFlag_n;
+        v0datatpc->ntrack.filterset1 = 0;
+        v0datatpc->ntrack.filterset2 = 0;
+        v0datatpc->ntrack.filterset3 = 0;
+        
+        
+       }
+     }//end v0's loop
+    
+  }
+  
+  if(fTreeOption) {
+    
+    if( analysisMode==kGlobalTrk ){
+
+      
+      fEvent->trackmult = trackmult;
+      fEvent->n         = nadded;
+      
+      
+    }
+    
+    
+  }
+  
+  
+  
+}
+
+
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDxV0.h b/PWGLF/SPECTRA/IdentifiedHighPt/grid/AliAnalysisTaskHighPtDeDxV0.h
new file mode 100644 (file)
index 0000000..2f14c42
--- /dev/null
@@ -0,0 +1,139 @@
+#ifndef ALIANALYSISTASKHIGHPTDEDXV0_H
+#define ALIANALYSISTASKHIGHPTDEDXV0_H
+
+// ROOT includes
+#include <TList.h>
+#include <TH1.h>
+#include <TTreeStream.h>
+#include <TObject.h>
+
+// AliRoot includes
+#include <AliAnalysisTaskSE.h>
+#include <AliESDEvent.h>
+#include <AliAODEvent.h>
+#include <AliAnalysisFilter.h>
+#include <AliStack.h>
+#include <AliGenEventHeader.h>
+#include <AliVHeader.h>
+#include <AliAODMCParticle.h> 
+
+#include <DebugClasses.C>
+
+
+class AliAnalysisTaskHighPtDeDxV0 : public AliAnalysisTaskSE {
+ public:
+  enum AnalysisMode { kInvalid = -1, kGlobalTrk = 0x1, kTPCTrk = 0x2 }; 
+  AliAnalysisTaskHighPtDeDxV0();
+  AliAnalysisTaskHighPtDeDxV0(const char *name);
+
+  virtual ~AliAnalysisTaskHighPtDeDxV0();
+
+  virtual void   UserCreateOutputObjects();
+  virtual void   UserExec(Option_t *option);
+
+  Bool_t   GetAnalysisMC() { return fAnalysisMC; }   
+  Double_t GetVtxCut() { return fVtxCut; }   
+  Double_t GetEtaCut() { return fEtaCut; }     
+  Double_t GetMinPt() { return fMinPt; }   
+  Int_t    GetTreeOption() { return fTreeOption; }  
+
+  virtual void  SetTrigger1(UInt_t ktriggerInt1) {ftrigBit1 = ktriggerInt1;}
+  virtual void  SetTrigger2(UInt_t ktriggerInt2) {ftrigBit2 = ktriggerInt2;}
+  virtual void  SetTrackFilter(AliAnalysisFilter* trackF) {fTrackFilter = trackF;}
+  virtual void  SetTrackFilterGolden(AliAnalysisFilter* trackF) {fTrackFilterGolden = trackF;}
+  virtual void  SetTrackFilterTPC(AliAnalysisFilter* trackF) {fTrackFilterTPC = trackF;}
+  virtual void  SetProduceTPCBranch(Bool_t prodtpcb) {fTPCBranch = prodtpcb;}
+  virtual void  SetAnalysisType(const char* analysisType) {fAnalysisType = analysisType;}
+  virtual void  SetAnalysisMC(Bool_t isMC) {fAnalysisMC = isMC;}
+  virtual void  SetVtxCut(Double_t vtxCut){fVtxCut = vtxCut;}
+  virtual void  SetEtaCut(Double_t etaCut){fEtaCut = etaCut;}
+  virtual void  SetMinPt(Double_t value) {fMinPt = value;}   
+  virtual void  SetMinCent(Float_t minvalc) {fMinCent = minvalc;}
+  virtual void  SetMaxCent(Float_t maxvalc) {fMaxCent = maxvalc;}
+  virtual void  SetMassCut(Double_t massCut){fMassCut = massCut;}
+  virtual void  SetTreeOption(Int_t value) {fTreeOption = value;}  
+  virtual void  SetRequireRecV0(Bool_t value) {fRequireRecV0 = value;}
+  virtual void  SetStoreMcIn(Bool_t value) {fStoreMcIn = value;}
+  virtual void  SetAnalysisPbPb(Bool_t isanaPbPb) {fAnalysisPbPb = isanaPbPb;}
+
+ private:
+  virtual Float_t GetVertex(const AliVEvent* event) const;
+  virtual void AnalyzeESD(AliESDEvent* esd); 
+  virtual void AnalyzeAOD(AliAODEvent* aod); 
+  virtual void ProduceArrayTrksESD(AliESDEvent* event, AnalysisMode anamode );
+  virtual void ProduceArrayTrksAOD(AliAODEvent* event, AnalysisMode anamode );
+  Short_t   GetPidCode(Int_t pdgCode) const;
+  void      ProcessMCTruthESD();
+  void      ProcessMCTruthAOD(); 
+  void      Sort(TClonesArray* array, Bool_t isMC);
+  Short_t   GetPythiaEventProcessType(Int_t pythiaType);
+  Short_t   GetDPMjetEventProcessType(Int_t dpmJetType);
+  ULong64_t GetEventIdAsLong(AliVHeader* header) const;
+
+  TParticle* FindPrimaryMother(AliStack* stack, Int_t label);
+  Int_t      FindPrimaryMotherLabel(AliStack* stack, Int_t label, Int_t& nSteps);
+
+  AliAODMCParticle* FindPrimaryMotherAOD(AliAODMCParticle* startParticle, Int_t& nSteps);
+
+  static const Double_t fgkClight;   // Speed of light (cm/ps)
+
+  AliESDEvent* fESD;                  //! ESD object
+  AliAODEvent* fAOD;                  //! AOD object
+  AliMCEvent*  fMC;                   //! MC object
+  AliStack*    fMCStack;              //! MC ESD stack
+  TClonesArray* fMCArray;             //! MC array for AOD
+  AliAnalysisFilter* fTrackFilter;    //  Track Filter, old cuts 2010
+  AliAnalysisFilter* fTrackFilterGolden;    //  Track Filter, set 2010 with golden cuts
+  AliAnalysisFilter* fTrackFilterTPC; // track filter for TPC only tracks
+  Bool_t        fTPCBranch;           //tru if you want to produce the TPC branch
+  TString       fAnalysisType;        //  "ESD" or "AOD"
+  Bool_t        fAnalysisMC;          //  Real(kFALSE) or MC(kTRUE) flag
+  Bool_t        fAnalysisPbPb;        //  true you want to analyze PbPb data, false for pp
+  DeDxEvent*    fEvent;               //! event pointer
+  TClonesArray* fV0ArrayGlobalPar;             //! V0 array pointer, global tracks
+  TClonesArray* fV0ArrayTPCPar;             //! V0 array pointer, tpc tracks
+  TClonesArray* fTrackArrayMC;        //! MC track array pointer
+
+  //
+  // Cuts and options
+  //
+  UInt_t       ftrigBit1;
+  UInt_t       ftrigBit2;
+  Double_t     fVtxCut;             // Vtx cut on z position in cm
+  Double_t     fEtaCut;             // Eta cut used to select particles
+  Double_t     fMinPt;              // Min pt - for histogram limits
+  Double_t     fMassCut;            // Reject all v0 with all dmass > masscut!
+  Int_t        fTreeOption;         // 0: no tree, >0: enable debug tree
+  Float_t      fMinCent; //minimum centrality
+  Float_t      fMaxCent; //maximum centrality
+  Bool_t       fRequireRecV0;       // Require a v0 before updating tree
+                                    // For a spectra analysis we will need to
+                                    // keep track also of the empty events
+  Bool_t       fStoreMcIn;          // Store MC input tracks
+  //
+  // Help variables
+  //
+  Short_t      fMcProcessType;      // -1=invalid, 0=data, 1=ND, 2=SD, 3=DD
+  Short_t      fTriggeredEventMB;   // 1 = triggered, 0 = not trigged (MC only)
+  Short_t      fVtxStatus;          // -1 = no vtx, 0 = outside cut, 1 = inside cut
+  Float_t      fZvtx;               // z vertex
+  Float_t      fZvtxMC;             // z vertex MC (truth)
+  Int_t        fRun;                // run no
+  ULong64_t    fEventId;            // unique event id
+              
+  //
+  // Output objects
+  //
+  TList*        fListOfObjects;     //! Output list of objects
+  TH1I*         fEvents;            //! No of accepted events
+  TH1I*         fVtx;               //! Event vertex info
+  TH1F *        fnv0;
+  TH1I*         fVtxMC;             //! Event vertex info for ALL MC events
+  TH1F*         fVtxBeforeCuts;     //! Vertex z dist before cuts
+  TH1F*         fVtxAfterCuts;      //! Vertex z dist after cuts
+  TTree*        fTree;              //! Debug tree 
+
+  ClassDef(AliAnalysisTaskHighPtDeDxV0, 1);    //Analysis task for high pt v0 analysis 
+};
+
+#endif
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/CreateAlienHandler.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/CreateAlienHandler.C
new file mode 100644 (file)
index 0000000..661cb8b
--- /dev/null
@@ -0,0 +1,204 @@
+void SetDataFromConfigFile(AliAnalysisAlien *plugin, const char* filename, Int_t AnalysisMC, Bool_t esdAna, Int_t nMaxRuns);
+
+
+//AliAnalysisGrid* CreateAlienHandler(Int_t nFiles, Bool_t AnalysisMC, Int_t runtype, const char* taskname, const char* mode)
+AliAnalysisGrid* CreateAlienHandler(Int_t nMaxRuns, Int_t AnalysisMC, Bool_t esdAna, const char* taskname,  const char* nameoutputs, const char* mode, const char* label, const char* alirootver, Int_t task_num)
+{
+  
+  AliAnalysisAlien *plugin = new AliAnalysisAlien();
+  
+  plugin->SetRunMode(mode);
+  
+  // Set versions of used packages
+  plugin->SetAPIVersion("V1.1x");
+  plugin->SetROOTVersion("v5-30-06");
+  plugin->SetAliROOTVersion(alirootver);
+
+  Char_t configfile[64];
+  sprintf(configfile,"%s.conf",label);
+
+  cout << "Configuration file: " << configfile << endl;
+
+  if(AnalysisMC){
+    if(esdAna)
+      sprintf(label, "%s_MC_ESDs_%d", label, AnalysisMC);
+    else
+      sprintf(label, "%s_MC_AODs_%d", label, AnalysisMC);
+  }
+  else{
+    if(esdAna)
+      sprintf(label, "%s_Data_ESDs", label);
+    else
+      sprintf(label, "%s_Data_AODs", label);
+  }
+  cout << "Label: " << label << endl;
+
+  // output to run numbers
+  plugin->SetOutputToRunNo();
+
+  SetDataFromConfigFile(plugin, configfile, AnalysisMC, esdAna, nMaxRuns);  
+
+  //  sprintf(outputfiles,"%s_%s.root %sDebug.root",taskname,label,taskname);
+  //Char_t outputfiles[256];
+  //sprintf(outputfiles,"%s_Tree.root",taskname);
+
+// Method 2: Declare existing data files (raw collections, xml
+// collections, root file) If no path mentioned data is supposed to be
+// in the work directory (see SetGridWorkingDir()) XML collections
+// added via this method can be combined with the first method if the
+// content is compatible (using or not tags)
+// plugin->AddDataFile("tag.xml");
+// plugin->AddDataFile("/alice/data/2008/LHC08c/000057657/raw/Run57657.Merged.RAW.tag.root");
+  
+
+// Define alien work directory where all files will be copied. Relative to alien $HOME.
+  Char_t tmpname[128];
+  sprintf(tmpname,"work_%s_%s",taskname,label);
+  plugin->SetGridWorkingDir(tmpname);
+  
+  // Declare alien output directory. Relative to working directory.
+  plugin->SetGridOutputDir("output"); // In this case will be $HOME/work/output
+  
+  // Declare the analysis source files names separated by blancs. To be compiled runtime
+  // using ACLiC on the worker nodes.
+  plugin->AddIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include");
+  Char_t anasource[256];
+  if(task_num!=4){
+    sprintf(anasource, "DebugClasses.C AliAnalysisTask%s.cxx", taskname);
+  }
+  else{
+    sprintf(anasource, "DebugClasses.C AliAnalysisTask%s.cxx AliAnalysisTask%sV0.cxx", taskname, taskname);
+  }
+  plugin->SetAnalysisSource(anasource);
+  
+  // Declare all libraries (other than the default ones for the framework. These will be
+  // loaded by the generated analysis macro. Add all extra files (task .cxx/.h) here.
+  Char_t addlib[256];
+  if(task_num!=4){
+    sprintf(addlib, "DebugClasses.C AliAnalysisTask%s.h AliAnalysisTask%s.cxx", taskname, taskname);
+  }else{
+    sprintf(addlib, "DebugClasses.C AliAnalysisTask%s.h AliAnalysisTask%s.cxx AliAnalysisTask%sV0.h AliAnalysisTask%sV0.cxx", taskname, taskname, taskname, taskname);
+  }
+  plugin->SetAdditionalLibs(addlib);
+   
+   // Declare the output file names separated by blancs.
+   // (can be like: file.root or file.root@ALICE::Niham::File)
+   plugin->SetDefaultOutputs(kFALSE);
+   plugin->SetOutputFiles(nameoutputs);
+
+   //plugin->SetMergeViaJDL(kTRUE);
+
+
+   
+   // Optionally set a name for the generated analysis macro (default MyAnalysis.C)
+   sprintf(tmpname,"macro_%s_%s.C",taskname,label);
+   plugin->SetAnalysisMacro(tmpname);
+   
+// Optionally set maximum number of input files/subjob (default 100, put 0 to ignore)
+   plugin->SetSplitMaxInputFileNumber(100);
+   
+// Optionally set number of failed jobs that will trigger killing waiting sub-jobs.
+   plugin->SetMaxInitFailed(500);
+   
+   // Optionally resubmit threshold.
+   plugin->SetMasterResubmitThreshold(90);
+   
+   // Optionally set time to live (default 30000 sec)
+   // plugin->SetTTL(7200);
+   plugin->SetTTL(30000);
+   
+   // Optionally set input format (default xml-single)
+   plugin->SetInputFormat("xml-single");
+   
+   // Optionally modify the name of the generated JDL (default analysis.jdl)
+   sprintf(tmpname,"%s_%s.jdl",taskname,label);
+   plugin->SetJDLName(tmpname);
+   
+   // Optionally modify the executable name (default analysis.sh)
+   sprintf(tmpname,"%s_%s.sh",taskname,label);
+   plugin->SetExecutable(tmpname);
+   
+   // Optionally modify job price (default 1)
+   plugin->SetPrice(1); 
+   // Merge via JDL
+   plugin->SetMergeViaJDL(kTRUE);
+   // Use fastread option
+   plugin->SetFastReadOption(kTRUE);
+   // Optionally modify split mode (default 'se')    
+   plugin->SetSplitMode("se");
+   plugin->SetExecutableCommand("aliroot -b -q");
+
+  
+
+   return plugin;
+} 
+
+
+
+
+
+void SetDataFromConfigFile(AliAnalysisAlien *plugin, const char* fileName, Int_t AnalysisMC, Bool_t esdAna, Int_t nMaxRuns)
+{
+
+
+  FILE* file = fopen(fileName,"r");
+  if(!file) {
+    cout << "File " << fileName << " not found!" << endl;
+    return;
+  }
+
+  Char_t dummy[128];
+
+  Char_t runperiodpattern[128];
+  if(AnalysisMC)
+    sprintf(runperiodpattern,"Run period MC%d: %s", AnalysisMC, "%s %s %s");
+  else
+    sprintf(runperiodpattern,"Run period: %s", "%s %s %s");
+
+  cout << "PATTERN: " << runperiodpattern << endl;
+
+  Int_t nRuns = 0;
+  while (fgets(dummy,128,file) != NULL && (nRuns<nMaxRuns||nMaxRuns<=0)) {     
+    char runperiod[128], pass[64], aodDir[64];
+    Int_t run, a, b;
+    if(sscanf(dummy, runperiodpattern, &runperiod, &pass, &aodDir)){
+      //if(sscanf(dummy, "Run period: %d %d",&a,&b)){
+      Char_t griddatadir[256];
+      Char_t datapattern[256];
+      
+      if(AnalysisMC){
+       sprintf(griddatadir, "/alice/sim/%s", runperiod);
+       if(esdAna) {
+         sprintf(datapattern,"/*/AliESDs.root");
+       } else {
+         sprintf(datapattern,"/%s/*/AliAOD.root", aodDir);
+       }
+      }
+      else{
+       plugin->SetRunPrefix("000");
+       Int_t year = 0;
+       sscanf(runperiod, "LHC%d", &year);
+       sprintf(griddatadir, "/alice/data/20%d/%s", year, runperiod);
+       if(esdAna) {
+         sprintf(datapattern,"*ESDs/%s/*/AliESDs.root",pass);
+         //sprintf(datapattern,"*ESDs/%s/10000121040024.40/AliESDs.root",pass);
+       } else {
+         sprintf(datapattern,"*ESDs/%s/%s/*/AliAOD.root",pass, aodDir);
+       }
+      }
+      cout << "GridDataDir: " << griddatadir << endl;
+      cout << "DataPatter: " << datapattern << endl;
+      plugin->SetGridDataDir(griddatadir);
+      plugin->SetDataPattern(datapattern);
+      continue;
+    }
+    if(sscanf(dummy,"Run: %d %s", &run)){
+      plugin->AddRunNumber(run);
+      nRuns++;
+      continue;
+    }
+  }
+
+
+
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/DebugClasses.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/DebugClasses.C
new file mode 100644 (file)
index 0000000..64a236a
--- /dev/null
@@ -0,0 +1,242 @@
+class DeDxTrack : public TObject
+{
+ public:
+  Float_t   p;
+  Float_t   pt;
+  //  Float_t   ptcon;
+  Float_t   pttrue;
+  //  Float_t   tpcchi;
+  Float_t   eta;
+  Float_t   phi;
+  Float_t   dedx;
+  Float_t   beta;
+  Float_t   dcaxy;
+  Float_t   dcaz;
+  Int_t     mother; // pdg of mother (can be same particle)
+  Short_t   q;
+  Short_t   filter;
+  Short_t   ncl;
+  Short_t   neff;
+  Short_t   pid;
+  Short_t   primary;  
+  Short_t   order;
+  Bool_t filterset1;//TPC  
+  Bool_t filterset2;//2010 old
+  Bool_t filterset3;//2010 golden
+
+
+  DeDxTrack();
+  
+  ClassDef(DeDxTrack, 1);    // Help class
+};
+//_________________________________________________________
+class VZEROCell : public TObject
+{
+ public:
+
+  Int_t   cellmult;
+  Float_t cellindex;
+  VZEROCell();
+  
+  ClassDef(VZEROCell, 1);    // Help class
+};
+
+
+//_____________________________________________________________________________
+class DeDxV0 : public TObject
+{
+ public:
+  Float_t   p;
+  Float_t   pt;
+  Float_t   eta;
+  Float_t   phi;
+  Float_t   pdca;     // Distance of Closest Approach for positive track
+  Float_t   ndca;     // Distance of Closest Approach for positive track
+  Float_t   dmassG;
+  Float_t   dmassK0;
+  Float_t   dmassL;
+  Float_t   dmassAL;
+  Float_t   alpha;
+  Float_t   ptarm;
+  Float_t   decayr;
+  Float_t   decayl;
+  // new
+  Float_t   chi2;
+  Float_t   cospt;
+  Float_t   dcav0;
+  Float_t   dcadaughters;
+  Int_t     pdg;
+  Short_t   primary;  
+  Short_t   status;  
+  // old
+  DeDxTrack ptrack;
+  DeDxTrack ntrack;
+  
+  DeDxV0();
+  
+  ClassDef(DeDxV0, 1);    // Help class
+};
+
+
+//_____________________________________________________________________________
+class DeDxTrackMC : public TObject
+{
+ public:
+  Float_t pMC;
+  Float_t ptMC;
+  Float_t etaMC;
+  Float_t phiMC;
+  Short_t qMC;
+  Short_t pidMC;
+  Short_t orderMC;
+  Int_t   pdgMC;
+
+  DeDxTrackMC();
+  
+  ClassDef(DeDxTrackMC, 1);    // Help class for MC track debug info
+};
+
+//_____________________________________________________________________________
+class DeDxEvent : public TObject
+{
+ public:
+  ULong64_t eventid;     // unique event id
+  Int_t     run;         // run number
+  UInt_t    time;        // time of event
+  Float_t   cent;        // centrality
+  Float_t   mag;         // magnetic field
+  Float_t   zvtx;        // rec vertex
+  Float_t   zvtxMC;      // MC true vertes
+  Float_t   ptmax;       // Max pt of tracks for this event
+  Float_t   ptmaxMC;     // Max pt of MC tracks
+  Short_t   vtxstatus;   // Vtx status (-1=no vtx, 0 = outside, 1 = inside cuts)
+  Short_t   trackmult;   // Track mult (no cuts)
+  Short_t   n;           // Number of added tracks 
+  Short_t   trackmultMC; // MC track mult (primary tracks)
+  Short_t   nMC;         // MC number of added tracks 
+  Short_t   process;     // MC process: -1=invalid, 0=data, 1=ND, 2=SD, 3=DD
+  Short_t   trig;        // 0=untriggered, &1 = MB, &2=V0 AND
+  Short_t   pileup;      // Is the event marked as pileup?
+  
+  DeDxEvent();
+  
+  ClassDef(DeDxEvent, 1);    // Help class
+};
+
+//_____________________________________________________________________________
+ClassImp(DeDxTrack)
+
+DeDxTrack::DeDxTrack():
+TObject(),
+  p(-1),
+  pt(-1),
+//  ptcon(-1),
+  pttrue(-1),
+//  tpcchi(-1),
+  eta(-999),
+  phi(-999),
+  dedx(-999),
+  beta(-999),
+  dcaxy(-999),
+  dcaz(-999),
+  mother(0),
+  q(-999),
+  filter(-999),
+  ncl(-999),
+  neff(-999),
+  pid(-999),
+  primary(-999),
+  order(-1),
+  filterset1(0),
+  filterset2(0),
+  filterset3(0)
+
+{
+  // default constructor
+}
+//_____________________________________________________________________________
+ClassImp(VZEROCell)
+
+VZEROCell::VZEROCell():
+TObject(),
+  cellmult(-1),
+  cellindex(-999)
+
+{
+  // default constructor
+}
+
+//_____________________________________________________________________________
+ClassImp(DeDxV0)
+
+DeDxV0::DeDxV0():
+TObject(),
+  p(-1),
+  pt(-1),
+  eta(-999),
+  phi(-999),
+  pdca(-1),
+  ndca(-1),
+  dmassG(-1),
+  dmassK0(-1),
+  dmassL(-1),
+  dmassAL(-1),
+  alpha(-999),
+  ptarm(-999),
+  decayr(-999),
+  decayl(-999),
+  chi2(-1),
+  cospt(-999),
+  dcav0(999),
+  dcadaughters(999),
+  pdg(0),
+  primary(-1),  
+  status(),  
+  ptrack(),
+  ntrack()
+{
+  // default constructor
+}
+
+//_____________________________________________________________________________
+ClassImp(DeDxTrackMC)
+
+DeDxTrackMC::DeDxTrackMC():
+TObject(),
+  pMC(-1),
+  ptMC(-1),
+  etaMC(-999),
+  phiMC(-999),
+  qMC(-999),
+  pidMC(-999),
+  orderMC(-1),
+  pdgMC(0)
+{
+  // default constructor
+}
+
+//_____________________________________________________________________________
+ClassImp(DeDxEvent)
+
+DeDxEvent::DeDxEvent():
+TObject(),
+  eventid(0),      // unique event id
+  run(-1),         // run number
+  time(-1),        // time of event
+  cent(1000),      // centrality
+  mag(+999),       // magnetic field
+  zvtx(+999),      // rec vertex
+  zvtxMC(+999),    // MC true vertes
+  ptmax(-1),       // Max pt of tracks for this event
+  ptmaxMC(-1),     // Max pt of MC tracks
+  vtxstatus(-2),   // Vtx status (-1=no vtx, 0 = outside, 1 = inside cuts)
+  trackmult(-1),   // Track mult (no cuts)
+  n(-1),           // Number of added tracks 
+  trackmultMC(-1), // MC track mult (primary tracks)
+  nMC(-1),         // MC number of added tracks 
+  process(-2),     // MC process: -1=invalid, 0=data, 1=ND, 2=SD, 3=DD
+  trig(-1),        // Was the event triggered
+  pileup(-1)       // Is the event marked as pileup?
+{
+  // default constructor
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/DebugClasses_C.d b/PWGLF/SPECTRA/IdentifiedHighPt/grid/DebugClasses_C.d
new file mode 100644 (file)
index 0000000..b24cfef
--- /dev/null
@@ -0,0 +1,4 @@
+
+# DO NOT DELETE
+../grid/DebugClasses_C.so: /home/pchristi/software/root/include/cintdictversion.h /home/pchristi/software/root/include/RVersion.h
+DebugClasses_C__ROOTBUILDVERSION= 5.30/06
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/HighPtDeDx_lhc10b_Data_ESDs_merge.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/HighPtDeDx_lhc10b_Data_ESDs_merge.C
new file mode 100644 (file)
index 0000000..8405fb6
--- /dev/null
@@ -0,0 +1,94 @@
+void HighPtDeDx_lhc10b_Data_ESDs_merge(const char *dir, Int_t stage=0)
+{
+// Automatically generated merging macro executed in grid subjobs
+
+   TStopwatch timer;
+   timer.Start();
+
+// Reset existing include path and add current directory first in the search
+   gSystem->SetIncludePath("-I.");
+// Load analysis framework libraries
+   gSystem->Load("libANALYSIS");
+   gSystem->Load("libOADB");
+   gSystem->Load("libANALYSISalice");
+   gSystem->Load("libCORRFW");
+
+// include path
+   TString intPath = gInterpreter->GetIncludePath();
+   TObjArray *listpaths = intPath.Tokenize(" ");
+   TIter nextpath(listpaths);
+   TObjString *pname;
+   while ((pname=(TObjString*)nextpath())) {
+      TString current = pname->GetName();
+      if (current.Contains("AliRoot") || current.Contains("ALICE_ROOT")) continue;
+      gSystem->AddIncludePath(current);
+   }
+   if (listpaths) delete listpaths;
+   gSystem->AddIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include ");
+   gROOT->ProcessLine(".include $ALICE_ROOT/include");
+   printf("Include path: %s\n", gSystem->GetIncludePath());
+
+// Add aditional AliRoot libraries
+
+// Analysis source to be compiled at runtime (if any)
+   gROOT->ProcessLine(".L DebugClasses.C+g");
+   gROOT->ProcessLine(".L AliAnalysisTaskHighPtDeDx.cxx+g");
+   gROOT->ProcessLine(".L AliAnalysisTaskHighPtDeDxV0.cxx+g");
+
+// fast xrootd reading enabled
+   printf("!!! You requested FastRead option. Using xrootd flags to reduce timeouts. Note that this may skip some files that could be accessed !!!");
+   gEnv->SetValue("XNet.ConnectTimeout",50);
+   gEnv->SetValue("XNet.RequestTimeout",50);
+   gEnv->SetValue("XNet.MaxRedirectCount",2);
+   gEnv->SetValue("XNet.ReconnectTimeout",50);
+   gEnv->SetValue("XNet.FirstConnectMaxCnt",1);
+
+// Set temporary merging directory to current one
+   gSystem->Setenv("TMPDIR", gSystem->pwd());
+
+// Set temporary compilation directory to current one
+   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
+
+// Connect to AliEn
+   if (!TGrid::Connect("alien://")) return;
+   TString outputDir = dir;
+   TString outputFiles = "EventStat_temp.root,HighPtDeDx_Tree.root,HighPtDeDxV0_Tree.root";
+   TString mergeExcludes = " ";
+   TObjArray *list = outputFiles.Tokenize(",");
+   TIter *iter = new TIter(list);
+   TObjString *str;
+   TString outputFile;
+   Bool_t merged = kTRUE;
+   while((str=(TObjString*)iter->Next())) {
+      outputFile = str->GetString();
+      if (outputFile.Contains("*")) continue;
+      Int_t index = outputFile.Index("@");
+      if (index > 0) outputFile.Remove(index);
+      // Skip already merged outputs
+      if (!gSystem->AccessPathName(outputFile)) {
+         printf("Output file <%s> found. Not merging again.",outputFile.Data());
+         continue;
+      }
+      if (mergeExcludes.Contains(outputFile.Data())) continue;
+      merged = AliAnalysisAlien::MergeOutput(outputFile, outputDir, 100, stage);
+      if (!merged) {
+         printf("ERROR: Cannot merge %s\n", outputFile.Data());
+         return;
+      }
+   }
+   // all outputs merged, validate
+   ofstream out;
+   out.open("outputs_valid", ios::out);
+   out.close();
+   // read the analysis manager from file
+   if (!outputDir.Contains("Stage")) return;
+   AliAnalysisManager *mgr = AliAnalysisAlien::LoadAnalysisManager("HighPtDeDx_lhc10b_Data_ESDs.root");
+   if (!mgr) return;
+   mgr->SetRunFromPath(mgr->GetRunFromAlienPath(dir));
+   mgr->SetSkipTerminate(kFALSE);
+   mgr->PrintStatus();
+   AliLog::SetGlobalLogLevel(AliLog::kError);
+   TTree *tree = NULL;
+   mgr->StartAnalysis("gridterminate", tree);
+}
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/HighPtDeDx_lhc10c_Data_ESDs_merge.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/HighPtDeDx_lhc10c_Data_ESDs_merge.C
new file mode 100644 (file)
index 0000000..283fd44
--- /dev/null
@@ -0,0 +1,94 @@
+void HighPtDeDx_lhc10c_Data_ESDs_merge(const char *dir, Int_t stage=0)
+{
+// Automatically generated merging macro executed in grid subjobs
+
+   TStopwatch timer;
+   timer.Start();
+
+// Reset existing include path and add current directory first in the search
+   gSystem->SetIncludePath("-I.");
+// Load analysis framework libraries
+   gSystem->Load("libANALYSIS");
+   gSystem->Load("libOADB");
+   gSystem->Load("libANALYSISalice");
+   gSystem->Load("libCORRFW");
+
+// include path
+   TString intPath = gInterpreter->GetIncludePath();
+   TObjArray *listpaths = intPath.Tokenize(" ");
+   TIter nextpath(listpaths);
+   TObjString *pname;
+   while ((pname=(TObjString*)nextpath())) {
+      TString current = pname->GetName();
+      if (current.Contains("AliRoot") || current.Contains("ALICE_ROOT")) continue;
+      gSystem->AddIncludePath(current);
+   }
+   if (listpaths) delete listpaths;
+   gSystem->AddIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include ");
+   gROOT->ProcessLine(".include $ALICE_ROOT/include");
+   printf("Include path: %s\n", gSystem->GetIncludePath());
+
+// Add aditional AliRoot libraries
+
+// Analysis source to be compiled at runtime (if any)
+   gROOT->ProcessLine(".L DebugClasses.C+g");
+   gROOT->ProcessLine(".L AliAnalysisTaskHighPtDeDx.cxx+g");
+   gROOT->ProcessLine(".L AliAnalysisTaskHighPtDeDxV0.cxx+g");
+
+// fast xrootd reading enabled
+   printf("!!! You requested FastRead option. Using xrootd flags to reduce timeouts. Note that this may skip some files that could be accessed !!!");
+   gEnv->SetValue("XNet.ConnectTimeout",50);
+   gEnv->SetValue("XNet.RequestTimeout",50);
+   gEnv->SetValue("XNet.MaxRedirectCount",2);
+   gEnv->SetValue("XNet.ReconnectTimeout",50);
+   gEnv->SetValue("XNet.FirstConnectMaxCnt",1);
+
+// Set temporary merging directory to current one
+   gSystem->Setenv("TMPDIR", gSystem->pwd());
+
+// Set temporary compilation directory to current one
+   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
+
+// Connect to AliEn
+   if (!TGrid::Connect("alien://")) return;
+   TString outputDir = dir;
+   TString outputFiles = "EventStat_temp.root,HighPtDeDx_Tree.root,HighPtDeDxV0_Tree.root";
+   TString mergeExcludes = " ";
+   TObjArray *list = outputFiles.Tokenize(",");
+   TIter *iter = new TIter(list);
+   TObjString *str;
+   TString outputFile;
+   Bool_t merged = kTRUE;
+   while((str=(TObjString*)iter->Next())) {
+      outputFile = str->GetString();
+      if (outputFile.Contains("*")) continue;
+      Int_t index = outputFile.Index("@");
+      if (index > 0) outputFile.Remove(index);
+      // Skip already merged outputs
+      if (!gSystem->AccessPathName(outputFile)) {
+         printf("Output file <%s> found. Not merging again.",outputFile.Data());
+         continue;
+      }
+      if (mergeExcludes.Contains(outputFile.Data())) continue;
+      merged = AliAnalysisAlien::MergeOutput(outputFile, outputDir, 100, stage);
+      if (!merged) {
+         printf("ERROR: Cannot merge %s\n", outputFile.Data());
+         return;
+      }
+   }
+   // all outputs merged, validate
+   ofstream out;
+   out.open("outputs_valid", ios::out);
+   out.close();
+   // read the analysis manager from file
+   if (!outputDir.Contains("Stage")) return;
+   AliAnalysisManager *mgr = AliAnalysisAlien::LoadAnalysisManager("HighPtDeDx_lhc10c_Data_ESDs.root");
+   if (!mgr) return;
+   mgr->SetRunFromPath(mgr->GetRunFromAlienPath(dir));
+   mgr->SetSkipTerminate(kFALSE);
+   mgr->PrintStatus();
+   AliLog::SetGlobalLogLevel(AliLog::kWarning);
+   TTree *tree = NULL;
+   mgr->StartAnalysis("gridterminate", tree);
+}
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/ListDirectories.h b/PWGLF/SPECTRA/IdentifiedHighPt/grid/ListDirectories.h
new file mode 100644 (file)
index 0000000..3c12b5a
--- /dev/null
@@ -0,0 +1,51 @@
+//---------------------------------------------------------\r
+// PARAMETERS TO BE SET BY HAND\r
+\r
+\r
+const Int_t runs[]={\r
+\r
+  //117222,\r
+  \r
+  117220,\r
+  117116,\r
+  117112,\r
+  117109,\r
+  117099,\r
+  117092,\r
+  117086,\r
+  117077,\r
+  117065,\r
+  117063,\r
+  117060,\r
+  117059,\r
+  117054,\r
+  117053,\r
+  117052,\r
+  117050,\r
+  117048,\r
+  116645,\r
+  116643,\r
+  116574,\r
+  116571,\r
+  116562,\r
+  116403,\r
+  116402,\r
+  116288,\r
+  116102,\r
+  115414,\r
+  115401,\r
+  115393,\r
+  115193,\r
+  115186,\r
+  114931,\r
+  -1\r
+  \r
+};\r
+\r
+\r
+TString location="/alice/cern.ch/user/a/aortizve/work_HighPtDeDx_lhc10b_Data_ESDs/output";\r
+//  TString output="ESDs/pass1_4plus/QA";\r
+//TString output="output";\r
+\r
+//const char * localPath   = "./cache_41/";\r
+const char * localPath   = "./files/";\r
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/copyStatisticFiles.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/copyStatisticFiles.C
new file mode 100644 (file)
index 0000000..2d7d5d5
--- /dev/null
@@ -0,0 +1,115 @@
+//using namespace std;
+
+#include <iostream>
+
+#include "ListDirectories.h"
+
+
+
+const char * GetLocalFileName1(Int_t run,  const char * path);
+const char * GetLocalFileName2(Int_t run,  const char * path);
+//---------------------------------------------------------
+
+
+void copyStatisticFiles() {
+  
+  
+  
+  
+  //loading libraries
+  loadlibs();
+  
+  // connect to grid
+  TGrid::Connect("alien://");  
+  
+  // do not use scientific notation for run number
+  TGaxis::SetMaxDigits(7)  ;
+  
+  
+  // loop over all files
+  Int_t ifile =-1;
+  Int_t ifileGood = 0;
+  Int_t ifileNotEmpty  = 0;
+  while (runs[++ifile] > 0) {
+    
+    
+    //loop over two root files
+    for(Int_t i=0;i<2;++i){
+      
+      Long_t *id,*size,*flags,*mt;
+      
+      TString file;
+      TFile *fr=0;
+      TString file2 ;
+      TFile *fr2=0;
+      
+      TFile *fc=0; // centrality, only in local mode for the time being
+      
+      cout<<"location.Data()="<<location.Data()<<endl;
+      cout<<"runs[ifile]="<<runs[ifile]<<endl;
+      //cout<<" output.Data()="<<output.Data()<<endl;
+      
+      
+      switch(i){
+      case 0:{
+       file.Form("alien://%s/000%d/HighPtDeDx_Tree.root",location.Data(),runs[ifile] );
+       
+       Printf("\nBegin of reading: %s", file.Data());    
+       
+       gSystem->Exec(Form("alien_cp %s %s",file.Data(), GetLocalFileName1(runs[ifile],  localPath)));
+       cout << Form("alien_cp %s %s",file.Data(), GetLocalFileName1(runs[ifile], localPath)) <<endl;
+      }break;
+      case 1:{
+       file.Form("alien://%s/000%d/HighPtDeDxV0_Tree.root",location.Data(),runs[ifile] );
+       
+       Printf("\nBegin of reading: %s", file.Data());    
+       
+       gSystem->Exec(Form("alien_cp %s %s",file.Data(), GetLocalFileName2(runs[ifile],  localPath)));
+       cout << Form("alien_cp %s %s",file.Data(), GetLocalFileName2(runs[ifile], localPath)) <<endl;
+      }break;
+       
+       
+       
+      }
+      
+      
+    }
+    //gSystem->Exec(Form("alien_cp %s %s",file2.Data(), GetLocalFileName2(runs[ifile], localSuffix, localPath)));
+    //cout << Form("alien_cp %s %s",file2.Data(), GetLocalFileName2(runs[ifile], localSuffix, localPath)) <<endl;   
+    
+    
+  }
+}
+
+const char * GetLocalFileName1(Int_t run, const char * path) {
+  // returns the filename of the local copy of the event_stat file
+  static TString name;
+  //  name.Form("%s/event_stat_%s_%d.root", path, suffix, run);
+  name.Form("%s/HighPtDeDx_Tree_%d.root", path, run);
+  return name.Data();
+
+}
+const char * GetLocalFileName2(Int_t run, const char * path) {
+  // returns the filename of the local copy of the event_stat file
+  static TString name;
+  //  name.Form("%s/event_stat_%s_%d.root", path, suffix, run);
+  name.Form("%s/HighPtDeDxV0_Tree_%d.root", path, run);
+  return name.Data();
+
+}
+
+void loadlibs()
+{
+  gSystem->Load("libVMC");
+  gSystem->Load("libTree");
+  gSystem->Load("libSTEERBase");
+  gSystem->Load("libESD");
+  gSystem->Load("libAOD");
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  gSystem->Load("libCORRFW");
+  gSystem->Load("libMinuit");
+  gSystem->Load("libPWG2spectra");
+  gSystem->Load("libPWG0base"); 
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/lhc10b.conf b/PWGLF/SPECTRA/IdentifiedHighPt/grid/lhc10b.conf
new file mode 100644 (file)
index 0000000..dd02b86
--- /dev/null
@@ -0,0 +1,35 @@
+Run period: LHC10b pass3 AOD067
+Run period MC1: LHC11a10a dummy AOD048 (Pythia)
+Run: 117222
+Run: 117220
+Run: 117116
+Run: 117112
+Run: 117109
+Run: 117099
+Run: 117092
+Run: 117086
+Run: 117077
+Run: 117065
+Run: 117063
+Run: 117060
+Run: 117059
+Run: 117054
+Run: 117053
+Run: 117052
+Run: 117050
+Run: 117048
+Run: 116645
+Run: 116643
+Run: 116574
+Run: 116571
+Run: 116562
+Run: 116403
+Run: 116402
+Run: 116288
+Run: 116102
+Run: 115414
+Run: 115401
+Run: 115393
+Run: 115193
+Run: 115186
+Run: 114931
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/macro_HighPtDeDx_lhc10b_Data_ESDs.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/macro_HighPtDeDx_lhc10b_Data_ESDs.C
new file mode 100644 (file)
index 0000000..cdca5cb
--- /dev/null
@@ -0,0 +1,107 @@
+const char *anatype = "ESD";
+
+void macro_HighPtDeDx_lhc10b_Data_ESDs()
+{
+// Analysis using ESD data
+// Automatically generated analysis steering macro executed in grid subjobs
+
+   TStopwatch timer;
+   timer.Start();
+
+// Set temporary merging directory to current one
+   gSystem->Setenv("TMPDIR", gSystem->pwd());
+
+// Set temporary compilation directory to current one
+   gSystem->SetBuildDir(gSystem->pwd(), kTRUE);
+
+// Reset existing include path and add current directory first in the search
+   gSystem->SetIncludePath("-I.");
+// Load analysis framework libraries
+   gSystem->Load("libANALYSIS");
+   gSystem->Load("libOADB");
+   gSystem->Load("libANALYSISalice");
+   gSystem->Load("libCORRFW");
+
+// include path
+   TString intPath = gInterpreter->GetIncludePath();
+   TObjArray *listpaths = intPath.Tokenize(" ");
+   TIter nextpath(listpaths);
+   TObjString *pname;
+   while ((pname=(TObjString*)nextpath())) {
+      TString current = pname->GetName();
+      if (current.Contains("AliRoot") || current.Contains("ALICE_ROOT")) continue;
+      gSystem->AddIncludePath(current);
+   }
+   if (listpaths) delete listpaths;
+   gSystem->AddIncludePath("-I$ROOTSYS/include -I$ALICE_ROOT/include ");
+   gROOT->ProcessLine(".include $ALICE_ROOT/include");
+   printf("Include path: %s\n", gSystem->GetIncludePath());
+
+// Add aditional AliRoot libraries
+
+// analysis source to be compiled at runtime (if any)
+   gROOT->ProcessLine(".L DebugClasses.C+g");
+   gROOT->ProcessLine(".L AliAnalysisTaskHighPtDeDx.cxx+g");
+   gROOT->ProcessLine(".L AliAnalysisTaskHighPtDeDxV0.cxx+g");
+
+// fast xrootd reading enabled
+   printf("!!! You requested FastRead option. Using xrootd flags to reduce timeouts. Note that this may skip some files that could be accessed !!!");
+   gEnv->SetValue("XNet.ConnectTimeout",50);
+   gEnv->SetValue("XNet.RequestTimeout",50);
+   gEnv->SetValue("XNet.MaxRedirectCount",2);
+   gEnv->SetValue("XNet.ReconnectTimeout",50);
+   gEnv->SetValue("XNet.FirstConnectMaxCnt",1);
+
+// connect to AliEn and make the chain
+   if (!TGrid::Connect("alien://")) return;
+// read the analysis manager from file
+   AliAnalysisManager *mgr = AliAnalysisAlien::LoadAnalysisManager("HighPtDeDx_lhc10b_Data_ESDs.root");
+   if (!mgr) return;
+   mgr->PrintStatus();
+   AliLog::SetGlobalLogLevel(AliLog::kError);
+   TChain *chain = CreateChain("wn.xml", anatype);
+
+   mgr->StartAnalysis("localfile", chain);
+   timer.Stop();
+   timer.Print();
+}
+
+//________________________________________________________________________________
+TChain* CreateChain(const char *xmlfile, const char *type="ESD")
+{
+// Create a chain using url's from xml file
+   TString filename;
+   Int_t run = 0;
+   TString treename = type;
+   treename.ToLower();
+   treename += "Tree";
+   printf("***************************************\n");
+   printf("    Getting chain of trees %s\n", treename.Data());
+   printf("***************************************\n");
+   TAlienCollection *coll = TAlienCollection::Open(xmlfile);
+   if (!coll) {
+      ::Error("CreateChain", "Cannot create an AliEn collection from %s", xmlfile);
+      return NULL;
+   }
+   AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+   TChain *chain = new TChain(treename);
+   coll->Reset();
+   while (coll->Next()) {
+      filename = coll->GetTURL();
+      if (mgr) {
+         Int_t nrun = AliAnalysisManager::GetRunFromAlienPath(filename);
+         if (nrun && nrun != run) {
+            printf("### Run number detected from chain: %d\n", nrun);
+            mgr->SetRunFromPath(nrun);
+            run = nrun;
+         }
+      }
+      chain->Add(filename);
+   }
+   if (!chain->GetNtrees()) {
+      ::Error("CreateChain", "No tree found from collection %s", xmlfile);
+      return NULL;
+   }
+   return chain;
+}
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/runAAF.C b/PWGLF/SPECTRA/IdentifiedHighPt/grid/runAAF.C
new file mode 100644 (file)
index 0000000..a778753
--- /dev/null
@@ -0,0 +1,655 @@
+/*
+How to debug:
+Check that AliRoot and ROOT versions are OK!
+
+to run:
+ export X509_CERT_DIR=$ALIEN_ROOT/globus/share/certificates
+ aliroot
+ .L runAAF.C
+
+ runAAF(10, "proof", "/alice/data/LHC10h_000137366_p2", 2)
+
+ runAAF(1, "local aod MC", "test_aod_mc.txt", 3)
+
+ runAAF(1, "grid aod off", "lhc10d", 3)
+
+
+ runAAF(5, "grid off MC1", "lhc10d", 3)
+
+ runAAF(1, "local esd PbPb", "test_esd.txt", 2) //ESDs local
+
+
+ runAAF(20, "grid esd term PbPb", "lhc10h", 2)
+
+To clean:
+ rm -f HighPtDeDx*
+ rm -f *.xml
+ rm -f *.root
+
+*/
+
+//UInt_t kTriggerInt=AliVEvent::kMB;
+//UInt_t *kTriggerInt=new UInt_t[2];
+//kTriggerInt[0]=AliVEvent::kMB;
+//kTriggerInt[1]=AliVEvent::kINT7;
+
+UInt_t kTriggerInt[2] = { AliVEvent::kMB, AliVEvent::kINT7 };
+Float_t minCent[6] = { 0.0, 5.0, 10.0, 20.0, 40.0, 60.0 };
+Float_t maxCent[6] = { 5.0, 10.0, 20.0, 40.0, 60.0, 80.0 };
+void runAAF(Int_t nFilesMax, char* type = "local", char* textFileName = "esd.txt", Int_t task = 2);
+TChain* CreateChainCAF(Int_t nFilesMax, TFileCollection* coll, char* treeName);
+//TChain* CreateChainCAF(Int_t nFilesMax, const char* label, const char* treeName, Bool_t AnalysisMC);
+TChain* CreateChainLocal(Int_t nFilesMax, char* filename, char* treeName);
+const Char_t* GetTreeName(Bool_t esdAna);
+
+//________________________________________________________________
+const Char_t* GetTreeName(Bool_t esdAna)
+{
+  if(esdAna)
+    return "esdTree";
+  else
+    return "aodTree";    
+}
+
+//________________________________________________________________
+void runAAF(Int_t nFilesMax, char* type, char* textFileName, Int_t task)
+{
+  Int_t analysisMC  = 0;
+  Bool_t debug      = kTRUE;
+  Bool_t readTR     = kFALSE;
+  Bool_t esdAna     = kTRUE;  // run ESD analysis (kTRUE) or AOD analysis (kFALSE)
+  Int_t runtype = -1;
+
+
+
+
+  if(strstr(type,"aod") != NULL) esdAna = kFALSE;; // AOD analysis
+
+  const Char_t* treeName = GetTreeName(esdAna);
+
+  if(strstr(type,"PbPb") != NULL) runtype = 2; // PbPb
+  if(strstr(type,"pp") != NULL) runtype = 3; // pp
+  if(strstr(type,"900") != NULL){ // 900GeV pp
+    if(runtype != -1){
+      printf("conflicting run types\n");
+      return;
+    }
+    runtype = 1;
+  }
+  if(runtype == -1) runtype = 0; // 7TeV pp
+
+  char *test;
+  test = strstr(type,"MC");
+  if(test != NULL){
+    analysisMC = kTRUE;
+    cout << "Test: " << test << endl;
+    if(sscanf(test,"MC%d",&analysisMC)){
+      //  cout << "**************" << analysisMC << endl;
+      if(!analysisMC) analysisMC = 1;
+    }
+  }
+  cout << "MonteCarlo " << analysisMC << endl;
+
+  const char* alirootver = "v5-02-17-AN";
+  Int_t mode = -1; // mode 1: PROOF, 2: GRID, 0: LOCAL
+  printf("===================================================================\n");
+  if(strstr(type,"proof") != NULL){ 
+    if(mode != -1){
+      printf("===== CONFLICTING TYPES =====\n");
+      return;
+    }
+    mode = 1; 
+    printf("===============   RUNNING ANALYSIS IN CAF MODE   ================\n");
+  }
+  if(strstr(type,"grid") != NULL){
+    if(mode != -1){
+      printf("===== CONFLICTING TYPES =====\n");
+      return;
+    }
+    printf("===============  RUNNING ANALYSIS IN GRID MODE   ================\n");
+    mode = 2; 
+  }
+  if(strstr(type,"local") != NULL || mode<0){ 
+    if(mode != -1){
+      printf("===== CONFLICTING TYPES =====\n");
+      return;
+    }
+    printf("===============  RUNNING ANALYSIS IN LOCAL MODE  ================\n");
+    mode = 0;
+  }
+
+  printf("===================================================================\n");
+  printf("===================================================================\n");
+  if (analysisMC) printf(":: use MC    TRUE\n");
+  else            printf(":: use MC    FALSE\n");
+  if (readTR)     printf(":: read TR   TRUE\n");
+  else            printf(":: read TR   FALSE\n");
+  if (debug)      printf(":: debugging TRUE\n");
+  else            printf(":: debugging FALSE\n");
+
+  Char_t taskname[128];
+  Char_t taskname1[128];
+  Char_t taskname2[128];
+
+  switch(task){
+  case 1:
+    sprintf(taskname,"ChFluct");
+    break;
+  case 2:
+    sprintf(taskname,"HighPtDeDx");
+    break;
+  case 3:
+    sprintf(taskname,"HighPtDeDxV0");
+    break;
+  case 4:{
+    sprintf(taskname1,"HighPtDeDx");
+    sprintf(taskname2,"HighPtDeDxV0");
+  }
+    break;
+  default:
+    printf("Unknown task\n");
+    return;
+  }
+
+
+
+  Char_t nameouputfiles[1280]={0};
+  if(runtype ==2){
+    for(Int_t i=0;i<6;++i){
+      //Char_t tmpname[128]={0};
+      sprintf(nameouputfiles,"%s %s_Tree_%1.0f_%1.0f.root",nameouputfiles,taskname,minCent[i],maxCent[i]);
+      
+    }
+  }
+  if(runtype ==3){
+      sprintf(nameouputfiles,"%s %s_Tree.root",taskname);
+  }
+  if(task==4){
+    
+    if(runtype ==3){
+      sprintf(nameouputfiles,"%s_Tree.root %s_Tree.root",taskname1,taskname2);
+    }
+    
+  }
+
+
+
+  cout<<"Files to be stored:"<<nameouputfiles<<endl;
+
+
+  // Load common libraries   
+  gSystem->Load("libTree.so");
+  gSystem->Load("libPhysics.so");
+  gSystem->Load("libGeom.so");
+  gSystem->Load("libVMC.so");
+  gSystem->Load("libSTEERBase.so");
+  gSystem->Load("libESD.so");
+  gSystem->Load("libAOD.so");
+  gSystem->Load("libCDB.so");
+  gSystem->Load("libANALYSIS.so");
+  gSystem->Load("libANALYSISalice.so");
+  // tender
+  Bool_t v0tender = kTRUE;
+  if(v0tender) {
+    gSystem->Load("libTENDER.so");
+    gSystem->Load("libTENDERSupplies.so");
+  }
+
+  gROOT->ProcessLine(Form(".include %s/include", gSystem->ExpandPathName("$ALICE_ROOT")));
+
+
+  cout << "mode " << mode << ", type " << type << endl;
+
+  if (mode == 1){
+    cout << "Connecting to CAF..." << endl;
+    gEnv->SetValue("XSec.GSI.DelegProxy","2");
+
+    //const char* AAF = "pchristi@skaf.saske.sk";    
+    const char* AAF = "aortizve@alice-caf.cern.ch";    
+
+    if(strstr(type,"reset") != NULL)
+       TProof::Reset(AAF,kFALSE);
+    //       TProof::Reset("pchristi@alice-caf.cern.ch",kTRUE);
+    //    TProof::Open(AAF);
+    TProof::Open(AAF, "workers=10");
+
+    TList *list = new TList();
+    list->Add(new TNamed("ALIROOT_EXTRA_LIBS", "CDB"));
+
+    gProof->EnablePackage(Form("VO_ALICE@AliRoot::%s",alirootver), list);
+
+    cout << "Connected to " << AAF << endl;
+  }
+
+  // Load the analysis macro (old version); should be removed when the library will be decided
+  Char_t loadtask1[128];
+  Char_t loadtask2[128];
+  Char_t loadtask[128];
+
+  if(task==4){
+    sprintf(loadtask1,"AliAnalysisTask%s.cxx+", taskname1);
+    sprintf(loadtask2,"AliAnalysisTask%s.cxx+", taskname2);
+  }else{
+    sprintf(loadtask,"AliAnalysisTask%s.cxx+", taskname);
+  }
+
+  if(mode == 1){ // PROOF
+
+    // switch(task){
+    // case 1: // ch fluct
+    //   break;
+    // case 2: // high pt dedx
+    //gProof->Load("DebugClasses.C++g");
+    //   break;
+    // case 3: // high pt v0s
+    //   gProof->Load("DebugClasses.C++g");
+    //   break;
+    // default:
+    //   printf("Unknown task\n");
+    //   return;
+    // }
+
+    gProof->Load(loadtask);
+  }else{
+
+    switch(task){
+    case 1: // ch fluct
+      break;
+    case 2: // high pt dedx
+      gROOT->LoadMacro("DebugClasses.C++g");
+      break;
+    case 3: // high pt v0s
+      gROOT->LoadMacro("DebugClasses.C++g");
+      break;
+    case 4: // high pt v0s
+      gROOT->LoadMacro("DebugClasses.C++g");
+      break;
+    default:
+      printf("Unknown task\n");
+      return;
+    }
+
+    if(task==4){
+      gROOT->LoadMacro(loadtask1);
+      gROOT->LoadMacro(loadtask2);
+    }else{
+      gROOT->LoadMacro(loadtask);
+    }
+  }
+
+  // Make the analysis manager
+  AliAnalysisManager* mgr = new AliAnalysisManager("PID histos", "testing analysis");
+
+
+  // Dataset 
+  switch(mode){
+  case 1: // PROOF
+    TFileCollection* proofColl = gProof->GetDataSet(textFileName);
+    TFileCollection* stagedColl = proofColl->GetStagedSubset();
+    TChain* chain = CreateChainCAF(nFilesMax, stagedColl, treeName);
+//    TChain* chain = CreateChainCAF(nFilesMax, textFileName, treeName, analysisMC);
+    break;
+  case 2: // GRID
+    //gSystem->Setenv("alien_CLOSE_SE", "ALICE::GSI::SE2");
+    //    gSystem->Setenv("alien_CLOSE_SE", "ALICE::NIHAM::FILE");
+    TGrid::Connect("alien://");
+    //gSystem->Setenv("alien_CLOSE_SE", "ALICE::GSI::SE2");
+    //    gSystem->Setenv("alien_CLOSE_SE", "ALICE::NIHAM::FILE");
+    
+    Char_t gridmode[64];
+    sprintf(gridmode, "full");
+    if(strstr(type,"term") != NULL) 
+      sprintf(gridmode, "terminate");
+    if(strstr(type,"off") != NULL) 
+      sprintf(gridmode, "offline");
+    if(strstr(type,"sub") != NULL) 
+      sprintf(gridmode, "submit");
+    if(strstr(type,"test") != NULL) 
+      sprintf(gridmode, "test");
+
+
+    gROOT->LoadMacro("CreateAlienHandler.C");
+    //    AliAnalysisGrid *alienHandler = CreateAlienHandler(nFilesMax, analysisMC, runtype, taskname, gridmode);  
+    AliAnalysisGrid *alienHandler = CreateAlienHandler(nFilesMax, analysisMC, esdAna, taskname1, nameouputfiles, gridmode, textFileName, alirootver, task);  
+    if (!alienHandler) return; 
+
+    // DOES NOT WORK BECAUSE THERE ARE NO GETTERS?
+    // // Here we can add extra files to the plugin
+    // switch(task){
+    // case 1: // ch fluct
+    //   break;
+    // case 2: // high pt dedx
+    //   alienHandler->SetAnalysisSource(Form("DebugClasses.C %s", alienHandler->GetAnalysisSource()));
+    //   alienHandler->SetAdditionalLibs(Form("DebugClasses.C %s", alienHandler->GetAdditionalLibs()));
+    //   break;
+    // case 3: // high pt v0s
+    //   alienHandler->SetAnalysisSource(Form("DebugClasses.C %s", alienHandler->GetAnalysisSource()));
+    //   alienHandler->SetAdditionalLibs(Form("DebugClasses.C %s", alienHandler->GetAdditionalLibs()));
+    //   break;
+    // default:
+    //   printf("Unknown task\n");
+    //   return;
+    // }
+
+    // Connect plugin to the analysis manager
+    mgr->SetGridHandler(alienHandler); 
+    break;
+  case 0: // LOCAL
+    // Process data - chain
+    AliXRDPROOFtoolkit tool;
+    TChain* chain = tool.MakeChain(textFileName,treeName, 0, 100);
+    chain->Lookup();
+    break;
+  default:
+    printf("Unknown mode");
+    return;
+  }
+  
+  // ESD input handler
+  if(esdAna) {
+
+    AliESDInputHandler *esdHandler = new AliESDInputHandler();
+    mgr->SetInputEventHandler(esdHandler);
+  } else {
+
+    AliAODInputHandler* aodHandler = new AliAODInputHandler();
+    mgr->SetInputEventHandler(aodHandler);
+  }
+
+  // Monte Carlo handler
+  if (analysisMC) {
+    AliMCEventHandler* mcHandler = new AliMCEventHandler();
+    if(esdAna)
+      mgr->SetMCtruthEventHandler(mcHandler);
+    mcHandler->SetReadTR(readTR); 
+  }
+
+  // Debug if needed
+  if (debug) 
+    mgr->SetDebugLevel(3);
+
+  if(v0tender) {
+    // V0 tender for LHC10c pass 3
+    //========= Add tender to the ANALYSIS manager and set default storage =====
+    AliTender *tender=new AliTender("AnalysisTender");
+    tender->SetCheckEventSelection(kTRUE);
+    tender->SetDefaultCDBStorage("raw://");
+    mgr->AddTask(tender);
+    if (mgr->GetTasks()->First() != (TObject*)tender) {
+      ::Error("When setting the tender to check the event selection, it has to be the first wagon ! Aborting.");
+      return;
+    }   
+    
+    //========= Attach VZERO supply ======
+    AliVZEROTenderSupply *vzeroSupply=new AliVZEROTenderSupply("VZEROtender");
+    vzeroSupply->SetDebug(kFALSE);
+    tender->AddSupply(vzeroSupply);
+    
+    //================================================
+    //              data containers
+    //================================================
+    
+    //            define output containers, please use 'username'_'somename'
+    AliAnalysisDataContainer *coutputtender =
+      mgr->CreateContainer("tender_event", AliESDEvent::Class(),
+                          AliAnalysisManager::kExchangeContainer,"default_tender");
+    
+    //           connect containers
+    mgr->ConnectInput  (tender,  0, mgr->GetCommonInputContainer() );
+    mgr->ConnectOutput (tender,  1, coutputtender);
+  }
+
+  // ######### Centrality task ###############  
+
+  cout<<"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%"<<endl;
+  cout<<"esdAna="<<esdAna<<"  runtype="<<runtype<<endl;
+    
+  // ######### PHYSICS SELECTION ###############
+  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+  AliPhysicsSelectionTask* physSelTask = AddTaskPhysicsSelection();
+  if (analysisMC) {
+    AliPhysicsSelection* physSel = physSelTask->GetPhysicsSelection();
+    physSel->SetAnalyzeMC();
+  }
+
+  if(esdAna && runtype==2) { // only for ESD and PbPb
+
+    gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
+    AliCentralitySelectionTask *taskCentrality = AddTaskCentrality(); 
+    //taskCentrality->SetPass(2);
+    if (analysisMC)
+      taskCentrality->SetMCInput(); 
+  }
+
+  // ######### PID task ###############
+
+  if(task!=4){
+    gROOT->LoadMacro(Form("AddTask%s.C", taskname));  
+    AliAnalysisTask* taskPid = AddTask(analysisMC, taskname, runtype, kTriggerInt, minCent, maxCent);
+  }else{
+    cout<<"%%%%%%%%%%%%  flag"<<endl;
+    gROOT->LoadMacro(Form("AddTask%s.C", taskname1));  
+    AliAnalysisTask* taskPid = AddTask(analysisMC, taskname1, runtype, kTriggerInt, minCent, maxCent);
+    gROOT->LoadMacro(Form("AddTask%s.C", taskname2));  
+    AliAnalysisTask* taskPid = AddTask(analysisMC, taskname2, runtype, kTriggerInt, minCent, maxCent);
+  }
+
+
+
+
+  // Run the analysis  
+  if (mgr->InitAnalysis()){
+    mgr->PrintStatus();
+    switch(mode){
+    case 1: // PROOF
+      mgr->StartAnalysis("proof",chain);
+      break;
+    case 2: // GRID
+      mgr->StartAnalysis("grid");
+      break;
+    case 0:
+      mgr->StartAnalysis("local",chain);
+      break;
+    default:
+      printf("Unknown mode\n");
+      return;
+    }
+  } 
+}  
+
+
+//__________________________________________________________
+TChain* CreateChainCAF(Int_t nFilesMax, TFileCollection* coll, char* treeName)
+{
+  TIter iter(coll->GetList());
+  
+  TChain* target = new TChain(treeName);
+  
+  Int_t nFiles = 0;
+  
+  TFileInfo* fileInfo = 0;
+  while ((fileInfo = dynamic_cast<TFileInfo*> (iter())) && (nFiles<nFilesMax || nFilesMax == 0)){
+    if (fileInfo->GetFirstUrl()) {
+      target->Add(fileInfo->GetFirstUrl()->GetUrl());
+      nFiles++;
+    }
+  }
+  
+  Printf("Added %d files to chain", target->GetListOfFiles()->GetEntries());
+  
+  return target;
+}
+
+
+// //__________________________________________________________
+// TChain* CreateChainCAF(Int_t nFilesMax, const char* label, const char* treeName, Bool_t AnalysisMC)
+// {
+
+//   cout << "CreateChainCAF2" << endl; 
+
+//   TChain* target = new TChain(treeName);
+
+//   Int_t nFiles = 0;
+//   Char_t fileName[256];
+//   sprintf(fileName,"%s.conf", label);
+
+//   FILE* file = fopen(fileName,"r");
+//   if(!file) {
+//     cout << "File " << fileName << " not found!" << endl;
+//     return;
+//   }
+
+//   Char_t dummy[128];
+//   Char_t runperiodpattern[128];
+//   if(AnalysisMC)
+//     sprintf(runperiodpattern,"Run period MC%d: %s", AnalysisMC,"%s %s");
+//   else
+//     sprintf(runperiodpattern,"Run period: %s","%s %s");
+
+//   cout << "Pattern: " << runperiodpattern << endl;
+
+//   char runperiod[128], pass[64];
+//   while (fgets(dummy,128,file) != NULL) {  
+//     Printf("line: %s", dummy);   
+//     Int_t run, a, b;
+//     if(sscanf(dummy, runperiodpattern, &runperiod, &pass)){
+//       Char_t tmp[128];
+//       sscanf(pass,"pass%s",tmp);
+//       sprintf(pass,"p%s",tmp);
+//       continue;
+//     }
+//     if(sscanf(dummy,"Run: %d", &run)){
+//       Char_t textFileName[256];
+//       if(AnalysisMC)
+//     sprintf(textFileName,"/alice/sim/%s_%d",runperiod, run, pass);
+//       else
+//     sprintf(textFileName,"/alice/data/%s_000%d_%s",runperiod, run, pass);
+
+//       cout << "Collection: " << textFileName << endl;
+//       TFileCollection* proofColl = gProof->GetDataSet(textFileName);
+//       TFileCollection* stagedColl = proofColl->GetStagedSubset();
+//       TIter iter(proofColl->GetList());
+      
+//       TFileInfo* fileInfo = 0;
+//       while ((fileInfo = dynamic_cast<TFileInfo*> (iter())) && (nFiles<nFilesMax || nFilesMax <= 0)){
+//     if (fileInfo->GetFirstUrl()) {
+//       Printf("Adding %s", fileInfo->GetFirstUrl()->GetUrl());
+//       target->Add(fileInfo->GetFirstUrl()->GetUrl());
+//       nFiles++;
+//     }
+//       }
+      
+//       continue;
+//     }
+//   }
+
+
+
+
+//   Printf("Added %d files to chain", target->GetListOfFiles()->GetEntries());
+
+//   return target;
+// }
+
+//__________________________________________________________
+TChain* CreateChainLocal(Int_t nFilesMax, char* filename, char* treeName)
+{
+  // If file name ends in .root the chain will be created directly from that
+  // fileName, otherwise it will assume that it is a text file and create it
+  // from that.
+  //
+  // nFilesMax is only used for the text files
+  // nFilesMax=0 means add all files
+
+  TChain* chain = new TChain(treeName); 
+  
+  // Open the input stream
+  ifstream in;
+  in.open(filename);
+
+  Int_t nFiles = 0;
+
+  // Read the input list of files and add them to the chain
+  TString file;
+  while(in.good() && (nFiles<nFilesMax || nFilesMax<=0)) {
+    in >> file;
+    if (!file.Contains("root")) 
+      continue; // protection
+
+    nFiles++;
+    chain->Add(file.Data());
+  }
+
+  in.close();
+
+  return chain;
+}
+
+
+
+
+/*
+
+  gEnv->SetValue("XSec.GSI.DelegProxy","2");
+  const char* AAF = "pchristi@alice-caf.cern.ch";    
+  TProof::Open(AAF, "workers=10");
+  TList *list = new TList();
+  list->Add(new TNamed("ALIROOT_EXTRA_LIBS", "CDB"));
+  gProof->EnablePackage(Form("VO_ALICE@AliRoot::%s",alirootver), list);
+  const char* alirootver = "v4-21-20-AN";
+  gProof->EnablePackage(Form("VO_ALICE@AliRoot::%s",alirootver), list);
+  gProof->Load("AliAnalysisTaskHighPtDeDx.cxx++g")
+  AliAnalysisManager* mgr = new AliAnalysisManager("PID histos", "testing analysis");
+  TFileCollection* proofColl = gProof->GetDataSet("/alice/data/LHC10h_000137366_p2")
+  TFileCollection* stagedColl = proofColl->GetStagedSubset();
+  .L runAAF.C 
+  TChain* chain = CreateChainCAF(10, stagedColl, "esdTree")
+  gSystem->Load("libTree.so");
+  gSystem->Load("libPhysics.so");
+  gSystem->Load("libGeom.so");
+  gSystem->Load("libVMC.so");
+  gSystem->Load("libSTEERBase.so");
+  gSystem->Load("libESD.so");
+  gSystem->Load("libAOD.so");
+  gSystem->Load("libCDB.so");
+  gSystem->Load("libANALYSIS.so");
+  gSystem->Load("libANALYSISalice.so");
+  gROOT->ProcessLine(Form(".include %s/include", gSystem->ExpandPathName("$ALICE_ROOT")));
+  AliAnalysisManager* mgr = new AliAnalysisManager("PID histos", "testing analysis");
+  AliESDInputHandler *esdHandler = new AliESDInputHandler();
+  mgr->SetInputEventHandler(esdHandler);
+  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
+  AliCentralitySelectionTask *taskCentrality = AddTaskCentrality(); 
+
+  // ######### PID task ###############
+  gROOT->LoadMacro("AddTaskHighPtDeDx.C");
+  AliAnalysisTask* taskPid = AddTask(kFALSE, "testTask");
+
+
+  // ######### PHYSICS SELECTION ###############
+  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+  AliPhysicsSelectionTask* physSelTask = AddTaskPhysicsSelection();
+  mgr->InitAnalysis()
+  mgr->PrintStatus();
+  mgr->StartAnalysis("proof",chain);
+  
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ */
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/grid/test_esd.txt b/PWGLF/SPECTRA/IdentifiedHighPt/grid/test_esd.txt
new file mode 100644 (file)
index 0000000..f67e0e0
--- /dev/null
@@ -0,0 +1 @@
+~/Analysis/datos_LHC10b_Pass3/10000117099041.80/AliESDs.root
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBase.cxx b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBase.cxx
new file mode 100644 (file)
index 0000000..39ff63e
--- /dev/null
@@ -0,0 +1,487 @@
+#include "AliHighPtDeDxBase.h"
+
+#include <TMath.h>
+#include <TStyle.h>
+#include <TROOT.h>
+
+#ifndef __IOSTREAM__
+#include <iostream>
+#endif
+
+using namespace std;
+
+ClassImp(AliHighPtDeDxBase);
+
+//
+// AliHighPtDeDxBase class
+//
+// This class contains the AliHighPtDeDxBase information 
+//
+
+//_________________________________________________________
+AliHighPtDeDxBase::AliHighPtDeDxBase():
+  TNamed(),
+  fIsMc(kFALSE),
+  fUseRunCut(kFALSE),
+  fRun(0),
+  fUseEtaCut(kFALSE),
+  fUseEtaCutAbs(kFALSE),
+  fEtaLow(-0.8),
+  fEtaHigh(0.8),
+  fUseFilterCut(kFALSE),
+  fFilter(1),
+  fUsePhiCut(kFALSE),
+  fPhiCutLow(0x0),
+  fPhiCutHigh(0x0),
+  fEventVtxStatus(-999),
+  fEventVtxStatusMc(-999),
+  fEventRun(0),
+  fEventMag(0),
+  fEventTrigger(-1),
+  fTrackCharge(0),
+  fTrackEta(0),
+  fTrackP(0),
+  fTrackPt(0),
+  fTrackFilter(-999),
+  fTrackPhi(-999),
+  fTrackPhiCutVariable(-999),
+  fTrackDeDx(-999),
+  fTrackNcl(-999),
+  fTrackPidMc(0),
+  fTrackPrimaryMc(-1),
+  hVtxStatus(0x0),
+  hNevents(0x0),
+  hPhi(0x0),
+  hEta(0x0),
+  hPt(0x0),
+  hMeanPt(0x0),
+  hNclVsPhiVsPtBefore(0x0),
+  hNclVsPhiVsPtAfter(0x0)
+{
+  // default constructor - do not use
+}
+
+//_________________________________________________________
+AliHighPtDeDxBase::AliHighPtDeDxBase(const char* name, const char* title):
+  TNamed(name, title),
+  fIsMc(kFALSE),
+  fUseRunCut(kFALSE),
+  fRun(0),
+  fUseEtaCut(kFALSE),
+  fUseEtaCutAbs(kFALSE),
+  fEtaLow(-0.8),
+  fEtaHigh(0.8),
+  fUseFilterCut(kFALSE),
+  fFilter(1),
+  fUsePhiCut(kFALSE),
+  fPhiCutLow(0x0),
+  fPhiCutHigh(0x0),
+  fEventVtxStatus(-999),
+  fEventVtxStatusMc(-999),
+  fEventRun(0),
+  fEventMag(0),
+  fEventTrigger(-1),
+  fTrackCharge(0),
+  fTrackEta(0),
+  fTrackP(0),
+  fTrackPt(0),
+  fTrackFilter(-999),
+  fTrackPhi(-999),
+  fTrackPhiCutVariable(-999),
+  fTrackDeDx(-999),
+  fTrackNcl(-999),
+  fTrackPidMc(0),
+  fTrackPrimaryMc(-1),
+  hVtxStatus(0x0),
+  hNevents(0x0),
+  hPhi(0x0),
+  hEta(0x0),
+  hPt(0x0),
+  hMeanPt(0x0),
+  hNclVsPhiVsPtBefore(0x0),
+  hNclVsPhiVsPtAfter(0x0)
+{
+  // named constructor
+}
+
+//_________________________________________________________
+AliHighPtDeDxBase::~AliHighPtDeDxBase()
+{
+  delete hVtxStatus;
+  delete hNevents;
+  delete hEta;
+  delete hPhi;
+  delete hPt;
+  delete hMeanPt;
+  delete hNclVsPhiVsPtBefore;
+  delete hNclVsPhiVsPtAfter;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxBase::Init(Int_t nPtBins, Double_t* ptBins)
+{
+  //
+  // Create histograms
+  //
+  hVtxStatus = new TH1D("hVtxStatus", "Vtx status - No Vtx = -1, Vtx outside cut = 0, Vtx inside = 1",
+                       3, -1.5, 1.5);
+  hVtxStatus->Sumw2();
+  hVtxStatus->SetDirectory(0);
+
+  hNevents = new TH1D("hNevents", "N events - No Vtx = 0, Vtx OK = 1",
+                     2, 0, 2);
+  hNevents->Sumw2();
+  hNevents->SetDirectory(0);
+  
+  hEta = new TH1D("hEta", "#eta distribution; #eta; Counts",
+                 100, -1.0, 1.0);
+  hEta->Sumw2();
+  hEta->SetDirectory(0);
+  
+  hPhi = new TH1D("hPhi", "#varphi distribution; #varphi; Counts",
+                 360, 0, TMath::TwoPi());
+  hPhi->Sumw2();
+  hPhi->SetDirectory(0);
+  
+  hPt = new TH1D("hPt", "p_{T} spectrum; p_{T} [GeV/c]; Counts",
+                nPtBins, ptBins);
+  hPt->Sumw2();
+  hPt->SetDirectory(0);
+  
+  hMeanPt = new TProfile("hMeanPt", "mean p_{T}; p_{T} [GeV/c]; mean p_{T}",
+                        nPtBins, ptBins);
+  hMeanPt->SetDirectory(0);
+
+  const Int_t nPhiBins = 50;
+  const Double_t phiBinSize = TMath::Pi()/9.0/nPhiBins;
+  Double_t phiBins[nPhiBins+1];
+
+  for(Int_t i = 0; i <= nPhiBins; i++) {
+
+    phiBins[i] = phiBinSize*i;
+  }
+
+  const Int_t nNclBins = 45;
+  const Double_t nclBinSize = 90.0/nNclBins;
+  Double_t nclBins[nNclBins+1];
+
+  for(Int_t i = 0; i <= nNclBins; i++) {
+
+    nclBins[i] = 69.5 + nclBinSize*i;
+  }
+  
+  hNclVsPhiVsPtBefore = new TH3F("hNclVsPhiVsPtBefore", "<Ncl> vs Pt and #phi (before #phi cut); p_{T} [GeV/c]; fmod(#phi, #pi/9.0)",
+                                nPtBins, ptBins, nPhiBins, phiBins, nNclBins, nclBins); 
+  hNclVsPhiVsPtBefore->SetDirectory(0);
+  hNclVsPhiVsPtAfter = new TH3F("hNclVsPhiVsPtAfter", "<Ncl> vs Pt and #phi (after #phi cut); p_{T} [GeV/c]; fmod(#phi, #pi/9.0)",
+                               nPtBins, ptBins, nPhiBins, phiBins, nNclBins, nclBins); 
+  hNclVsPhiVsPtAfter->SetDirectory(0);
+}
+
+//_________________________________________________________
+Bool_t AliHighPtDeDxBase::EventAccepted()
+{
+  if(fUseRunCut && fRun!=fEventRun)
+    return kFALSE;
+
+  return kTRUE;
+}
+
+//_________________________________________________________
+Bool_t AliHighPtDeDxBase::TrackAccepted()
+{
+  if(fUseFilterCut && !(fTrackFilter&fFilter))
+    return kFALSE;
+
+  if(fUseEtaCut && (fTrackEta<fEtaLow || fTrackEta>fEtaHigh))
+    return kFALSE;
+  
+  if(fUseEtaCutAbs && (TMath::Abs(fTrackEta)<fEtaLow || TMath::Abs(fTrackEta)>fEtaHigh))
+    return kFALSE;
+  
+  if(fUsePhiCut) {
+
+    fTrackPhiCutVariable = fTrackPhi;
+    if(fEventMag<0)    // for negatve polarity field
+      fTrackPhiCutVariable = TMath::TwoPi() - fTrackPhiCutVariable;
+    if(fTrackCharge<0) // for negatve charge
+      fTrackPhiCutVariable = TMath::TwoPi()-fTrackPhiCutVariable;
+    if(fTrackPhiCutVariable < 0)
+      cout << "Warning!!!!! phi < 0: " << fTrackPhiCutVariable << endl;
+    
+    fTrackPhiCutVariable += TMath::Pi()/18.0; // to center gap in the middle
+    fTrackPhiCutVariable = fmod(fTrackPhiCutVariable, TMath::Pi()/9.0);
+
+    hNclVsPhiVsPtBefore->Fill(fTrackPt, fTrackPhiCutVariable, fTrackNcl);
+
+    if(fTrackPt>2.0 && fTrackPhiCutVariable<fPhiCutHigh->Eval(fTrackPt) 
+       && fTrackPhiCutVariable>fPhiCutLow->Eval(fTrackPt))
+      return kFALSE; // reject track
+
+    hNclVsPhiVsPtAfter->Fill(fTrackPt, fTrackPhiCutVariable, fTrackNcl);
+  }
+  
+  return kTRUE;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxBase::FillEventInfo()
+{
+  if(fEventTrigger==1) {
+    hVtxStatus->Fill(fEventVtxStatus);
+    if(fEventVtxStatus != 0) {
+      hNevents->Fill(1.0+0.5*fEventVtxStatus);
+    }
+  }
+}
+
+//_________________________________________________________
+void AliHighPtDeDxBase::FillTrackInfo(Float_t weight)
+{
+  hEta->Fill(fTrackEta, weight);
+  hPhi->Fill(fTrackPhi, weight);
+  hPt->Fill(fTrackPt, weight);
+  hMeanPt->Fill(fTrackPt, fTrackPt);
+}
+
+//_________________________________________________________
+void AliHighPtDeDxBase::Print(Option_t* option) const
+{
+  cout << ClassName() << " : " << GetName() << endl  
+       << "Event cuts: " << endl;
+  if(fUseRunCut)
+    cout << "   Run cut: " << fRun << endl;
+  else
+    cout << "   Run cut is diabled " << endl;
+  
+  cout << "Track cuts: " << endl;
+  if(fUseFilterCut)
+    cout << "   Filter cut: " << fFilter << endl;
+  else
+    cout << "   Filter cut is diabled " << endl;
+  if(fUseEtaCut)
+    cout << "   Eta range: " << fEtaLow << " - " << fEtaHigh << endl;
+  if(fUseEtaCutAbs)
+    cout << "   |Eta| range: " << fEtaLow << " - " << fEtaHigh << endl;
+  else
+    cout << "   Eta cut is diabled " << endl;
+  if(fUsePhiCut)
+    cout << "   Phi cut is ENABLED" << endl;
+  else
+    cout << "   Phi cut is diabled " << endl;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxBase::SetUseEtaCut(Bool_t  value)
+{
+  fUseEtaCut = value;
+
+  if(value == kTRUE)
+    fUseEtaCutAbs = kFALSE;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxBase::SetUseEtaCutAbs(Bool_t  value)
+{
+  fUseEtaCutAbs = value;
+
+  if(value == kTRUE)
+    fUseEtaCut = kFALSE;
+}
+
+//_________________________________________________________
+TF1* AliHighPtDeDxBase::GetStandardPhiCutLow()
+{
+  //  TF1* cutLow  = new TF1("StandardPhiCutLow",  "-0.01/x+pi/18.0-0.015", 0, 50);
+  TF1* cutLow  = new TF1("StandardPhiCutLow",  "0.1/x/x+pi/18.0-0.025", 0, 50);
+  return cutLow;
+}
+
+//_________________________________________________________
+TF1* AliHighPtDeDxBase::GetStandardPhiCutHigh()
+{
+  //  TF1* cutHigh = new TF1("StandardPhiCutHigh", "0.55/x/x+pi/18.0+0.03", 0, 50);
+  TF1* cutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 50);
+  return cutHigh;
+}
+
+
+//___________________________________________________________________________
+TCanvas* AliHighPtDeDxBase::DrawPhiCutHistograms()
+{
+  gStyle->SetOptStat(0);
+
+  TCanvas* cPhiCut = FindCanvas("cPhiCut", 1200, 800);
+  cPhiCut->SetTitle("phi cut histograms");
+  cPhiCut->Clear();
+  cPhiCut->Divide(3,2);
+
+  // cPhiCut->cd(1);
+  // TH2D* hPhiVsPtBefore = (TH2D*)hNclVsPhiVsPtBefore->Project3D("yx");
+  // hPhiVsPtBefore->SetName("hPhiVsPtBefore");
+  // hPhiVsPtBefore->SetTitle("Phi vs p_{T} (before cuts)");
+  // MakeNice2dHisto(hPhiVsPtBefore, gPad, kTRUE);
+  // hPhiVsPtBefore->Draw("COL");
+  // fPhiCutHigh->SetRange(2.0, 50.0);
+  // fPhiCutHigh->Draw("SAME");
+  // fPhiCutLow->SetRange(2.0, 50.0);
+  // fPhiCutLow->Draw("SAME");
+  
+  cPhiCut->cd(1);
+  TProfile2D* hNclBefore = hNclVsPhiVsPtBefore->Project3DProfile("yx");
+  hNclBefore->SetName("hNclBefore");
+  hNclBefore->SetTitle("<Ncl> (before cuts); p_{T} [GeV/c]; #varphi'");
+  MakeNice2dHisto(hNclBefore, gPad, kTRUE);
+  DrawNice(hNclBefore, 0, 0, 0, "COLZ");
+  fPhiCutHigh->Draw("SAME");
+  fPhiCutLow->Draw("SAME");
+  
+  cPhiCut->cd(2);
+  gPad->SetGridy();
+  TH2D* hNclVsPtBefore = (TH2D*)hNclVsPhiVsPtBefore->Project3D("zx");
+  hNclVsPtBefore->SetName("hNclVsPtBefore");
+  hNclVsPtBefore->SetTitle("; p_{T} [GeV/c]; Ncl;");
+  MakeNice2dHisto(hNclVsPtBefore, gPad, kTRUE);
+  hNclVsPtBefore->Draw("COL");
+  TProfile* hNclVsPtBeforeProf = hNclVsPtBefore->ProfileX();
+  hNclVsPtBeforeProf->SetMarkerStyle(29);
+  hNclVsPtBeforeProf->SetMarkerColor(2);
+  hNclVsPtBeforeProf->Draw("SAME");
+
+  // cPhiCut->cd(2);
+  // TH2D* hPhiVsPtAfter = (TH2D*)hNclVsPhiVsPtAfter->Project3D("yx");
+  // MakeNice2dHisto(hNclVsPtAfter, gPad, kTRUE);
+  // hPhiVsPtAfter->SetName("hPhiVsPtAfter");
+  // hPhiVsPtAfter->SetTitle("Phi vs p_{T} (after cuts)");
+  // DrawNice(hPhiVsPtAfter, 0, 0, 0, "COL");
+                         
+  cPhiCut->cd(4);
+  TProfile2D* hNclAfter = (TProfile2D*)hNclVsPhiVsPtAfter->Project3DProfile("yx");
+  hNclAfter->SetName("hNclAfter");
+  hNclAfter->SetTitle("<Ncl> (after cuts); p_{T} [GeV/c]; #varphi'");
+  MakeNice2dHisto(hNclAfter, gPad, kTRUE);
+  DrawNice(hNclAfter, 0, 0, 0, "COLZ");
+  
+  cPhiCut->cd(5);
+  gPad->SetGridy();
+  TH2D* hNclVsPtAfter = (TH2D*)hNclVsPhiVsPtAfter->Project3D("zx");
+  hNclVsPtAfter->SetName("hNclVsPtAfter");
+  hNclVsPtAfter->SetTitle("; p_{T} [GeV/c]; Ncl;");
+  MakeNice2dHisto(hNclVsPtAfter, gPad, kTRUE);
+  hNclVsPtAfter->Draw("COL");
+  TProfile* hNclVsPtAfterProf = hNclVsPtAfter->ProfileX();
+  hNclVsPtAfterProf->SetMarkerStyle(29);
+  hNclVsPtAfterProf->SetMarkerColor(2);
+  hNclVsPtAfterProf->Draw("SAME");
+
+  cPhiCut->cd(3);
+  gPad->SetGridy();
+  TH1D* hEfficiency = (TH1D*)hNclVsPhiVsPtAfter->Project3D("x");
+  hEfficiency->SetName("hEfficiency");
+  hEfficiency->SetTitle("; p_{T} [GeV/c]; Cut efficiency;");  
+  TH1D* hHelp = (TH1D*)hNclVsPhiVsPtBefore->Project3D("x");
+  hEfficiency->Divide(hEfficiency, hHelp, 1, 1, "B");
+  delete hHelp;
+  MakeNice1dHisto(hEfficiency, gPad);
+  hEfficiency->SetMarkerStyle(20);
+  hEfficiency->Draw("P");
+
+  return cPhiCut;
+}
+
+/*
+  These methods does not fit in very well here, but for now I put them
+  here. Maybe they should go in some tool class.
+ */
+
+//_______________________________________________________________________
+void AliHighPtDeDxBase::MakeNice1dHisto(TH1* hist, TVirtualPad* c1)
+{
+  if(c1) {
+    
+    c1->SetLeftMargin(0.12);
+    c1->SetRightMargin(0.02);
+    c1->SetBottomMargin(0.12);
+    c1->SetTopMargin(0.06);
+  }
+
+  gStyle->SetTitleH(0.08);
+  gStyle->SetTitleW(0.46);
+  gStyle->SetTitleX(0.29);
+  gStyle->SetTitleY(0.99);
+  hist->GetXaxis()->SetTitleSize(0.07);
+  hist->GetYaxis()->SetTitleSize(0.07);
+  hist->GetXaxis()->SetTitleOffset(0.7);
+  hist->GetYaxis()->SetTitleOffset(0.8);
+}
+
+//_______________________________________________________________________
+void AliHighPtDeDxBase::MakeNice2dHisto(TH2* hist, TVirtualPad* c1, Bool_t colz)
+{
+  gStyle->SetTitleH(0.08);
+  gStyle->SetTitleW(0.76);
+  gStyle->SetTitleX(0.14);
+  gStyle->SetTitleY(0.98);
+  if(colz)
+    gStyle->SetTitleW(0.68);
+
+  hist->GetXaxis()->SetTitleSize(0.07);
+  hist->GetYaxis()->SetTitleSize(0.07);
+  hist->GetXaxis()->SetTitleOffset(0.7);
+  hist->GetYaxis()->SetTitleOffset(0.8);
+  if(c1) {
+    
+    c1->SetLeftMargin(0.12);
+    if(!colz)
+      c1->SetRightMargin(0.02);
+    else
+      c1->SetRightMargin(0.12);      
+    c1->SetBottomMargin(0.12);
+    c1->SetTopMargin(0.06);
+  }
+}
+//______________________________________________________________________
+TCanvas* AliHighPtDeDxBase::FindCanvas(const Char_t* canvasName, 
+                                      Int_t xwidth, Int_t ywidth)
+{
+  
+  TCanvas *c1 = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(canvasName);
+  if(!c1)
+    c1 = new TCanvas(canvasName, canvasName, xwidth, ywidth);
+  else
+    c1->SetWindowSize(xwidth, ywidth);
+  
+  return c1;
+}
+
+//_______________________________________________________________________
+TCanvas* AliHighPtDeDxBase::DrawNice(TH1* hist, const Char_t* canvasName,
+                                    Int_t xwidth, Int_t ywidth, const Char_t* option)
+{
+  TCanvas* canv = 0;
+
+  if(canvasName) {
+    canv = FindCanvas(canvasName, xwidth, ywidth);
+    canv->Clear();
+  }
+
+  Bool_t is2dHist = hist->InheritsFrom("TH2");
+  
+  if(is2dHist) {
+    
+    TString opt(option);
+    opt.ToUpper();
+    
+    if (opt.Contains("COL"))
+      MakeNice2dHisto((TH2*)hist, canv, kTRUE);
+    else
+      MakeNice2dHisto((TH2*)hist, canv);
+    
+  } else
+    MakeNice1dHisto(hist, canv);
+  
+  hist->Draw(option);
+
+  return canv;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBase.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBase.h
new file mode 100644 (file)
index 0000000..f612025
--- /dev/null
@@ -0,0 +1,133 @@
+#ifndef ALIHIGHPTDEDXBASE_H
+#define ALIHIGHPTDEDXBASE_H
+
+#include <TNamed.h>
+#include <TH1.h>
+#include <TH2.h>
+#include <TH3.h>
+#include <TProfile.h>
+#include <TProfile2D.h>
+#include <TF1.h>
+#include <TCanvas.h>
+
+class AliHighPtDeDxBase : public TNamed {
+ public:
+  AliHighPtDeDxBase(); // default constructor  
+  AliHighPtDeDxBase(const char* name, const char* title); // named constructor    
+  virtual ~AliHighPtDeDxBase(); // default destructor
+  
+  void MakeNice1dHisto(TH1* hist, TVirtualPad* c1);
+  void MakeNice2dHisto(TH2* hist, TVirtualPad* c1, Bool_t colz=kFALSE);
+
+  TCanvas* DrawPhiCutHistograms();
+  TCanvas* FindCanvas(const Char_t* canvasName, 
+                     Int_t xwidth, Int_t ywidth);
+  TCanvas* DrawNice(TH1* hist, const Char_t* canvasName,
+                   Int_t xwidth, Int_t ywidth, const Char_t* option);
+  
+  Double_t GetEtaLow()  { return fEtaLow; }    
+  Double_t GetEtaHigh() { return fEtaHigh; }    
+  Bool_t   IsMc()       { return fIsMc; } 
+
+  virtual void SetIsMc        (Bool_t  value) { fIsMc = value; } 
+
+  virtual void SetUseRunCut   (Bool_t  value) { fUseRunCut = value; } 
+  virtual void SetRun        (Int_t   value) { fRun = value; }       
+  virtual void SetUseEtaCut(Bool_t  value);
+  virtual void SetUseEtaCutAbs(Bool_t  value);
+  virtual void SetEtaLow      (Double_t value) { fEtaLow = value; }    
+  virtual void SetEtaHigh     (Double_t value) { fEtaHigh = value; }   
+  virtual void SetUseFilterCut(Bool_t  value) { fUseFilterCut = value; }
+  virtual void SetFilter      (Int_t   value) { fFilter = value; }    
+  virtual void SetUsePhiCut   (Bool_t  value) { fUsePhiCut = value; } 
+  virtual void SetPhiCutLow   (TF1*    value) { fPhiCutLow = value; } 
+  virtual void SetPhiCutHigh  (TF1*    value) { fPhiCutHigh = value; }
+  
+  virtual void SetEventVtxStatus(Int_t value)   { fEventVtxStatus = value; }
+  virtual void SetEventVtxStatusMc(Int_t value) { fEventVtxStatusMc = value; }
+  virtual void SetEventRun(Int_t value)         { fEventRun = value; }
+  virtual void SetEventMag(Double_t value)      { fEventMag = value; }
+  virtual void SetEventTrigger(Int_t value)     { fEventTrigger = value; }
+  virtual void SetTrackCharge(Int_t value)      { fTrackCharge = value; }
+  virtual void SetTrackEta(Double_t value)      { fTrackEta = value; }
+  virtual void SetTrackP(Double_t value)        { fTrackP = value; }  
+  virtual void SetTrackPt(Double_t value)       { fTrackPt = value; } 
+  virtual void SetTrackFilter(Int_t value)      { fTrackFilter = value; }
+  virtual void SetTrackPhi(Double_t value)      { fTrackPhi = value; }
+  virtual void SetTrackDeDx(Double_t value)     { fTrackDeDx = value; }
+  virtual void SetTrackNcl(Int_t value)         { fTrackNcl = value; }
+  virtual void SetTrackBeta(Double_t value)     { fTrackBeta = value; }
+  
+  virtual void SetTrackPidMc(Int_t value)       { fTrackPidMc = value; }
+  virtual void SetTrackPrimaryMc(Int_t value)   { fTrackPrimaryMc = value; }
+  
+  TF1* GetStandardPhiCutLow();
+  TF1* GetStandardPhiCutHigh();
+
+  TH1D* GetHistNevents()    { return hNevents; };
+  TH1D* GetHistVtxStatus()  { return hVtxStatus; };
+  TH1D* GetHistPt()         { return hPt; };
+  TH1D* GetHistEta()        { return hEta; };
+  TProfile* GetHistMeanPt() { return hMeanPt; };
+  TH3F* GetHistNclVsPhiVsPtBefore() { return hNclVsPhiVsPtBefore; }
+  TH3F* GetHistNclVsPhiVsPtAfter()  { return hNclVsPhiVsPtAfter; }
+  
+  virtual void   FillEventInfo();
+  virtual void   FillTrackInfo(Float_t weight=1);
+  virtual Bool_t EventAccepted();
+  virtual Bool_t TrackAccepted();
+  virtual void Init(Int_t nPtBins, Double_t* ptBins);
+
+  void Print(Option_t* option="") const;
+  
+ protected: // so we can use the variables in derived classes
+  // cut ranges
+  Bool_t   fIsMc;                 // kTRUE is data is Mc (e.g. pid info is available)
+  Bool_t   fUseRunCut;            // kTRUE to only sture data from fRun
+  Int_t    fRun;
+  Bool_t   fUseEtaCut;            // kTRUE to require fEtaLow < eta < fEtaHigh
+  Bool_t   fUseEtaCutAbs;         // kTRUE to require fEtaLow < eta < fEtaHigh
+  Double_t fEtaLow;
+  Double_t fEtaHigh;
+  Bool_t   fUseFilterCut;         // kTRUE to require that fFilter (bit) was set
+  Int_t    fFilter;
+  Bool_t   fUsePhiCut;            // kTRUE to use pT > 2.0 edge cut
+  TF1*     fPhiCutLow;            // Function for phi cut low
+  TF1*     fPhiCutHigh;           // Function for phi cut low
+
+  // Actual values for the event and track
+  Int_t    fEventVtxStatus;      //! event vtx status
+  Int_t    fEventVtxStatusMc;    //! event vtx status based on Mc vtx
+  Int_t    fEventRun;            //! event run
+  Double_t fEventMag;            //! event magnetic field
+  Double_t fEventTrigger;        //! 1 is triggered / 0 if not (Mc only)
+
+  Int_t    fTrackCharge;         //! charge (+1 or -1)
+  Double_t fTrackEta;            //! eta
+  Double_t fTrackP;              //! p
+  Double_t fTrackPt;             //! pt
+  Int_t    fTrackFilter;         //! filter
+  Double_t fTrackPhi;            //! phi
+  Double_t fTrackPhiCutVariable; //! derived phi variable used for cutting
+  Double_t fTrackDeDx;           //! dE/dx for track
+  Int_t    fTrackNcl;            //! N cl used for dE/dx for track
+  Double_t fTrackBeta;           //! Beta
+
+  Int_t    fTrackPidMc;          //! Mc pid information
+  Int_t    fTrackPrimaryMc;      //! Mc information if track is primary
+
+ private:
+  // Debug histograms
+  TH1D*     hVtxStatus;
+  TH1D*     hNevents;
+  TH1D*     hPhi;
+  TH1D*     hEta;
+  TH1D*     hPt;
+  TProfile* hMeanPt;
+  TH3F*     hNclVsPhiVsPtBefore;
+  TH3F*     hNclVsPhiVsPtAfter;
+  ClassDef(AliHighPtDeDxBase, 4)  // AliHighPtDeDxBase information
+    };
+
+#endif
+       
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBaseCint.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxBaseCint.h
new file mode 100644 (file)
index 0000000..94f3632
--- /dev/null
@@ -0,0 +1,72 @@
+/********************************************************************
+* AliHighPtDeDxBaseCint.h
+* CAUTION: DON'T CHANGE THIS FILE. THIS FILE IS AUTOMATICALLY GENERATED
+*          FROM HEADER FILES LISTED IN G__setup_cpp_environmentXXX().
+*          CHANGE THOSE HEADER FILES AND REGENERATE THIS FILE.
+********************************************************************/
+#ifdef __CINT__
+#error AliHighPtDeDxBaseCint.h/C is only for compilation. Abort cint.
+#endif
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#define G__ANSIHEADER
+#define G__DICTIONARY
+#define G__PRIVATE_GVALUE
+#include "G__ci.h"
+#include "FastAllocString.h"
+extern "C" {
+extern void G__cpp_setup_tagtableAliHighPtDeDxBaseCint();
+extern void G__cpp_setup_inheritanceAliHighPtDeDxBaseCint();
+extern void G__cpp_setup_typetableAliHighPtDeDxBaseCint();
+extern void G__cpp_setup_memvarAliHighPtDeDxBaseCint();
+extern void G__cpp_setup_globalAliHighPtDeDxBaseCint();
+extern void G__cpp_setup_memfuncAliHighPtDeDxBaseCint();
+extern void G__cpp_setup_funcAliHighPtDeDxBaseCint();
+extern void G__set_cpp_environmentAliHighPtDeDxBaseCint();
+}
+
+
+#include "TObject.h"
+#include "TMemberInspector.h"
+#include "Include.h"
+#include <algorithm>
+namespace std { }
+using namespace std;
+
+#ifndef G__MEMFUNCBODY
+#endif
+
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TClass;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TBuffer;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TMemberInspector;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TObject;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TNamed;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_vectorlEROOTcLcLTSchemaHelpercOallocatorlEROOTcLcLTSchemaHelpergRsPgR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_reverse_iteratorlEvectorlEROOTcLcLTSchemaHelpercOallocatorlEROOTcLcLTSchemaHelpergRsPgRcLcLiteratorgR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_vectorlETVirtualArraymUcOallocatorlETVirtualArraymUgRsPgR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_reverse_iteratorlEvectorlETVirtualArraymUcOallocatorlETVirtualArraymUgRsPgRcLcLiteratorgR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TVectorTlEfloatgR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TVectorTlEdoublegR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TF1;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TH1D;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TH1;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TMatrixTBaselEfloatgR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TMatrixTBaselEdoublegR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TProfile;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TH2;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TH2D;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TH3F;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TH3D;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_iteratorlEbidirectional_iterator_tagcOTObjectmUcOlongcOconstsPTObjectmUmUcOconstsPTObjectmUaNgR;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TCanvas;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_TVirtualPad;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_AliHighPtDeDxBase;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_AliHighPtDeDxCalib;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_AliHighPtDeDxData;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_AliHighPtDeDxMc;
+extern G__linked_taginfo G__AliHighPtDeDxBaseCintLN_AliHighPtDeDxSpectra;
+
+/* STUB derived class for protected member access */
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxCalib.cxx b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxCalib.cxx
new file mode 100644 (file)
index 0000000..ddb05e9
--- /dev/null
@@ -0,0 +1,871 @@
+#include "AliHighPtDeDxCalib.h"
+
+#ifndef __IOSTREAM__
+#include <iostream>
+#endif
+
+using namespace std;
+
+ClassImp(AliHighPtDeDxCalib);
+
+//
+// AliHighPtDeDxCalib class
+//
+// This class contains the AliHighPtDeDxCalib information 
+//
+
+//_________________________________________________________
+AliHighPtDeDxCalib::AliHighPtDeDxCalib():
+  AliHighPtDeDxBase(),
+  fStep(1),             // Step 1 = Eta calibration, step 2 = dE/dx calibration, step = 3 ncl calib
+  fInit(0),             // Step 1 = Eta calibration, step 2 = dE/dx calibration, step = 3 ncl calib
+  fPMIPMin(0.4),        // Min P for MIP pion
+  fPMIPMax(0.6),        // Max P for MIP pion
+  fDeDxMIPMin(40),      // Min dE/dx for MIP pion
+  fDeDxMIPMax(60),      // Max dE/dx for MIP pion
+  fDeltaBeta(0.1),      // delta beta cut for electrons 
+  fDeDxPi(0x0),         // dE/dx vs p for pions
+  fSigmaDeDx(0x0),      // sigma dE/dx vs ncl
+  fDeDxVsEtaNeg(0x0),   // eta < 0 dE/dx calib
+  fDeDxVsEtaPos(0x0),   // eta > 0 dE/dx calib
+  fDeDxVsNcl(0x0),      // ncl dE/dx calib
+  hSelection1(0x0),             // selected region in p and dE/dx for pion MIPs
+  hSelection2(0x0),             // selected region in p and dE/dx for pion MIPs
+  hSelection3(0x0),             // selected region in p and dE/dx for pion MIPs
+  hSelectionElectrons2(0x0),    // selected region in p and dE/dx for electrons
+  hSelectionElectrons3(0x0),    // selected region in p and dE/dx for electrons
+  hDeDxVsEta(0x0),             // dE/dx vs eta uncalibrated (pion MIPs)
+  hDeDxVsEtaElectrons(0x0),    // dE/dx vs eta uncalibrated (electrons)
+  hNclVsEta(0x0),              // Ncl vs eta (pion MIPs)
+  hNclVsEtaElectrons(0x0),     // Ncl vs eta (electrons)
+  hDeDxVsEtaCal(0x0),          // dE/dx vs eta calibrated (pion MIPs)
+  hDeDxVsEtaCalElectrons(0x0), // dE/dx vs eta calibrated (electrons)
+  hMeanEta(0x0),               // <eta> in the 4 eta interval (pion MIPs)
+  hMeanEtaElectrons(0x0),      // <eta> in the 4 eta interval (electrons)
+  hDeDx(0x0),                  // dE/dx no eta cut    (pion MIPs)
+  hDeDx1(0x0),                 // dE/dx 0.0<|eta|<0.2 (pion MIPs)
+  hDeDx2(0x0),                 // dE/dx 0.2<|eta|<0.4 (pion MIPs)
+  hDeDx3(0x0),                 // dE/dx 0.4<|eta|<0.6 (pion MIPs)
+  hDeDx4(0x0),                 // dE/dx 0.6<|eta|<0.8 (pion MIPs)
+  hDeDxElectrons(0x0),         // dE/dx no eta cut    (electrons)
+  hDeDxElectrons1(0x0),        // dE/dx 0.0<|eta|<0.2 (electrons)
+  hDeDxElectrons2(0x0),        // dE/dx 0.2<|eta|<0.4 (electrons)
+  hDeDxElectrons3(0x0),        // dE/dx 0.4<|eta|<0.6 (electrons)
+  hDeDxElectrons4(0x0),        // dE/dx 0.6<|eta|<0.8 (electrons)
+  hDeDxVsNclBefore(0x0),       // dE/dx vs ncl for step 2 calib (pion MIPs)
+  hDeDxVsNcl(0x0),             // dE/dx vs ncl no eta cut    (pion MIPs)
+  hDeDxVsNcl1(0x0),            // dE/dx vs ncl 0.0<|eta|<0.2 (pion MIPs)
+  hDeDxVsNcl2(0x0),            // dE/dx vs ncl 0.2<|eta|<0.4 (pion MIPs)
+  hDeDxVsNcl3(0x0),            // dE/dx vs ncl 0.4<|eta|<0.6 (pion MIPs)
+  hDeDxVsNcl4(0x0),            // dE/dx vs ncl 0.6<|eta|<0.8 (pion MIPs)
+  hDeDxVsNclElectrons(0x0),    // dE/dx vs ncl no eta cut    (electrons)
+  hDeDxVsNclElectrons1(0x0),   // dE/dx vs ncl 0.0<|eta|<0.2 (electrons)
+  hDeDxVsNclElectrons2(0x0),   // dE/dx vs ncl 0.2<|eta|<0.4 (electrons)
+  hDeDxVsNclElectrons3(0x0),   // dE/dx vs ncl 0.4<|eta|<0.6 (electrons)
+  hDeDxVsNclElectrons4(0x0),   // dE/dx vs ncl 0.6<|eta|<0.8 (electrons)
+  hMeanP(0x0),        // <p> vs p
+  hDeDxVsP(0x0),      // dE/dx vs p 
+  hDeDxVsPPiMc(0x0),  // dE/dx vs p for MC pions
+  hDeDxVsPKMc(0x0),   // dE/dx vs p for MC Kaons
+  hDeDxVsPPMc(0x0),   // dE/dx vs p for MC protons
+  hDeDxVsPEMc(0x0),   // dE/dx vs p for MC electrons
+  hDeDxVsPMuMc(0x0)   // dE/dx vs p for MC muons
+{
+  // default constructor - do not use
+
+}
+
+//_________________________________________________________
+AliHighPtDeDxCalib::AliHighPtDeDxCalib(const char* name, const char* title):
+  AliHighPtDeDxBase(name, title),
+  fStep(1),             // Step 1 = Eta calibration, step 2 = dE/dx calibration
+  fInit(0),             // Step 1 = Eta calibration, step 2 = dE/dx calibration, step = 3 ncl calib
+  fPMIPMin(0.4),        // Min P for MIP pion
+  fPMIPMax(0.6),        // Max P for MIP pion
+  fDeDxMIPMin(40),      // Min dE/dx for MIP pion
+  fDeDxMIPMax(60),      // Max dE/dx for MIP pion
+  fDeltaBeta(0.1),      // delta beta cut for electrons 
+  fDeDxPi(0x0),         // dE/dx vs p for pions
+  fSigmaDeDx(0x0),      // sigma dE/dx vs ncl
+  fDeDxVsEtaNeg(0x0),   // eta < 0 dE/dx calib
+  fDeDxVsEtaPos(0x0),   // eta > 0 dE/dx calib
+  fDeDxVsNcl(0x0),      // ncl dE/dx calib
+  hSelection1(0x0),             // selected region in p and dE/dx for pion MIPs
+  hSelection2(0x0),             // selected region in p and dE/dx for pion MIPs
+  hSelection3(0x0),             // selected region in p and dE/dx for pion MIPs
+  hSelectionElectrons2(0x0),    // selected region in p and dE/dx for electrons
+  hSelectionElectrons3(0x0),    // selected region in p and dE/dx for electrons
+  hDeDxVsEta(0x0),             // dE/dx vs eta uncalibrated (pion MIPs)
+  hDeDxVsEtaElectrons(0x0),    // dE/dx vs eta uncalibrated (electrons)
+  hNclVsEta(0x0),              // Ncl vs eta (pion MIPs)
+  hNclVsEtaElectrons(0x0),     // Ncl vs eta (electrons)
+  hDeDxVsEtaCal(0x0),          // dE/dx vs eta calibrated (pion MIPs)
+  hDeDxVsEtaCalElectrons(0x0), // dE/dx vs eta calibrated (electrons)
+  hMeanEta(0x0),               // <eta> in the 4 eta interval (pion MIPs)
+  hMeanEtaElectrons(0x0),      // <eta> in the 4 eta interval (electrons)
+  hDeDx(0x0),                  // dE/dx no eta cut    (pion MIPs)
+  hDeDx1(0x0),                 // dE/dx 0.0<|eta|<0.2 (pion MIPs)
+  hDeDx2(0x0),                 // dE/dx 0.2<|eta|<0.4 (pion MIPs)
+  hDeDx3(0x0),                 // dE/dx 0.4<|eta|<0.6 (pion MIPs)
+  hDeDx4(0x0),                 // dE/dx 0.6<|eta|<0.8 (pion MIPs)
+  hDeDxElectrons(0x0),         // dE/dx no eta cut    (electrons)
+  hDeDxElectrons1(0x0),        // dE/dx 0.0<|eta|<0.2 (electrons)
+  hDeDxElectrons2(0x0),        // dE/dx 0.2<|eta|<0.4 (electrons)
+  hDeDxElectrons3(0x0),        // dE/dx 0.4<|eta|<0.6 (electrons)
+  hDeDxElectrons4(0x0),        // dE/dx 0.6<|eta|<0.8 (electrons)
+  hDeDxVsNclBefore(0x0),       // dE/dx vs ncl no eta cut    (pion MIPs)
+  hDeDxVsNcl(0x0),             // dE/dx vs ncl no eta cut    (pion MIPs)
+  hDeDxVsNcl1(0x0),            // dE/dx vs ncl 0.0<|eta|<0.2 (pion MIPs)
+  hDeDxVsNcl2(0x0),            // dE/dx vs ncl 0.2<|eta|<0.4 (pion MIPs)
+  hDeDxVsNcl3(0x0),            // dE/dx vs ncl 0.4<|eta|<0.6 (pion MIPs)
+  hDeDxVsNcl4(0x0),            // dE/dx vs ncl 0.6<|eta|<0.8 (pion MIPs)
+  hDeDxVsNclElectrons(0x0),    // dE/dx vs ncl no eta cut    (electrons)
+  hDeDxVsNclElectrons1(0x0),   // dE/dx vs ncl 0.0<|eta|<0.2 (electrons)
+  hDeDxVsNclElectrons2(0x0),   // dE/dx vs ncl 0.2<|eta|<0.4 (electrons)
+  hDeDxVsNclElectrons3(0x0),   // dE/dx vs ncl 0.4<|eta|<0.6 (electrons)
+  hDeDxVsNclElectrons4(0x0),   // dE/dx vs ncl 0.6<|eta|<0.8 (electrons)
+  hMeanP(0x0),        // <p> vs p
+  hDeDxVsP(0x0),      // dE/dx vs p 
+  hDeDxVsPPiMc(0x0),  // dE/dx vs p for MC pions
+  hDeDxVsPKMc(0x0),   // dE/dx vs p for MC Kaons
+  hDeDxVsPPMc(0x0),   // dE/dx vs p for MC protons
+  hDeDxVsPEMc(0x0),   // dE/dx vs p for MC electrons
+  hDeDxVsPMuMc(0x0)   // dE/dx vs p for MC muons
+{
+  // named constructor
+}
+
+//_________________________________________________________
+AliHighPtDeDxCalib::~AliHighPtDeDxCalib()
+{
+  delete fDeDxPi;
+  delete fSigmaDeDx;
+  delete fDeDxVsEtaNeg;
+  delete fDeDxVsEtaPos;
+  delete fDeDxVsNcl;
+  delete hSelection1;
+  delete hSelection2;
+  delete hSelection3;
+  delete hSelectionElectrons2;
+  delete hSelectionElectrons3;
+  delete hDeDxVsEta;
+  delete hDeDxVsEtaElectrons;
+  delete hNclVsEta;
+  delete hNclVsEtaElectrons;
+  delete hDeDxVsEtaCal;
+  delete hDeDxVsEtaCalElectrons;
+  delete hMeanEta;
+  delete hMeanEtaElectrons;
+  delete hDeDx;
+  delete hDeDx1;
+  delete hDeDx2;
+  delete hDeDx3;
+  delete hDeDx4;
+  delete hDeDxElectrons;
+  delete hDeDxElectrons1;
+  delete hDeDxElectrons2;
+  delete hDeDxElectrons3;
+  delete hDeDxElectrons4;
+  delete hDeDxVsNclBefore;
+  delete hDeDxVsNcl;
+  delete hDeDxVsNcl1;
+  delete hDeDxVsNcl2;
+  delete hDeDxVsNcl3;
+  delete hDeDxVsNcl4;
+  delete hDeDxVsNclElectrons;
+  delete hDeDxVsNclElectrons1;
+  delete hDeDxVsNclElectrons2;
+  delete hDeDxVsNclElectrons3;
+  delete hDeDxVsNclElectrons4;
+  delete hMeanP;
+  delete hDeDxVsP;
+  delete hDeDxVsPPiMc;
+  delete hDeDxVsPKMc;
+  delete hDeDxVsPPMc;
+  delete hDeDxVsPEMc;
+  delete hDeDxVsPMuMc;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxCalib::Init(Int_t nPtBins, Double_t* ptBins)
+{
+  //
+  // Create histograms and functions
+  //
+
+  //
+  // init base class
+  //
+  AliHighPtDeDxBase::Init(nPtBins, ptBins);
+
+  //
+  // functions
+  //
+  fDeDxVsEtaNeg = new TF1("fDeDxVsEtaNeg", "pol3", -1,  0);
+  fDeDxVsEtaNeg->SetParameters(50, 0, 0, 0);
+  fDeDxVsEtaPos = new TF1("fDeDxVsEtaPos", "pol3",  0, +1);
+  fDeDxVsEtaPos->SetParameters(50, 0, 0, 0);
+
+  fDeDxVsNcl = new TF1("fDeDxVsNcl", "pol1",  0, 160);
+  fDeDxVsNcl->SetParameters(50, 0);
+}
+
+void AliHighPtDeDxCalib::Init(Int_t step, Int_t nPtBins, Double_t* ptBins)
+{
+  if(step != fStep)
+    cout << "Warning! Innit called for step " << step << " but next step is " << fStep << endl;
+
+  if(fInit>=step) {
+    cout << "Step " << step << " has been initialized!" << endl;
+    return;
+  }
+
+  switch (step) {
+  case 1:
+    //
+    // step 1 histograms - nCl calibration
+    //
+    hSelection1 = new TH2D("hSelection1", "dE/dx vs P (pion MIPs) step 1; P [GeV/c]; dE/dx",
+                          100, 0.2, 0.8, 
+                          100, 0, 100);
+    hSelection1->SetDirectory(0);
+
+    hDeDxVsNclBefore = new TH2D("hDeDxVsNclBefore", "dE/dx vs Ncl (pion MIPs); Ncl; dE/dx",
+                               18, 69.5, 159.5, 
+                               fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsNclBefore->Sumw2();
+    hDeDxVsNclBefore->SetDirectory(0);
+
+    fInit = 1;
+    
+    break;
+
+  case 2:
+    //
+    // step 2 histograms - eta calibration
+    //
+    
+    hSelection2 = new TH2D("hSelection1", "dE/dx vs P (pion MIPs) step 2; P [GeV/c]; dE/dx",
+                          100, 0.2, 0.8, 
+                          100, 0, 100);
+    hSelection2->SetDirectory(0);
+
+    hSelectionElectrons2 = new TH2D("hSelectionElectrons3", "dE/dx vs P (electrons) step 2; P [GeV/c]; dE/dx",
+                                  100, 0.2, 0.8, 
+                                  100, 0, 100);
+   hSelectionElectrons2->SetDirectory(0);
+
+    hDeDxVsEta = new TH2D("hDeDxVsEta", "dE/dx vs #eta (pion MIPs); #eta; dE/dx",
+                         50, -1.0, 1.0, 
+                         fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsEta->Sumw2();
+    hDeDxVsEta->SetDirectory(0);
+    
+    hDeDxVsEtaElectrons = new TH2D("hDeDxVsEtaElectrons", "dE/dx vs #eta (electrons); #eta; dE/dx",
+                                50, -1.0, 1.0, 
+                                  95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxVsEtaElectrons->Sumw2();
+    hDeDxVsEtaElectrons->SetDirectory(0);
+
+    hNclVsEta = new TH2D("hNclVsEta", "Ncl vs #eta (pion MIPs); #eta; Ncl",
+                        50, -1.0, 1.0, 
+                        18, 69.5, 159.5); 
+    hNclVsEta->Sumw2();
+    hNclVsEta->SetDirectory(0);
+    hNclVsEtaElectrons = new TH2D("hNclVsEtaElectrons", "Ncl vs #eta (electrons); #eta; Ncl",
+                                 50, -1.0, 1.0, 
+                                 18, 69.5, 159.5); 
+    hNclVsEtaElectrons->Sumw2();
+    hNclVsEtaElectrons->SetDirectory(0);
+    
+    fInit = 2;
+
+    break;
+
+  case 3:
+
+  //
+  // step 3 histograms 
+  //
+    hSelection3 = new TH2D("hSelection3", "dE/dx vs P (pion MIPs) step 3; P [GeV/c]; dE/dx",
+                          100, 0.2, 0.8, 
+                          100, 0, 100);
+    hSelection3->SetDirectory(0);
+
+    hSelectionElectrons3 = new TH2D("hSelectionElectrons3", "dE/dx vs P (electrons) step 3; P [GeV/c]; dE/dx",
+                                  100, 0.2, 0.8, 
+                                  100, 0, 100);
+    hSelectionElectrons3->SetDirectory(0);
+    
+
+    hMeanP = new TProfile("hMeanP", "mean p; p [GeV/c]; mean p",
+                         nPtBins, ptBins);
+    hMeanP->SetDirectory(0);
+    
+    hDeDxVsP = new TH2D("hDeDxVsP", "dE/dx vs P; p [GeV/c]; dE/dx",
+                       nPtBins, ptBins, 55, 40, 95);
+    hDeDxVsP->Sumw2();
+    hDeDxVsP->SetDirectory(0);
+    // dE/dx vs p 
+    if(fIsMc) {
+      
+      hDeDxVsPPiMc = new TH2D("hDeDxVsPPiMc", "dE/dx vs P; p [GeV/c]; dE/dx",
+                             nPtBins, ptBins, 55, 40, 95);
+      hDeDxVsPPiMc->Sumw2();
+      hDeDxVsPPiMc->SetDirectory(0);
+      
+      hDeDxVsPKMc = new TH2D("hDeDxVsPKMc", "dE/dx vs P; p [GeV/c]; dE/dx",
+                            nPtBins, ptBins, 55, 40, 95);
+      hDeDxVsPKMc->Sumw2();
+      hDeDxVsPKMc->SetDirectory(0);
+      
+      hDeDxVsPPMc = new TH2D("hDeDxVsPPMc", "dE/dx vs P; p [GeV/c]; dE/dx",
+                            nPtBins, ptBins, 55, 40, 95);
+      hDeDxVsPPMc->Sumw2();
+      hDeDxVsPPMc->SetDirectory(0);
+      
+      hDeDxVsPEMc = new TH2D("hDeDxVsPEMc", "dE/dx vs P; p [GeV/c]; dE/dx",
+                            nPtBins, ptBins, 55, 40, 95);
+      hDeDxVsPEMc->Sumw2();
+      hDeDxVsPEMc->SetDirectory(0);
+      
+      hDeDxVsPMuMc = new TH2D("hDeDxVsPMuMc", "dE/dx vs P; p [GeV/c]; dE/dx",
+                             nPtBins, ptBins, 55, 40, 95);
+      hDeDxVsPMuMc->Sumw2();
+      hDeDxVsPMuMc->SetDirectory(0);
+    }
+    
+    //
+    // step 3 histograms reated to the eta calibration
+    //
+    
+    hDeDxVsEtaCal = new TH2D("hDeDxVsEtaCal", "dE/dx vs #eta calibrated (pion MIPs); #eta; dE/dx",
+                            50, -1.0, 1.0, 
+                            fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsEtaCal->Sumw2();
+    hDeDxVsEtaCal->SetDirectory(0);
+    
+    hDeDxVsEtaCalElectrons = new TH2D("hDeDxVsEtaCalElectrons", "dE/dx vs #eta calibrated (electrons); #eta; dE/dx",
+                                     50, -1.0, 1.0, 
+                                     95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxVsEtaCalElectrons->Sumw2();
+    hDeDxVsEtaCalElectrons->SetDirectory(0);
+  
+    //
+    // step 3 histograms related to resolution
+    //
+    hMeanEta = new TProfile("hMeanEta", "<|#eta|> in |#eta| intervals (pion MIPs); |#eta|; <|#eta|>",
+                           4, 0, 0.8);
+    hMeanEta->SetDirectory(0);
+
+    hMeanEtaElectrons = new TProfile("hMeanEtaElectrons", "<|#eta|> in |#eta| intervals (electrons); |#eta|; <|#eta|>",
+                                    4, 0, 0.8);
+    hMeanEtaElectrons->SetDirectory(0);
+    
+    hDeDx = new TH1D("hDeDx", "dE/dx (pion MIPs); dE/dx; Counts",
+                    fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDx->Sumw2();
+    hDeDx->SetDirectory(0);
+    hDeDx1 = new TH1D("hDeDx1", "dE/dx |#eta|<0.2 (pion MIPs); dE/dx; Counts",
+                     fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDx1->Sumw2();
+    hDeDx1->SetDirectory(0);
+    hDeDx2 = new TH1D("hDeDx2", "dE/dx 0.2<|#eta|<0.4 (pion MIPs); dE/dx; Counts",
+                     fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDx2->Sumw2();
+    hDeDx2->SetDirectory(0);
+    hDeDx3 = new TH1D("hDeDx3", "dE/dx 0.4<|#eta|<0.6 (pion MIPs); dE/dx; Counts",
+                     fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDx3->Sumw2();
+    hDeDx3->SetDirectory(0);
+    hDeDx4 = new TH1D("hDeDx4", "dE/dx 0.6<|#eta|<0.8 (pion MIPs); dE/dx; Counts",
+                     fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDx4->Sumw2();
+    hDeDx4->SetDirectory(0);
+    
+    hDeDxElectrons = new TH1D("hDeDxElectrons", "dE/dx (electrons); dE/dx; Counts",
+                             95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxElectrons->Sumw2();
+    hDeDxElectrons->SetDirectory(0);
+    hDeDxElectrons1 = new TH1D("hDeDxElectrons1", "dE/dx |#eta|<0.2 (electrons); dE/dx; Counts",
+                              95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxElectrons1->Sumw2();
+    hDeDxElectrons1->SetDirectory(0);
+    hDeDxElectrons2 = new TH1D("hDeDxElectrons2", "dE/dx 0.2<|#eta|<0.4 (electrons); dE/dx; Counts",
+                              95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxElectrons2->Sumw2();
+    hDeDxElectrons2->SetDirectory(0);
+    hDeDxElectrons3 = new TH1D("hDeDxElectrons3", "dE/dx 0.4<|#eta|<0.6 (electrons); dE/dx; Counts",
+                              95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxElectrons3->Sumw2();
+    hDeDxElectrons3->SetDirectory(0);
+    hDeDxElectrons4 = new TH1D("hDeDxElectrons4", "dE/dx 0.6<|#eta|<0.8 (electrons); dE/dx; Counts",
+                              95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxElectrons4->Sumw2();
+    hDeDxElectrons4->SetDirectory(0);
+    
+    //
+    // step 3 histograms for resolution
+    //
+    
+    
+    
+    hDeDxVsNcl = new TH2D("hDeDxVsNcl", "dE/dx vs Ncl (pion MIPs); Ncl; dE/dx",
+                         18, 69.5, 159.5, 
+                         fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsNcl->Sumw2();
+    hDeDxVsNcl->SetDirectory(0);
+    hDeDxVsNcl1 = new TH2D("hDeDxVsNcl1", "dE/dx vs Ncl |#eta|<0.2 (pion MIPs); Ncl; dE/dx",
+                          18, 69.5, 159.5, 
+                          fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsNcl1->Sumw2();
+    hDeDxVsNcl1->SetDirectory(0);
+    hDeDxVsNcl2 = new TH2D("hDeDxVsNcl2", "dE/dx vs Ncl 0.2<|#eta|<0.4 (pion MIPs); Ncl; dE/dx",
+                          18, 69.5, 159.5, 
+                          fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsNcl2->Sumw2();
+    hDeDxVsNcl2->SetDirectory(0);
+    hDeDxVsNcl3 = new TH2D("hDeDxVsNcl3", "dE/dx vs Ncl 0.4<|#eta|<0.6 (pion MIPs); Ncl; dE/dx",
+                          18, 69.5, 159.5, 
+                          fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsNcl3->Sumw2();
+    hDeDxVsNcl3->SetDirectory(0);
+    hDeDxVsNcl4 = new TH2D("hDeDxVsNcl4", "dE/dx vs Ncl 0.6<|#eta|<0.8 (pion MIPs); Ncl; dE/dx",
+                          18, 69.5, 159.5, 
+                          fDeDxMIPMax-fDeDxMIPMin, fDeDxMIPMin, fDeDxMIPMax);
+    hDeDxVsNcl4->Sumw2();
+    hDeDxVsNcl4->SetDirectory(0);
+    
+    hDeDxVsNclElectrons = new TH2D("hDeDxVsNclElectrons", "dE/dx vs Ncl (electrons); Ncl; dE/dx",
+                                  18, 69.5, 159.5, 
+                                  95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxVsNclElectrons->Sumw2();
+    hDeDxVsNclElectrons->SetDirectory(0);
+    hDeDxVsNclElectrons1 = new TH2D("hDeDxVsNclElectrons1", "dE/dx vs Ncl |#eta|<0.2 (electrons); Ncl; dE/dx",
+                                   18, 69.5, 159.5, 
+                                   95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxVsNclElectrons1->Sumw2();
+    hDeDxVsNclElectrons1->SetDirectory(0);
+    hDeDxVsNclElectrons2 = new TH2D("hDeDxVsNclElectrons2", "dE/dx vs Ncl 0.2<|#eta|<0.4 (electrons); Ncl; dE/dx",
+                        18, 69.5, 159.5, 
+                                   95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxVsNclElectrons2->Sumw2();
+    hDeDxVsNclElectrons2->SetDirectory(0);
+    hDeDxVsNclElectrons3 = new TH2D("hDeDxVsNclElectrons3", "dE/dx vs Ncl 0.4<|#eta|<0.6 (electrons); Ncl; dE/dx",
+                                   18, 69.5, 159.5, 
+                        95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxVsNclElectrons3->Sumw2();
+    hDeDxVsNclElectrons3->SetDirectory(0);
+    hDeDxVsNclElectrons4 = new TH2D("hDeDxVsNclElectrons4", "dE/dx vs Ncl 0.6<|#eta|<0.8 (electrons); Ncl; dE/dx",
+                                   18, 69.5, 159.5, 
+                                   95-fDeDxMIPMax, fDeDxMIPMax, 95);
+    hDeDxVsNclElectrons4->Sumw2();
+    hDeDxVsNclElectrons4->SetDirectory(0);
+
+    fInit = 3;
+
+    break;
+  default:
+    cout << "No init implemented for step: " << step << endl;
+  }
+}
+
+//_________________________________________________________
+void AliHighPtDeDxCalib::FillTrackInfo(Float_t weight)
+{
+  if(fStep > 2) { // calibate eta dependence
+    
+    if(fTrackEta < 0) 
+      fTrackDeDx *= 50.0 / fDeDxVsEtaNeg->Eval(fTrackEta);
+    else
+      fTrackDeDx *= 50.0 / fDeDxVsEtaPos->Eval(fTrackEta);
+  }
+
+  if(fStep > 1) { // calibate ncl dependence
+    
+    fTrackDeDx *= 50.0 / fDeDxVsNcl->Eval(fTrackNcl);
+  }
+  
+  //
+  // Fill information for MIP pions
+  //
+  if(IsMIP()) {
+    
+    if(fStep == 2) { // calibate eta
+      
+      hSelection2->Fill(fTrackP, fTrackDeDx);
+      hDeDxVsEta->Fill(fTrackEta, fTrackDeDx);
+      hNclVsEta->Fill(fTrackEta, fTrackNcl);
+    } else if (fStep==1) { // calibrate nCl dependence
+      
+      hSelection1->Fill(fTrackP, fTrackDeDx);
+      hDeDxVsNclBefore->Fill(fTrackNcl, fTrackDeDx);
+
+    } else if (fStep==3) { // calibrate <dE/dx>pi and check eta calibration
+      
+      AliHighPtDeDxBase::FillTrackInfo(weight);
+
+      hSelection3->Fill(fTrackP, fTrackDeDx);
+
+      hDeDxVsEtaCal->Fill(fTrackEta, fTrackDeDx);
+      
+      hMeanEta->Fill(TMath::Abs(fTrackEta), TMath::Abs(fTrackEta));
+      hDeDx->Fill(fTrackDeDx);
+      hDeDxVsNcl->Fill(fTrackNcl, fTrackDeDx);
+      if(TMath::Abs(fTrackEta)<0.2) {
+       hDeDx1->Fill(fTrackDeDx);
+       hDeDxVsNcl1->Fill(fTrackNcl, fTrackDeDx);
+      } else if(TMath::Abs(fTrackEta)>=0.2&&TMath::Abs(fTrackEta)<0.4) {
+       hDeDx2->Fill(fTrackDeDx);
+       hDeDxVsNcl2->Fill(fTrackNcl, fTrackDeDx);
+      } else if(TMath::Abs(fTrackEta)>=0.4&&TMath::Abs(fTrackEta)<0.6) {
+       hDeDx3->Fill(fTrackDeDx);
+       hDeDxVsNcl3->Fill(fTrackNcl, fTrackDeDx);
+      }else if(TMath::Abs(fTrackEta)>=0.6&&TMath::Abs(fTrackEta)<0.8) { 
+       hDeDx4->Fill(fTrackDeDx);
+       hDeDxVsNcl4->Fill(fTrackNcl, fTrackDeDx);
+      }
+    }
+  }
+
+  //
+  // Fill information for electrons with same p as MIP pions
+  //
+  // This is done to validate the calibration/assumptions about sigma for a
+  // group of tracks with same topology but much higher dE/dx (plateau)
+  //
+  if(fStep > 1 && IsElectron()) {
+
+    if(fStep == 2) { // calibate eta
+      
+      hSelectionElectrons2->Fill(fTrackP, fTrackDeDx);
+      hDeDxVsEtaElectrons->Fill(fTrackEta, fTrackDeDx);
+      hNclVsEtaElectrons->Fill(fTrackEta, fTrackNcl);
+    } else if (fStep==3) { // calibrate <dE/dx>pi and check eta calibration
+      
+      hSelectionElectrons3->Fill(fTrackP, fTrackDeDx);
+
+      hDeDxVsEtaCalElectrons->Fill(fTrackEta, fTrackDeDx);
+      
+      hMeanEtaElectrons->Fill(TMath::Abs(fTrackEta), TMath::Abs(fTrackEta));
+      hDeDxElectrons->Fill(fTrackDeDx);
+      hDeDxVsNclElectrons->Fill(fTrackNcl, fTrackDeDx);
+      if(TMath::Abs(fTrackEta)<0.2) {
+       hDeDxElectrons1->Fill(fTrackDeDx);
+       hDeDxVsNclElectrons1->Fill(fTrackNcl, fTrackDeDx);
+      } else if(TMath::Abs(fTrackEta)>=0.2&&TMath::Abs(fTrackEta)<0.4) {
+       hDeDxElectrons2->Fill(fTrackDeDx);
+       hDeDxVsNclElectrons2->Fill(fTrackNcl, fTrackDeDx);
+      } else if(TMath::Abs(fTrackEta)>=0.4&&TMath::Abs(fTrackEta)<0.6) {
+       hDeDxElectrons3->Fill(fTrackDeDx);
+       hDeDxVsNclElectrons3->Fill(fTrackNcl, fTrackDeDx);
+      }else if(TMath::Abs(fTrackEta)>=0.6&&TMath::Abs(fTrackEta)<0.8) { 
+       hDeDxElectrons4->Fill(fTrackDeDx);
+       hDeDxVsNclElectrons4->Fill(fTrackNcl, fTrackDeDx);
+      }
+    }
+  }
+
+  //
+  // Fill information for high pT tracks (dE/dx vs p)
+  //
+  if(fStep==3) { // Fill dE/dx vs 
+    
+    hDeDxVsP->Fill(fTrackP, fTrackDeDx, weight);
+    hMeanP->Fill(fTrackP, fTrackP);    
+
+    if(fIsMc) {
+      
+      switch (fTrackPidMc) {
+       
+      case 1: // pion
+         hDeDxVsPPiMc->Fill(fTrackP, fTrackDeDx, weight);
+       break;
+      case 2: // kaon
+         hDeDxVsPKMc ->Fill(fTrackP, fTrackDeDx, weight);
+       break;
+      case 3: // proton
+         hDeDxVsPPMc ->Fill(fTrackP, fTrackDeDx, weight);
+       break;
+      case 4: // electron
+         hDeDxVsPEMc ->Fill(fTrackP, fTrackDeDx, weight);
+       break;
+      case 5: // muon
+         hDeDxVsPMuMc ->Fill(fTrackP, fTrackDeDx, weight);
+       break;
+      default:
+       break;
+      }
+    }
+  }
+}
+  
+
+//___________________________________________________________________________
+Bool_t AliHighPtDeDxCalib::IsMIP()
+{
+  if(fTrackP > fPMIPMin && fTrackP<fPMIPMax &&
+     fTrackDeDx > fDeDxMIPMin && fTrackDeDx < fDeDxMIPMax)
+    return kTRUE;
+  
+  return kFALSE;
+}
+
+//___________________________________________________________________________
+Bool_t AliHighPtDeDxCalib::IsElectron()
+{
+  if(fTrackP > fPMIPMin && fTrackP<fPMIPMax &&
+     fTrackDeDx > (fDeDxMIPMax+5) && TMath::Abs(fTrackBeta-1)<fDeltaBeta)
+    return kTRUE;
+  
+  return kFALSE;
+}
+
+
+//___________________________________________________________________________
+void AliHighPtDeDxCalib::PerformEtaCal()
+{
+  TProfile* hDeDxVsEtaProf = hDeDxVsEta->ProfileX();
+  hDeDxVsEtaProf->SetMarkerStyle(29);
+  hDeDxVsEtaProf->Fit(fDeDxVsEtaNeg, "0", "", -1, 0);
+  hDeDxVsEtaProf->Fit(fDeDxVsEtaPos, "0", "",  0, 1);
+  delete hDeDxVsEtaProf;
+}
+
+//___________________________________________________________________________
+void AliHighPtDeDxCalib::PerformNclCal()
+{
+  TProfile* hDeDxVsNclProf = hDeDxVsNclBefore->ProfileX();
+  hDeDxVsNclProf->SetMarkerStyle(29);
+  hDeDxVsNclProf->Fit(fDeDxVsNcl, "0", "", 69.5, 159.5);
+  delete hDeDxVsNclProf;
+}
+
+//___________________________________________________________________________
+TCanvas* AliHighPtDeDxCalib::DrawNclCal()
+{
+  TCanvas* cNcl = new TCanvas("cNcl", "dE/dx vs Ncl for MIP pions", 600, 400);
+  cNcl->Clear();
+  cNcl->cd();
+  hDeDxVsNclBefore->DrawCopy("COL");
+  TProfile* hDeDxVsNclProf = hDeDxVsNclBefore->ProfileX();
+  hDeDxVsNclProf->SetMarkerStyle(29);
+  hDeDxVsNclProf->DrawCopy("SAME");
+  fDeDxVsNcl->Draw("SAME");
+  delete hDeDxVsNclProf;
+  return cNcl;
+}
+
+//___________________________________________________________________________
+TCanvas* AliHighPtDeDxCalib::DrawEta(Bool_t forMIP)
+{
+  // Draw dE/dx vs eta for step 1 (calibration)
+  if(forMIP) {
+
+    TCanvas* cEta = new TCanvas("cEta", "dE/dx vs Eta for MIP pions", 600, 400);
+    cEta->Clear();
+    cEta->cd();
+    hDeDxVsEta->DrawCopy("COL");
+
+    TProfile* hDeDxVsEtaProf = hDeDxVsEta->ProfileX();
+    hDeDxVsEtaProf->SetMarkerStyle(29);
+    hDeDxVsEtaProf->DrawCopy("SAME");
+    fDeDxVsEtaNeg->DrawCopy("SAME");
+    fDeDxVsEtaPos->DrawCopy("SAME");
+
+    return cEta;
+  }
+
+  TCanvas* cEta = new TCanvas("cEtaElectrons", "dE/dx vs Eta for electrons", 600, 400);
+  cEta->Clear();
+  cEta->cd();
+  hDeDxVsEtaElectrons->DrawCopy("COL");
+
+  TProfile* hDeDxVsEtaProfElectrons = hDeDxVsEtaElectrons->ProfileX();
+  hDeDxVsEtaProfElectrons->SetMarkerStyle(29);
+  hDeDxVsEtaProfElectrons->DrawCopy("SAME");
+
+  return cEta;
+}     
+
+//___________________________________________________________________________
+TCanvas* AliHighPtDeDxCalib::DrawEtaCalibrated(Bool_t forMIP)
+{
+  // Draw dE/dx vs eta for step 2 (after calibration)
+  if(forMIP) {
+
+    TCanvas* cEtaCal = new TCanvas("cEtaCal", "dE/dx vs Eta for MIP pions (calibrated)", 600, 400);
+    cEtaCal->Clear();
+    cEtaCal->cd();
+    hDeDxVsEtaCal->DrawCopy("COL");
+
+    TProfile* hDeDxVsEtaCalProf = hDeDxVsEtaCal->ProfileX();
+    hDeDxVsEtaCalProf->SetMarkerStyle(29);
+    hDeDxVsEtaCalProf->DrawCopy("SAME");
+    
+    return cEtaCal;
+  }
+
+  TCanvas* cEtaCalElectrons = new TCanvas("cEtaCalElectrons", "dE/dx vs Eta (calibrated electrons)", 600, 400);
+  cEtaCalElectrons->Clear();
+  cEtaCalElectrons->cd();
+  hDeDxVsEtaCalElectrons->DrawCopy("COL");
+  TProfile* hDeDxVsEtaCalElectronsProf = 
+    hDeDxVsEtaCalElectrons->ProfileX();
+  hDeDxVsEtaCalElectronsProf->SetMarkerStyle(29);
+  hDeDxVsEtaCalElectronsProf->DrawCopy("SAME");
+  
+  return cEtaCalElectrons;
+}     
+
+//___________________________________________________________________________
+TCanvas* AliHighPtDeDxCalib::DrawSelectionHistograms(Int_t step)
+{
+  TCanvas* cSelection = new TCanvas("cSelection", "dE/dx vs p selection", 800, 800);
+  cSelection->Clear();
+  cSelection->Divide(2,2);
+
+  cSelection->cd(1);
+  if(step==1)
+    hSelection1->DrawCopy("COL");
+  else if(step==2)
+    hSelection2->DrawCopy("COL");
+  else if(step==3)
+    hSelection3->DrawCopy("COL");
+
+  cSelection->cd(2);
+  if(step==2)
+    hSelectionElectrons2->DrawCopy("COL");
+  else if(step==3)
+    hSelectionElectrons3->DrawCopy("COL");
+  
+  cSelection->cd(3);
+  hNclVsEta->DrawCopy("COL");
+
+  cSelection->cd(4);
+  hNclVsEtaElectrons->DrawCopy("COL");
+  
+  return cSelection;
+}
+
+//___________________________________________________________________________
+TH1D* AliHighPtDeDxCalib::GetHistDeDx(Bool_t forMIP, Int_t etaBin)
+{
+  switch (etaBin) {
+       
+  case 0:
+    if(forMIP)
+      return hDeDx;
+    else
+      return hDeDxElectrons;
+    break;
+  case 1:
+    if(forMIP)
+      return hDeDx1;
+    else
+      return hDeDxElectrons1;
+    break;
+  case 2:
+    if(forMIP)
+      return hDeDx2;
+    else
+      return hDeDxElectrons2;
+    break;
+  case 3:
+    if(forMIP)
+      return hDeDx3;
+    else
+      return hDeDxElectrons3;
+    break;
+  case 4:
+    if(forMIP)
+      return hDeDx4;
+    else
+      return hDeDxElectrons4;
+    break;
+  default:
+    cout << "Eta bin: " << etaBin << " not found" << endl;
+    break;
+  }
+  return 0;
+}
+
+//___________________________________________________________________________
+TH2D* AliHighPtDeDxCalib::GetHistDeDxVsNcl(Bool_t forMIP, Int_t etaBin)
+{
+  switch (etaBin) {
+       
+  case 0:
+    if(forMIP)
+      return hDeDxVsNcl;
+    else
+      return hDeDxVsNclElectrons;
+    break;
+  case 1:
+    if(forMIP)
+      return hDeDxVsNcl1;
+    else
+      return hDeDxVsNclElectrons1;
+    break;
+  case 2:
+    if(forMIP)
+      return hDeDxVsNcl2;
+    else
+      return hDeDxVsNclElectrons2;
+    break;
+  case 3:
+    if(forMIP)
+      return hDeDxVsNcl3;
+    else
+      return hDeDxVsNclElectrons3;
+    break;
+  case 4:
+    if(forMIP)
+      return hDeDxVsNcl4;
+    else
+      return hDeDxVsNclElectrons4;
+    break;
+  default:
+    cout << "Eta bin: " << etaBin << " not found" << endl;
+    break;
+  }
+  return 0;
+}
+
+//___________________________________________________________________________
+TH2D* AliHighPtDeDxCalib::GetHistDeDxVsP(Int_t pid)
+{
+  switch (pid) {
+       
+  case 0:
+    return hDeDxVsP;
+    break;
+  case 1:
+    return hDeDxVsPPiMc;
+    break;
+  case 2:
+    return hDeDxVsPKMc;
+    break;
+  case 3:
+    return hDeDxVsPPMc;
+    break;
+  case 4:
+    return hDeDxVsPEMc;
+    break;
+  case 5:
+    return hDeDxVsPMuMc;
+    break;
+  default:
+    cout << "PID: " << pid << " not found" << endl;
+    break;
+  }
+  return 0;
+}
+
+/*
+
+      }
+
+  }
+
+*/
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxCalib.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxCalib.h
new file mode 100644 (file)
index 0000000..a3366ac
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef ALIHIGHPTDEDXCALIB_H
+#define ALIHIGHPTDEDXCALIB_H
+
+#include <TCanvas.h>
+#include <TH1.h>
+#include <TH2.h>
+#include <TProfile.h>
+
+#include "AliHighPtDeDxBase.h"
+
+class AliHighPtDeDxCalib : public AliHighPtDeDxBase {
+ public:
+  AliHighPtDeDxCalib(); // default constructor  
+  AliHighPtDeDxCalib(const char* name, const char* title); // named constructor  
+  virtual ~AliHighPtDeDxCalib(); // default destructor
+
+  virtual void Init(Int_t nPtBins, Double_t* ptBins);
+  virtual void Init(Int_t step, Int_t nPtBins, Double_t* ptBins);
+  virtual void FillTrackInfo(Float_t weight);
+  virtual void PerformEtaCal();
+  virtual void PerformNclCal();
+
+  TCanvas* DrawNclCal();
+  TCanvas* DrawEta(Bool_t forMIP);
+  TCanvas* DrawEtaCalibrated(Bool_t forMIP);
+  TCanvas* DrawSelectionHistograms(Int_t step=3);
+  
+  virtual void SetStep(Int_t value) { fStep = value; }
+
+  virtual void SetPMIPMin(Double_t value)    { fPMIPMin    = value; }
+  virtual void SetPMIPMax(Double_t value)    { fPMIPMax    = value; }
+  virtual void SetDeDxMIPMin(Double_t value) { fDeDxMIPMin = value; }
+  virtual void SetDeDxMIPMax(Double_t value) { fDeDxMIPMax = value; }
+  virtual void SetDeltaBeta(Double_t value)  { fDeltaBeta  = value; }
+
+  TF1*  GetDeDxVsEtaNeg()  {return fDeDxVsEtaNeg;}
+  TF1*  GetDeDxVsEtaPos()  {return fDeDxVsEtaPos;} 
+  TF1*  GetDeDxVsNcl()     {return fDeDxVsNcl;}
+  TProfile* GetHistMeanP() {return hMeanP;}
+  TH1D* GetHistDeDx(Bool_t forMIP, Int_t etaBin);
+  TH2D* GetHistDeDxVsNcl(Bool_t forMIP, Int_t etaBin);
+  TH2D* GetHistDeDxVsP(Int_t pid);
+
+  //  virtual void Init(Int_t nPtBins, Double_t* ptBins);
+  //  virtual void FillTrackInfo(Double_t weight=1);
+  
+ private:
+
+  Bool_t IsMIP();
+  Bool_t IsElectron();
+
+  Int_t fStep;             // Step 1 = Eta calibration, step 2 = dE/dx calibration
+  Int_t fInit;             // Step 1 = Eta calibration, step 2 = dE/dx calibration
+  
+  Double_t fPMIPMin;       // Min P for MIP pion
+  Double_t fPMIPMax;       // Max P for MIP pion
+  Double_t fDeDxMIPMin;    // Min dE/dx for MIP pion
+  Double_t fDeDxMIPMax;    // Max dE/dx for MIP pion
+  Double_t fDeltaBeta;     // delta beta cut for electrons 
+
+  TF1*   fDeDxPi;          // dE/dx vs p for pions
+  TF1*   fSigmaDeDx;       // sigma dE/dx vs ncl
+
+  // functions
+  TF1* fDeDxVsEtaNeg;      // eta < 0 dE/dx calib
+  TF1* fDeDxVsEtaPos;      // eta > 0 dE/dx calib
+  TF1* fDeDxVsNcl;         // ncl dE/dx calib
+  
+  // histograms - step 0
+  TH2D* hSelection1;            // selected region in p and dE/dx for pion MIPs
+  TH2D* hSelection2;            // selected region in p and dE/dx for pion MIPs
+  TH2D* hSelection3;            // selected region in p and dE/dx for pion MIPs
+  TH2D* hSelectionElectrons2;   // selected region in p and dE/dx for electrons
+  TH2D* hSelectionElectrons3;   // selected region in p and dE/dx for electrons
+  TH2D* hDeDxVsEta;             // dE/dx vs eta uncalibrated (pion MIPs)
+  TH2D* hDeDxVsEtaElectrons;    // dE/dx vs eta uncalibrated (electrons)
+  TH2D* hNclVsEta;              // Ncl vs eta (pion MIPs)
+  TH2D* hNclVsEtaElectrons;     // Ncl vs eta (electrons)
+
+  // histograms - step 1
+  TH2D* hDeDxVsEtaCal;          // dE/dx vs eta calibrated (pion MIPs)
+  TH2D* hDeDxVsEtaCalElectrons; // dE/dx vs eta calibrated (electrons)
+  TProfile* hMeanEta;           // <eta> in the 4 eta interval (pion MIPs)
+  TProfile* hMeanEtaElectrons;  // <eta> in the 4 eta interval (electrons)
+
+  TH1D* hDeDx;                  // dE/dx no eta cut    (pion MIPs)
+  TH1D* hDeDx1;                 // dE/dx 0.0<|eta|<0.2 (pion MIPs)
+  TH1D* hDeDx2;                 // dE/dx 0.2<|eta|<0.4 (pion MIPs)
+  TH1D* hDeDx3;                 // dE/dx 0.4<|eta|<0.6 (pion MIPs)
+  TH1D* hDeDx4;                 // dE/dx 0.6<|eta|<0.8 (pion MIPs)
+  TH1D* hDeDxElectrons;         // dE/dx no eta cut    (electrons)
+  TH1D* hDeDxElectrons1;        // dE/dx 0.0<|eta|<0.2 (electrons)
+  TH1D* hDeDxElectrons2;        // dE/dx 0.2<|eta|<0.4 (electrons)
+  TH1D* hDeDxElectrons3;        // dE/dx 0.4<|eta|<0.6 (electrons)
+  TH1D* hDeDxElectrons4;        // dE/dx 0.6<|eta|<0.8 (electrons)
+  
+  TH2D* hDeDxVsNclBefore;       // dE/dx vs ncl for calib (step 2)
+
+  TH2D* hDeDxVsNcl;             // dE/dx vs ncl no eta cut    (pion MIPs)
+  TH2D* hDeDxVsNcl1;            // dE/dx vs ncl 0.0<|eta|<0.2 (pion MIPs)
+  TH2D* hDeDxVsNcl2;            // dE/dx vs ncl 0.2<|eta|<0.4 (pion MIPs)
+  TH2D* hDeDxVsNcl3;            // dE/dx vs ncl 0.4<|eta|<0.6 (pion MIPs)
+  TH2D* hDeDxVsNcl4;            // dE/dx vs ncl 0.6<|eta|<0.8 (pion MIPs)
+  TH2D* hDeDxVsNclElectrons;    // dE/dx vs ncl no eta cut    (electrons)
+  TH2D* hDeDxVsNclElectrons1;   // dE/dx vs ncl 0.0<|eta|<0.2 (electrons)
+  TH2D* hDeDxVsNclElectrons2;   // dE/dx vs ncl 0.2<|eta|<0.4 (electrons)
+  TH2D* hDeDxVsNclElectrons3;   // dE/dx vs ncl 0.4<|eta|<0.6 (electrons)
+  TH2D* hDeDxVsNclElectrons4;   // dE/dx vs ncl 0.6<|eta|<0.8 (electrons)
+  
+  /* TH1D* GetHistDeDx(Int_t bin = 0) { */
+    
+
+  /* } */
+
+  // histograms - step 1 dE/dx
+
+  TProfile* hMeanP;    // <p> vs p
+
+  TH2D* hDeDxVsP;      // dE/dx vs p 
+  TH2D* hDeDxVsPPiMc;  // dE/dx vs p for MC pions
+  TH2D* hDeDxVsPKMc;   // dE/dx vs p for MC Kaons
+  TH2D* hDeDxVsPPMc;   // dE/dx vs p for MC protons
+  TH2D* hDeDxVsPEMc;   // dE/dx vs p for MC electrons
+  TH2D* hDeDxVsPMuMc;  // dE/dx vs p for MC muons
+  
+  //  void Print(Option_t* option) const;
+  
+  ClassDef(AliHighPtDeDxCalib, 1)  // AliHighPtDeDxCalib information
+    };
+
+#endif
+       
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxData.cxx b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxData.cxx
new file mode 100644 (file)
index 0000000..7bbce84
--- /dev/null
@@ -0,0 +1,483 @@
+#include "AliHighPtDeDxData.h"
+
+#ifndef __IOSTREAM__
+#include <iostream>
+#endif
+
+#include <TRandom.h>
+
+using namespace std;
+
+ClassImp(AliHighPtDeDxData);
+
+//
+// AliHighPtDeDxData class
+//
+// This class contains the AliHighPtDeDxData information 
+//
+
+//_________________________________________________________
+AliHighPtDeDxData::AliHighPtDeDxData():
+  AliHighPtDeDxBase(),
+  fDeDxPi(0x0),
+  fDeDxK(0x0),
+  fDeDxP(0x0),
+  fDeDxE(0x0),
+  fSigmaDeDx(0x0),
+  hDeltaPiVsPt(0x0),
+  hDeltaPiVsPtNeg(0x0),
+  hDeltaPiVsPtPos(0x0),
+  hDeltaPiVsPtPiGen(0x0),
+  hDeltaPiVsPtPiGenNeg(0x0),
+  hDeltaPiVsPtPiGenPos(0x0),
+  hDeltaPiVsPtKGen(0x0),
+  hDeltaPiVsPtKGenNeg(0x0),
+  hDeltaPiVsPtKGenPos(0x0),
+  hDeltaPiVsPtPGen(0x0),
+  hDeltaPiVsPtPGenNeg(0x0),
+  hDeltaPiVsPtPGenPos(0x0),
+  hDeltaPiVsPtEGen(0x0),
+  hDeltaPiVsPtEGenNeg(0x0),
+  hDeltaPiVsPtEGenPos(0x0),
+  hDeltaPiVsPtPiMc(0x0),
+  hDeltaPiVsPtPiMcNeg(0x0),
+  hDeltaPiVsPtPiMcPos(0x0),
+  hDeltaPiVsPtKMc(0x0),
+  hDeltaPiVsPtKMcNeg(0x0),
+  hDeltaPiVsPtKMcPos(0x0),
+  hDeltaPiVsPtPMc(0x0),
+  hDeltaPiVsPtPMcNeg(0x0),
+  hDeltaPiVsPtPMcPos(0x0),
+  hPtPi(0x0),
+  hPtK(0x0),
+  hPtP(0x0),
+  hPrimaryVsPidVsPt(0x0)
+{
+  // default constructor - do not use
+}
+
+//_________________________________________________________
+AliHighPtDeDxData::AliHighPtDeDxData(const char* name, const char* title):
+  AliHighPtDeDxBase(name, title),
+  fDeDxPi(0x0),
+  fDeDxK(0x0),
+  fDeDxP(0x0),
+  fDeDxE(0x0),
+  fSigmaDeDx(0x0),
+  hDeltaPiVsPt(0x0),
+  hDeltaPiVsPtNeg(0x0),
+  hDeltaPiVsPtPos(0x0),
+  hDeltaPiVsPtPiGen(0x0),
+  hDeltaPiVsPtPiGenNeg(0x0),
+  hDeltaPiVsPtPiGenPos(0x0),
+  hDeltaPiVsPtKGen(0x0),
+  hDeltaPiVsPtKGenNeg(0x0),
+  hDeltaPiVsPtKGenPos(0x0),
+  hDeltaPiVsPtPGen(0x0),
+  hDeltaPiVsPtPGenNeg(0x0),
+  hDeltaPiVsPtPGenPos(0x0),
+  hDeltaPiVsPtEGen(0x0),
+  hDeltaPiVsPtEGenNeg(0x0),
+  hDeltaPiVsPtEGenPos(0x0),
+  hDeltaPiVsPtPiMc(0x0),
+  hDeltaPiVsPtPiMcNeg(0x0),
+  hDeltaPiVsPtPiMcPos(0x0),
+  hDeltaPiVsPtKMc(0x0),
+  hDeltaPiVsPtKMcNeg(0x0),
+  hDeltaPiVsPtKMcPos(0x0),
+  hDeltaPiVsPtPMc(0x0),
+  hDeltaPiVsPtPMcNeg(0x0),
+  hDeltaPiVsPtPMcPos(0x0),
+  hPtPi(0x0),
+  hPtK(0x0),
+  hPtP(0x0),
+  hPrimaryVsPidVsPt(0x0)
+{
+  // named constructor
+}
+
+//_________________________________________________________
+AliHighPtDeDxData::~AliHighPtDeDxData()
+{
+  // delete fDeDxPi;
+  // delete fDeDxK;
+  // delete fDeDxP;
+  // delete fSigmaDeDx;
+  delete hDeltaPiVsPt;
+  delete hDeltaPiVsPtNeg;
+  delete hDeltaPiVsPtPos;
+  delete hDeltaPiVsPtPiGen;
+  delete hDeltaPiVsPtPiGenNeg;
+  delete hDeltaPiVsPtPiGenPos;
+  delete hDeltaPiVsPtKGen;
+  delete hDeltaPiVsPtKGenNeg;
+  delete hDeltaPiVsPtKGenPos;
+  delete hDeltaPiVsPtPGen;
+  delete hDeltaPiVsPtPGenNeg;
+  delete hDeltaPiVsPtPGenPos;
+  delete hDeltaPiVsPtEGen;
+  delete hDeltaPiVsPtEGenNeg;
+  delete hDeltaPiVsPtEGenPos;
+  delete hDeltaPiVsPtPiMc;
+  delete hDeltaPiVsPtPiMcNeg;
+  delete hDeltaPiVsPtPiMcPos;
+  delete hDeltaPiVsPtKMc;
+  delete hDeltaPiVsPtKMcNeg;
+  delete hDeltaPiVsPtKMcPos;
+  delete hDeltaPiVsPtPMc;
+  delete hDeltaPiVsPtPMcNeg;
+  delete hDeltaPiVsPtPMcPos;
+  delete hPtPi;
+  delete hPtK;
+  delete hPtP;
+  delete hPrimaryVsPidVsPt;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxData::Init(Int_t nPtBins, Double_t* ptBins)
+{
+  //
+  // Create histograms and functions
+  //
+
+  //
+  // init base class
+  //
+  AliHighPtDeDxBase::Init(nPtBins, ptBins);
+
+  const Int_t nDeltaPiBins   = 60;
+  const Double_t deltaPiLow = -30;
+  const Double_t deltaPiHigh = 30;
+
+  hDeltaPiVsPt = new TH2D("hDeltaPiVsPt", "dE/dx-<dE/dx>_{#pi} vs p_{T}; p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPt->Sumw2();
+  hDeltaPiVsPt->SetDirectory(0);
+  
+  hDeltaPiVsPtNeg = new TH2D("hDeltaPiVsPtNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q < 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtNeg->Sumw2();
+  hDeltaPiVsPtNeg->SetDirectory(0);
+
+  hDeltaPiVsPtPos = new TH2D("hDeltaPiVsPtPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q > 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtPos->Sumw2();
+  hDeltaPiVsPtPos->SetDirectory(0);
+
+
+  //
+  // Generated pions
+  //
+
+  hDeltaPiVsPtPiGen = new TH2D("hDeltaPiVsPtPiGen", "dE/dx-<dE/dx>_{#pi} vs p_{T} (#pi gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtPiGen->Sumw2();
+  hDeltaPiVsPtPiGen->SetDirectory(0);
+
+  hDeltaPiVsPtPiGenNeg = new TH2D("hDeltaPiVsPtPiGenNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q < 0) (#pi gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtPiGenNeg->Sumw2();
+  hDeltaPiVsPtPiGenNeg->SetDirectory(0);
+
+  hDeltaPiVsPtPiGenPos = new TH2D("hDeltaPiVsPtPiGenPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q > 0) (#pi gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtPiGenPos->Sumw2();
+  hDeltaPiVsPtPiGenPos->SetDirectory(0);
+
+  //
+  // Generated kaons
+  //
+
+  hDeltaPiVsPtKGen = new TH2D("hDeltaPiVsPtKGen", "dE/dx-<dE/dx>_{#pi} vs p_{T} (K gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtKGen->Sumw2();
+  hDeltaPiVsPtKGen->SetDirectory(0);
+
+  hDeltaPiVsPtKGenNeg = new TH2D("hDeltaPiVsPtKGenNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q < 0) (K gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtKGenNeg->Sumw2();
+  hDeltaPiVsPtKGenNeg->SetDirectory(0);
+
+  hDeltaPiVsPtKGenPos = new TH2D("hDeltaPiVsPtKGenPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q > 0) (K gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtKGenPos->Sumw2();
+  hDeltaPiVsPtKGenPos->SetDirectory(0);
+
+  //
+  // Generated protons
+  //
+
+  hDeltaPiVsPtPGen = new TH2D("hDeltaPiVsPtPGen", "dE/dx-<dE/dx>_{#pi} vs p_{T} (p gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtPGen->Sumw2();
+  hDeltaPiVsPtPGen->SetDirectory(0);
+
+  hDeltaPiVsPtPGenNeg = new TH2D("hDeltaPiVsPtPGenNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q < 0) (p gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtPGenNeg->Sumw2();
+  hDeltaPiVsPtPGenNeg->SetDirectory(0);
+
+  hDeltaPiVsPtPGenPos = new TH2D("hDeltaPiVsPtPGenPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q > 0) (p gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtPGenPos->Sumw2();
+  hDeltaPiVsPtPGenPos->SetDirectory(0);
+
+  //
+  // Generated electrons
+  //
+
+  hDeltaPiVsPtEGen = new TH2D("hDeltaPiVsPtEGen", "dE/dx-<dE/dx>_{#pi} vs p_{T} (e gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtEGen->Sumw2();
+  hDeltaPiVsPtEGen->SetDirectory(0);
+
+  hDeltaPiVsPtEGenNeg = new TH2D("hDeltaPiVsPtEGenNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q < 0) (e gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtEGenNeg->Sumw2();
+  hDeltaPiVsPtEGenNeg->SetDirectory(0);
+
+  hDeltaPiVsPtEGenPos = new TH2D("hDeltaPiVsPtEGenPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (q > 0) (e gen); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                         nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+  hDeltaPiVsPtEGenPos->Sumw2();
+  hDeltaPiVsPtEGenPos->SetDirectory(0);
+
+  //
+  // MC
+  //
+  if(fIsMc) {
+    hDeltaPiVsPtPiMc = new TH2D("hDeltaPiVsPtPiMc", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                               nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtPiMc->Sumw2();
+    hDeltaPiVsPtPiMc->SetDirectory(0);
+
+    hDeltaPiVsPtPiMcNeg = new TH2D("hDeltaPiVsPtPiMcNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC) (q < 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                               nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtPiMcNeg->Sumw2();
+    hDeltaPiVsPtPiMcNeg->SetDirectory(0);
+
+    hDeltaPiVsPtPiMcPos = new TH2D("hDeltaPiVsPtPiMcPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC) (q > 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                               nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtPiMcPos->Sumw2();
+    hDeltaPiVsPtPiMcPos->SetDirectory(0);
+    
+    hDeltaPiVsPtKMc = new TH2D("hDeltaPiVsPtKMc", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                              nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtKMc->Sumw2();
+    hDeltaPiVsPtKMc->SetDirectory(0);
+
+    hDeltaPiVsPtKMcNeg = new TH2D("hDeltaPiVsPtKMcNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC) (q < 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                               nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtKMcNeg->Sumw2();
+    hDeltaPiVsPtKMcNeg->SetDirectory(0);
+
+    hDeltaPiVsPtKMcPos = new TH2D("hDeltaPiVsPtKMcPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC) (q > 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                               nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtKMcPos->Sumw2();
+    hDeltaPiVsPtKMcPos->SetDirectory(0);
+    
+    hDeltaPiVsPtPMc = new TH2D("hDeltaPiVsPtPMc", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                              nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtPMc->Sumw2();
+    hDeltaPiVsPtPMc->SetDirectory(0);
+
+    hDeltaPiVsPtPMcNeg = new TH2D("hDeltaPiVsPtPMcNeg", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC) (q < 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                               nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtPMcNeg->Sumw2();
+    hDeltaPiVsPtPMcNeg->SetDirectory(0);
+
+    hDeltaPiVsPtPMcPos = new TH2D("hDeltaPiVsPtPMcPos", "dE/dx-<dE/dx>_{#pi} vs p_{T} (MC) (q > 0); p_{T} [GeV/c]; dE/dx - <dE/dx>_{pi}",
+                               nPtBins, ptBins, nDeltaPiBins, deltaPiLow, deltaPiHigh);
+    hDeltaPiVsPtPMcPos->Sumw2();
+    hDeltaPiVsPtPMcPos->SetDirectory(0);
+
+    
+    const Int_t nPidBins = 7;
+    const Double_t pidBinSize = 1;
+    Double_t pidBins[nPidBins+1];
+
+    for(Int_t i = 0; i <= nPidBins; i++) {
+
+      pidBins[i] = pidBinSize*i - 0.5;
+    }
+
+    const Int_t nPrimaryBins = 2;
+    const Double_t primaryBinSize = 1;
+    Double_t primaryBins[nPrimaryBins+1];
+
+    for(Int_t i = 0; i <= nPrimaryBins; i++) {
+      
+      primaryBins[i] = primaryBinSize*i - 0.5;
+    }
+  
+    hPrimaryVsPidVsPt = new TH3D("hPrimaryVsPidVsPt", "primary status vs pid vs Pt; p_{T} [GeV/c]; Pid; Primary status", 
+                                nPtBins, ptBins, nPidBins, pidBins, nPrimaryBins, primaryBins);
+  }
+}
+
+//_________________________________________________________
+void AliHighPtDeDxData::FillTrackInfo(Float_t weight) 
+{
+  AliHighPtDeDxBase::FillTrackInfo(weight);
+  
+  const Double_t dedxPi  = fDeDxPi->Eval(fTrackP);
+  const Double_t sigmaPi = fSigmaDeDx->Eval(dedxPi);
+  
+  const Double_t dedxK   = fDeDxK->Eval(fTrackP);
+  const Double_t sigmaK  = fSigmaDeDx->Eval(dedxK);
+  
+  const Double_t dedxP   = fDeDxP->Eval(fTrackP);
+  const Double_t sigmaP  = fSigmaDeDx->Eval(dedxP);
+
+  const Double_t dedxE   = fDeDxE->Eval(fTrackP);
+  const Double_t sigmaE  = fSigmaDeDx->Eval(dedxE);
+  
+  hDeltaPiVsPt->Fill(fTrackPt, fTrackDeDx-dedxPi);
+  if(fTrackCharge<0)
+    hDeltaPiVsPtNeg->Fill(fTrackPt, fTrackDeDx-dedxPi);
+  else
+    hDeltaPiVsPtPos->Fill(fTrackPt, fTrackDeDx-dedxPi);
+  
+  // Fill MC info
+  if(fIsMc) {
+    
+    hPrimaryVsPidVsPt->Fill(fTrackPt, fTrackPidMc, fTrackPrimaryMc); 
+    switch (fTrackPidMc) {
+      
+    case 1: // pion
+      hDeltaPiVsPtPiMc->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      if(fTrackCharge<0)
+       hDeltaPiVsPtPiMcNeg->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      else
+       hDeltaPiVsPtPiMcPos->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      break;
+    case 2: // kaon
+      hDeltaPiVsPtKMc->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      if(fTrackCharge<0)
+       hDeltaPiVsPtKMcNeg->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      else
+       hDeltaPiVsPtKMcPos->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      break;
+    case 3: // proton
+      hDeltaPiVsPtPMc->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      if(fTrackCharge<0)
+       hDeltaPiVsPtPMcNeg->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      else
+       hDeltaPiVsPtPMcPos->Fill(fTrackPt, fTrackDeDx-dedxPi, weight);
+      break;
+    default:
+      break;
+    }
+  }
+
+  
+  for(Int_t i = 0; i< 10; i++) {
+
+    const Double_t piShape = gRandom->Gaus(0, sigmaPi);
+    const Double_t kShape  = gRandom->Gaus(dedxK - dedxPi, sigmaK);
+    const Double_t pShape  = gRandom->Gaus(dedxP - dedxPi, sigmaP);
+    const Double_t eShape  = gRandom->Gaus(dedxE - dedxPi, sigmaE);
+    hDeltaPiVsPtPiGen->Fill(fTrackPt, piShape);
+    hDeltaPiVsPtKGen->Fill(fTrackPt, kShape);
+    hDeltaPiVsPtPGen->Fill(fTrackPt, pShape);
+    hDeltaPiVsPtEGen->Fill(fTrackPt, eShape);
+    if(fTrackCharge<0) {
+
+      hDeltaPiVsPtPiGenNeg->Fill(fTrackPt, piShape);
+      hDeltaPiVsPtKGenNeg->Fill(fTrackPt, kShape);
+      hDeltaPiVsPtPGenNeg->Fill(fTrackPt, pShape);
+      hDeltaPiVsPtEGenNeg->Fill(fTrackPt, eShape);
+    } else {
+      
+      hDeltaPiVsPtPiGenPos->Fill(fTrackPt, piShape);
+      hDeltaPiVsPtKGenPos->Fill(fTrackPt, kShape);
+      hDeltaPiVsPtPGenPos->Fill(fTrackPt, pShape);
+      hDeltaPiVsPtEGenPos->Fill(fTrackPt, eShape);
+    }
+  }
+}
+
+TH2D* AliHighPtDeDxData::GetHistDeltaPiVsPt(Int_t pid, Int_t charge)
+{
+  switch (pid) {
+       
+  case 0:
+    if(charge==0)
+      return hDeltaPiVsPt;
+    else if(charge<0)
+      return hDeltaPiVsPtNeg;
+    else
+      return hDeltaPiVsPtPos;
+    break;
+  case 1:
+    if(charge==0)
+      return hDeltaPiVsPtPiGen;
+    else if(charge<0)
+      return hDeltaPiVsPtPiGenNeg;
+    else
+      return hDeltaPiVsPtPiGenPos;
+    break;
+  case 2:
+    if(charge==0)
+      return hDeltaPiVsPtKGen;
+    else if(charge<0)
+      return hDeltaPiVsPtKGenNeg;
+    else
+      return hDeltaPiVsPtKGenPos;
+    break;
+  case 3:
+    if(charge==0)
+      return hDeltaPiVsPtPGen;
+    else if(charge<0)
+      return hDeltaPiVsPtPGenNeg;
+    else
+      return hDeltaPiVsPtPGenPos;
+    break;
+  case 4:
+    if(charge==0)
+      return hDeltaPiVsPtEGen;
+    else if(charge<0)
+      return hDeltaPiVsPtEGenNeg;
+    else
+      return hDeltaPiVsPtEGenPos;
+    break;
+  default:
+    cout << "PID: " << pid << " not found" << endl;
+    break;
+  }
+  return 0;
+}
+
+TH2D* AliHighPtDeDxData::GetHistDeltaPiVsPtMc(Int_t pid, Int_t charge)
+{
+  switch (pid) {
+       
+  case 1:
+    if(charge==0)
+      return hDeltaPiVsPtPiMc;
+    else if(charge<0)
+      return hDeltaPiVsPtPiMcNeg;
+    else
+      return hDeltaPiVsPtPiMcPos;
+    break;
+  case 2:
+    if(charge==0)
+      return hDeltaPiVsPtKMc;
+    else if(charge<0)
+      return hDeltaPiVsPtKMcNeg;
+    else
+      return hDeltaPiVsPtKMcPos;
+    break;
+  case 3:
+    if(charge==0)
+      return hDeltaPiVsPtPMc;
+    else if(charge<0)
+      return hDeltaPiVsPtPMcNeg;
+    else
+      return hDeltaPiVsPtPMcPos;
+    break;
+  default:
+    cout << "PID: " << pid << " not found" << endl;
+    break;
+  }
+  return 0;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxData.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxData.h
new file mode 100644 (file)
index 0000000..c17cafb
--- /dev/null
@@ -0,0 +1,79 @@
+#ifndef ALIHIGHPTDEDXDATA_H
+#define ALIHIGHPTDEDXDATA_H
+
+#include "AliHighPtDeDxBase.h"
+
+class AliHighPtDeDxData : public AliHighPtDeDxBase {
+ public:
+  AliHighPtDeDxData(); // default constructor  
+  AliHighPtDeDxData(const char* name, const char* title); // named constructor  
+  virtual ~AliHighPtDeDxData(); // default destructor
+
+  //  virtual void Init(Int_t nPtBins, Double_t* ptBins);
+  //  virtual void FillTrackInfo(Float_t weight=1);
+  
+  TH2D* GetHistDeltaPiVsPt(Int_t pid, Int_t charge);
+  TH2D* GetHistDeltaPiVsPtMc(Int_t pid, Int_t charge);
+
+  void SetPionDeDxFunction(TF1* piFunc)     { fDeDxPi    = piFunc; }
+  void SetKaonDeDxFunction(TF1* kFunc)      { fDeDxK     = kFunc; }
+  void SetProtonDeDxFunction(TF1* pFunc)    { fDeDxP     = pFunc; }
+  void SetElectronDeDxFunction(TF1* eFunc)  { fDeDxE     = eFunc; }
+  void SetSigmaDeDxFunction(TF1* sigmaFunc) { fSigmaDeDx = sigmaFunc; }
+
+  void Init(Int_t nPtBins, Double_t* ptBins);
+  void FillTrackInfo(Float_t weight);
+
+ private:
+
+  TF1*   fDeDxPi;          //! dE/dx vs p for pions
+  TF1*   fDeDxK;           //! dE/dx vs p for kaons
+  TF1*   fDeDxP;           //! dE/dx vs p for protons
+  TF1*   fDeDxE;           //! dE/dx vs p for electrons
+  TF1*   fSigmaDeDx;       //! sigma dE/dx vs ncl
+
+  // histograms
+  TH2D* hDeltaPiVsPt;      // Delta pi vs pt (both q)
+  TH2D* hDeltaPiVsPtNeg;   // Delta pi vs pt (q < 0)
+  TH2D* hDeltaPiVsPtPos;   // Delta pi vs pt (q > 0)
+
+  TH2D* hDeltaPiVsPtPiGen;      // Delta pi vs pt (both q) - generated pions
+  TH2D* hDeltaPiVsPtPiGenNeg;   // Delta pi vs pt (q < 0)  - generated pions
+  TH2D* hDeltaPiVsPtPiGenPos;   // Delta pi vs pt (q > 0)  - generated pions
+
+  TH2D* hDeltaPiVsPtKGen;       // Delta pi vs pt (both q) - generated kaons
+  TH2D* hDeltaPiVsPtKGenNeg;    // Delta pi vs pt (q < 0)  - generated kaons
+  TH2D* hDeltaPiVsPtKGenPos;    // Delta pi vs pt (q > 0)  - generated kaons
+
+  TH2D* hDeltaPiVsPtPGen;       // Delta pi vs pt (both q) - generated protons
+  TH2D* hDeltaPiVsPtPGenNeg;    // Delta pi vs pt (q < 0)  - generated protons
+  TH2D* hDeltaPiVsPtPGenPos;    // Delta pi vs pt (q > 0)  - generated protons
+
+  TH2D* hDeltaPiVsPtEGen;       // Delta pi vs pt (both q) - generated electrons
+  TH2D* hDeltaPiVsPtEGenNeg;    // Delta pi vs pt (q < 0)  - generated electrons
+  TH2D* hDeltaPiVsPtEGenPos;    // Delta pi vs pt (q > 0)  - generated electrons
+
+  TH2D* hDeltaPiVsPtPiMc;     // Delta pi vs pt for MC pions
+  TH2D* hDeltaPiVsPtPiMcNeg;  // Delta pi vs pt for MC pions
+  TH2D* hDeltaPiVsPtPiMcPos;  // Delta pi vs pt for MC pions
+  TH2D* hDeltaPiVsPtKMc;      // Delta pi vs pt for MC Kaons
+  TH2D* hDeltaPiVsPtKMcNeg;   // Delta pi vs pt for MC Kaons
+  TH2D* hDeltaPiVsPtKMcPos;   // Delta pi vs pt for MC Kaons
+  TH2D* hDeltaPiVsPtPMc;      // Delta pi vs pt for MC protons
+  TH2D* hDeltaPiVsPtPMcNeg;   // Delta pi vs pt for MC protons
+  TH2D* hDeltaPiVsPtPMcPos;   // Delta pi vs pt for MC protons
+  TH1D* hPtPi;             // pt distribution for pions (from fits)
+  TH1D* hPtK;              // pt distribution for kaons (from fits)
+  TH1D* hPtP;              // pt distribution for protons (from fits)
+  TH3D* hPrimaryVsPidVsPt; // pt disrtibutions for efficiency
+  /* TH1D* hPtPiMc; */
+  /* TH1D* hPtKMc; */
+  /* TH1D* hPtPMc; */
+  
+  //  void Print(Option_t* option) const;
+  
+  ClassDef(AliHighPtDeDxData, 4)  // AliHighPtDeDxData information
+    };
+
+#endif
+       
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxMc.cxx b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxMc.cxx
new file mode 100644 (file)
index 0000000..cb4892f
--- /dev/null
@@ -0,0 +1,359 @@
+#include "AliHighPtDeDxMc.h"
+
+#ifndef __IOSTREAM__
+#include <iostream>
+#endif
+
+using namespace std;
+
+ClassImp(AliHighPtDeDxMc);
+
+//
+// AliHighPtDeDxMc class
+//
+// This class contains the AliHighPtDeDxMc information 
+//
+
+//_________________________________________________________
+AliHighPtDeDxMc::AliHighPtDeDxMc():
+  AliHighPtDeDxBase(),
+  fTrackChargeMc(0),
+  fTrackEtaMc(-999),
+  fTrackPtMc(-1),
+  hVtxStatusMc(0x0),
+  hNeventsMc(0x0),
+  hNeventsMcTrig(0x0),
+  hPtMc(0x0),
+  hPtMcNeg(0x0),
+  hPtMcPos(0x0),
+  hPtPiMc(0x0),
+  hPtPiMcNeg(0x0),
+  hPtPiMcPos(0x0),
+  hPtKMc(0x0),
+  hPtKMcNeg(0x0),
+  hPtKMcPos(0x0),
+  hPtPMc(0x0),
+  hPtPMcNeg(0x0),
+  hPtPMcPos(0x0),
+  hMeanPtMc(0x0)
+{
+  // default constructor - do not use
+}
+
+//_________________________________________________________
+AliHighPtDeDxMc::AliHighPtDeDxMc(const char* name, const char* title):
+  AliHighPtDeDxBase(name, title),
+  fTrackChargeMc(0),
+  fTrackEtaMc(-999),
+  fTrackPtMc(-1),
+  hVtxStatusMc(0x0),
+  hNeventsMc(0x0),
+  hNeventsMcTrig(0x0),
+  hPtMc(0x0),
+  hPtMcNeg(0x0),
+  hPtMcPos(0x0),
+  hPtPiMc(0x0),
+  hPtPiMcNeg(0x0),
+  hPtPiMcPos(0x0),
+  hPtKMc(0x0),
+  hPtKMcNeg(0x0),
+  hPtKMcPos(0x0),
+  hPtPMc(0x0),
+  hPtPMcNeg(0x0),
+  hPtPMcPos(0x0),
+  hMeanPtMc(0x0)
+{
+  // named constructor
+}
+
+//_________________________________________________________
+AliHighPtDeDxMc::~AliHighPtDeDxMc()
+{
+  delete hVtxStatusMc;
+  delete hNeventsMc;
+  delete hNeventsMcTrig;
+  delete hPtMc;
+  delete hPtMcNeg;
+  delete hPtMcPos;
+  delete hPtPiMc;
+  delete hPtPiMcNeg;
+  delete hPtPiMcPos;
+  delete hPtKMc;
+  delete hPtKMcNeg;
+  delete hPtKMcPos;
+  delete hPtPMc;
+  delete hPtPMcNeg;
+  delete hPtPMcPos;
+  delete hMeanPtMc;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxMc::Init(Int_t nPtBins, Double_t* ptBins)
+{
+  //
+  // Create histograms
+  //
+
+  AliHighPtDeDxBase::Init(nPtBins, ptBins);
+  
+  hVtxStatusMc = new TH1D("hVtxStatus", "Vtx status (MC) - No Vtx = -1, Vtx outside cut = 0, Vtx inside = 1",
+                       3, -1.5, 1.5);
+  hVtxStatusMc->Sumw2();
+  hVtxStatusMc->SetDirectory(0);
+
+  hNeventsMc = new TH1D("hNeventsMc", "N events (Mc vtx) - No Vtx = 0, Vtx OK = 1",
+                       2, 0, 2);
+  hNeventsMc->Sumw2();
+  hNeventsMc->SetDirectory(0);
+
+  hNeventsMcTrig = new TH1D("hNeventsMcTrig", "N events (MC vtx+trigger) - No Vtx = 0, Vtx OK = 1",
+                          2, 0, 2);
+  hNeventsMcTrig->Sumw2();
+  hNeventsMcTrig->SetDirectory(0);
+
+  hPtMc = new TH1D("hPtMc", "p_{T} input spectrum (MC); p_{T} [GeV/c]; Counts",
+                  nPtBins, ptBins);
+  hPtMc->Sumw2();
+  hPtMc->SetDirectory(0);
+
+  hPtMcNeg = new TH1D("hPtMcNeg", "p_{T} input spectrum (MC) (q<0); p_{T} [GeV/c]; Counts",
+                  nPtBins, ptBins);
+  hPtMcNeg->Sumw2();
+  hPtMcNeg->SetDirectory(0);
+
+  hPtMcPos = new TH1D("hPtMcPos", "p_{T} input spectrum (MC) (q>0); p_{T} [GeV/c]; Counts",
+                  nPtBins, ptBins);
+  hPtMcPos->Sumw2();
+  hPtMcPos->SetDirectory(0);
+
+  hPtPiMc = new TH1D("hPtPiMc", "p_{T} input spectrum for pi (MC); p_{T} [GeV/c]; Counts",
+                    nPtBins, ptBins);
+  hPtPiMc->Sumw2();
+  hPtPiMc->SetDirectory(0);
+
+  hPtPiMcNeg = new TH1D("hPtPiMcNeg", "p_{T} input spectrum for pi (MC) (q<0); p_{T} [GeV/c]; Counts",
+                       nPtBins, ptBins);
+  hPtPiMcNeg->Sumw2();
+  hPtPiMcNeg->SetDirectory(0);
+  
+  hPtPiMcPos = new TH1D("hPtPiMcPos", "p_{T} input spectrum for pi (MC) (q>0); p_{T} [GeV/c]; Counts",
+                       nPtBins, ptBins);
+  hPtPiMcPos->Sumw2();
+  hPtPiMcPos->SetDirectory(0);
+
+  hPtKMc = new TH1D("hPtKMc", "p_{T} input spectrum for k (MC); p_{T} [GeV/c]; Counts",
+                    nPtBins, ptBins);
+  hPtKMc->Sumw2();
+  hPtKMc->SetDirectory(0);
+
+  hPtKMcNeg = new TH1D("hPtKMcNeg", "p_{T} input spectrum for k (MC) (q<0); p_{T} [GeV/c]; Counts",
+                       nPtBins, ptBins);
+  hPtKMcNeg->Sumw2();
+  hPtKMcNeg->SetDirectory(0);
+  
+  hPtKMcPos = new TH1D("hPtKMcPos", "p_{T} input spectrum for k (MC) (q>0); p_{T} [GeV/c]; Counts",
+                       nPtBins, ptBins);
+  hPtKMcPos->Sumw2();
+  hPtKMcPos->SetDirectory(0);
+  
+  hPtPMc = new TH1D("hPtPMc", "p_{T} input spectrum for p (MC); p_{T} [GeV/c]; Counts",
+                    nPtBins, ptBins);
+  hPtPMc->Sumw2();
+  hPtPMc->SetDirectory(0);
+
+  hPtPMcNeg = new TH1D("hPtPMcNeg", "p_{T} input spectrum for p (MC) (q<0); p_{T} [GeV/c]; Counts",
+                       nPtBins, ptBins);
+  hPtPMcNeg->Sumw2();
+  hPtPMcNeg->SetDirectory(0);
+  
+  hPtPMcPos = new TH1D("hPtPMcPos", "p_{T} input spectrum for p (MC) (q>0); p_{T} [GeV/c]; Counts",
+                       nPtBins, ptBins);
+  hPtPMcPos->Sumw2();
+  hPtPMcPos->SetDirectory(0);
+
+  hMeanPtMc = new TProfile("hMeanPtMc", "mean p_{T}; p_{T} [GeV/c]; mean p_{T}",
+                          nPtBins, ptBins);
+  hMeanPtMc->SetDirectory(0);
+}
+
+//_________________________________________________________
+Bool_t AliHighPtDeDxMc::TrackAcceptedMc()
+{
+  if(fUseEtaCut && (fTrackEtaMc<fEtaLow || fTrackEtaMc>fEtaHigh))
+    return kFALSE;
+  
+  // only accept hadrons = pi(1), K(2), p(3), other (Sigma+ etc. = 6)
+  if(fTrackPidMc < 1 || fTrackPidMc == 4 || fTrackPidMc == 5 || fTrackPidMc > 6)
+    return kFALSE;
+  
+  return kTRUE;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxMc::FillEventInfo() 
+{
+  //
+  // We require that the MC vtx is withion our vertex range
+  // (fEventVtxStatusMc==1). In this way we have to accept both
+  // fEventVtxStatusMc==0 and fEventVtxStatusMc==1 to take into account
+  // migration effects. 
+  //
+  // The histogram associated with this is hNeventsMc (together with hNevents
+  // in the base class)
+  //
+  // To correct down the "no vtx" events in the data there are two possibilities
+  //
+  // 1) We can use the data fraction between accepted vtx and all vtx. Note
+  // that since the vtx rec efficiency is not constant vs the vtx position we
+  // make a small mistake here, but on the other hand we might be less
+  // sensitive to the MC.
+  //
+  // 2) We can use the MC prediction for estimating the fraction. In this way
+  // we might be have no problems with the slightly varying vtx efficiency,
+  // but we might be more sensitive to the MC.
+  //
+  // The histogram associated with this method is hNeventsMcTrig (together with hNevents
+  // in the base class)
+  //
+  // TO DO: We need to test which is better, e.g., by using PHOJET on PYTHIA
+  // and vice versa.
+  //
+  AliHighPtDeDxBase::FillEventInfo();
+  hVtxStatusMc->Fill(fEventVtxStatus);
+
+  if(fEventVtxStatusMc==1) {
+    if(fEventVtxStatus==-1) { // no vtx class
+      hNeventsMc->Fill(0.5);      
+      if(fEventTrigger)
+       hNeventsMcTrig->Fill(0.5);
+    } else {                  // vtx class
+      hNeventsMc->Fill(1.5);
+      if(fEventTrigger)
+       hNeventsMcTrig->Fill(1.5);
+    }
+  }
+}
+
+
+//_________________________________________________________
+TH1D* AliHighPtDeDxMc::GetPtSpectrum() 
+{
+  TH1D* histSpectrum = dynamic_cast<TH1D*>(hPtMc->Clone("hPtSpectrum"));
+
+  const Double_t nEvents = hNeventsMc->GetBinContent(1) 
+    + hNeventsMc->GetBinContent(2);
+  const Double_t etaRange = fEtaHigh - fEtaLow;
+  
+  histSpectrum->Scale(1.0/etaRange);
+  NormalizePt(histSpectrum);
+  histSpectrum->Scale(1.0/nEvents);
+
+  return histSpectrum;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxMc::NormalizePt(TH1* hist)
+{
+  const Int_t n = hist->GetNbinsX();
+
+  for(Int_t bin = 1; bin <= n; bin++) {
+    
+    const Float_t width = hist->GetXaxis()->GetBinWidth(bin);
+    hist->SetBinError(bin, hist->GetBinError(bin)/width);
+    hist->SetBinContent(bin, hist->GetBinContent(bin)/width);
+  }
+}
+
+
+// //_________________________________________________________
+// void AliHighPtDeDxMc::FillTrackInfo(Float_t weight) 
+// {
+  
+//   AliHighPtDeDxBase::FillTrackInfo(weight);
+  
+//   hPt->Fill(fTrackPt, weight);
+// }
+
+//_________________________________________________________
+void AliHighPtDeDxMc::FillTrackInfoMc(Float_t weight) 
+{
+  
+  hPtMc->Fill(fTrackPtMc, weight);
+  if(fTrackChargeMc<0)
+    hPtMcNeg->Fill(fTrackPtMc, weight);
+  else
+    hPtMcPos->Fill(fTrackPtMc, weight);
+
+  hMeanPtMc->Fill(fTrackPtMc, fTrackPtMc);
+
+  switch (fTrackPidMc) {
+    
+  case 1: // pion
+    hPtPiMc->Fill(fTrackPtMc, weight);
+    if(fTrackChargeMc<0)
+      hPtPiMcNeg->Fill(fTrackPtMc, weight);
+    else
+      hPtPiMcPos->Fill(fTrackPtMc, weight);
+    break;
+  case 2: // kaon
+    hPtKMc->Fill(fTrackPtMc, weight);
+    if(fTrackChargeMc<0)
+      hPtKMcNeg->Fill(fTrackPtMc, weight);
+    else
+      hPtKMcPos->Fill(fTrackPtMc, weight);
+    break;
+  case 3: // proton
+    hPtPMc->Fill(fTrackPtMc, weight);
+    if(fTrackChargeMc<0)
+      hPtPMcNeg->Fill(fTrackPtMc, weight);
+    else
+      hPtPMcPos->Fill(fTrackPtMc, weight);
+    break;
+  default:
+    break;
+  }
+}
+
+TH1D* AliHighPtDeDxMc::GetHistPtMc(Int_t pid, Int_t charge)
+{
+  switch (pid) {
+       
+  case 0:
+    if(charge==0)
+      return hPtMc;
+    else if(charge<0)
+      return hPtMcNeg;
+    else
+      return hPtMcPos;
+    break;
+  case 1:
+    if(charge==0)
+      return hPtPiMc;
+    else if(charge<0)
+      return hPtPiMcNeg;
+    else
+      return hPtPiMcPos;
+    break;
+  case 2:
+    if(charge==0)
+      return hPtKMc;
+    else if(charge<0)
+      return hPtKMcNeg;
+    else
+      return hPtKMcPos;
+    break;
+  case 3:
+    if(charge==0)
+      return hPtPMc;
+    else if(charge<0)
+      return hPtPMcNeg;
+    else
+      return hPtPMcPos;
+    break;
+  default:
+    cout << "PID: " << pid << " not found" << endl;
+    break;
+  }
+  return 0;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxMc.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxMc.h
new file mode 100644 (file)
index 0000000..d3f6324
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef ALIHIGHPTDEDXMC_H
+#define ALIHIGHPTDEDXMC_H
+
+#include "AliHighPtDeDxBase.h"
+
+class AliHighPtDeDxMc : public AliHighPtDeDxBase {
+ public:
+  AliHighPtDeDxMc(); // default constructor  
+  AliHighPtDeDxMc(const char* name, const char* title); // named constructor  
+  virtual ~AliHighPtDeDxMc(); // default destructor
+  
+  TH1D* GetPtSpectrum(); 
+
+  virtual void SetTrackChargeMc(Int_t value)  { fTrackChargeMc = value; }
+  virtual void SetTrackEtaMc(Double_t value)  { fTrackEtaMc = value; }
+  virtual void SetTrackPtMc(Double_t value)   { fTrackPtMc = value; } 
+  
+  virtual void Init(Int_t nPtBins, Double_t* ptBins);
+  virtual Bool_t TrackAcceptedMc();
+  virtual void FillEventInfo();
+  virtual void FillTrackInfoMc(Float_t weight=1);
+  
+  TH1D* GetHistNeventsMc()     { return hNeventsMc; };
+  TH1D* GetHistNeventsMcTrig() { return hNeventsMcTrig; };
+  TH1D* GetHistPtMc(Int_t pid, Int_t charge);
+  TProfile* GetHistMeanPtMc()  { return hMeanPtMc; };
+
+ protected:
+  // Actual values for the event and track
+  Int_t    fTrackChargeMc;       //! charge (+1 or -1)
+  Double_t fTrackEtaMc;          //! eta
+  Double_t fTrackPtMc;           //! pt
+
+ private:
+  void NormalizePt(TH1* hist);
+
+  // histograms
+  TH1D*     hVtxStatusMc;      // vtx status (all triggers) 
+  TH1D*     hNeventsMc;        // Nevents (all triggers) - based on MC vtx 
+  TH1D*     hNeventsMcTrig;    // Nevents (all triggers) - based on MC vtx + trig
+  TH1D*     hPtMc;             // pt input distribution
+  TH1D*     hPtMcNeg;          // pt input distribution (q<0)
+  TH1D*     hPtMcPos;          // pt input distribution (q>0)
+  TH1D*     hPtPiMc;           // pt input distribution
+  TH1D*     hPtPiMcNeg;        // pt input distribution (q<0)
+  TH1D*     hPtPiMcPos;        // pt input distribution (q>0)
+  TH1D*     hPtKMc;            // pt input distribution
+  TH1D*     hPtKMcNeg;         // pt input distribution (q<0)
+  TH1D*     hPtKMcPos;         // pt input distribution (q>0)
+  TH1D*     hPtPMc;            // pt input distribution
+  TH1D*     hPtPMcNeg;         // pt input distribution (q<0)
+  TH1D*     hPtPMcPos;         // pt input distribution (q>0)
+  TProfile* hMeanPtMc;         // mean pt input distribution
+    
+  ClassDef(AliHighPtDeDxMc, 4)  // AliHighPtDeDxMc information
+    };
+
+#endif
+       
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxSpectra.cxx b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxSpectra.cxx
new file mode 100644 (file)
index 0000000..19f3ec3
--- /dev/null
@@ -0,0 +1,285 @@
+#include "AliHighPtDeDxSpectra.h"
+
+#ifndef __IOSTREAM__
+#include <iostream>
+#endif
+
+using namespace std;
+
+ClassImp(AliHighPtDeDxSpectra);
+
+//
+// AliHighPtDeDxSpectra class
+//
+// This class contains the AliHighPtDeDxSpectra information 
+//
+
+//_________________________________________________________
+AliHighPtDeDxSpectra::AliHighPtDeDxSpectra():
+  TNamed(),
+  fDebugLevel(0),
+  fUseMcNoVtxCorrection(kTRUE),
+  fUseFittedEfficiency(kTRUE),
+  fUseBinCorrection(kTRUE),
+  fNevents(0),
+  hPt(0x0),
+  hNevents(0x0),
+  hTriggerEfficiency(0x0),
+  hEfficiency(0x0),
+  hMcNoVtxCorrection(0x0),
+  hBinCorrection(0x0),
+  hMeanPt(0x0),
+  fEfficiency(0x0),
+  fBinFit(0x0)
+{
+  // default constructor - do not use
+}
+
+//_________________________________________________________
+AliHighPtDeDxSpectra::AliHighPtDeDxSpectra(const char* name, const char* title):
+  TNamed(name, title),
+  fDebugLevel(0),
+  fUseMcNoVtxCorrection(kTRUE),
+  fUseFittedEfficiency(kTRUE),
+  fUseBinCorrection(kTRUE),
+  fNevents(0),
+  hPt(0x0),
+  hNevents(0x0),
+  hTriggerEfficiency(0x0),
+  hEfficiency(0x0),
+  hMcNoVtxCorrection(0x0),
+  hBinCorrection(0x0),
+  hMeanPt(0x0),
+  fEfficiency(0x0),
+  fBinFit(0x0)
+{
+  // named constructor
+}
+
+//_________________________________________________________
+AliHighPtDeDxSpectra::~AliHighPtDeDxSpectra()
+{
+  // histograms
+  delete hPt;                // pt spectrum for 
+  delete hNevents;           // events
+  delete hTriggerEfficiency; // trigger efficency
+  delete hEfficiency;        // track correction
+  delete hMcNoVtxCorrection;
+  delete hBinCorrection;     // bin correction
+  delete hMeanPt;            // mean pt of data
+  delete fEfficiency;
+  delete fBinFit;
+}
+
+//_________________________________________________________
+TH1D* AliHighPtDeDxSpectra::ConstructBinCorrection(TH1D* histPt, TProfile* histMeanPt)
+{
+  TH1D* histCorr = dynamic_cast<TH1D*>(histPt->Clone("hBinCorrection"));
+  histCorr->SetDirectory(0);
+  histCorr->Reset();
+
+  fBinFit = new TF1("fBinFit", "[0]*(1.0+x/[1])**(-[2])", 0.0, 50);
+  fBinFit->SetParameters(6, 0.5, 4);
+  histPt->Fit(fBinFit, "0N", "", 3.0, 50.0);
+  
+  const Int_t nPtBins = histPt->GetNbinsX();
+  for(Int_t bin = 1; bin < nPtBins; bin++) {
+    
+    Float_t meanPt = histMeanPt->GetBinContent(bin);
+    Float_t binPt  = histPt->GetXaxis()->GetBinCenter(bin);
+    Float_t correction = 0;
+    if(meanPt>0)
+      correction = fBinFit->Eval(meanPt)/fBinFit->Eval(binPt); 
+    if(fDebugLevel>5)
+      cout << "<pT>: " << meanPt << ", bin pT: " << binPt << ", correction: " << correction << endl;
+    histCorr->SetBinContent(bin, correction);
+    histCorr->SetBinError(bin, 0.0);
+  }
+
+  return histCorr;
+}
+
+//_________________________________________________________
+TH1D* AliHighPtDeDxSpectra::ConstructTriggerEfficiency(AliHighPtDeDxMc* mc)
+{
+  TH1D* histEff = dynamic_cast<TH1D*>(mc->GetHistNeventsMcTrig()->Clone("hTriggerEfficiency"));
+  histEff->SetDirectory(0);
+  histEff->Divide(histEff,  mc->GetHistNeventsMc(), 1, 1, "B");
+
+  if(fDebugLevel>1) {
+    
+    cout << "Trigger efficiency: " 
+        << Form("%.1f %% (No vtx), %.1f %% (vtx)", 
+                Float_t(histEff->GetBinContent(1)*100.0),
+                Float_t(histEff->GetBinContent(2)*100.0))
+        << endl;
+  }
+    
+  return histEff;
+}
+
+//_________________________________________________________
+TH1D* AliHighPtDeDxSpectra::GetEventCount(AliHighPtDeDxData* data, AliHighPtDeDxMc* mc)
+{
+  // Correct
+  TH1D* histEvents = dynamic_cast<TH1D*>(data->GetHistNevents()->Clone("hNevents"));
+  
+  Double_t noVtx = histEvents->GetBinContent(1);
+  //  Double_t vtx   = histEvents->GetBinContent(2);
+  Double_t vtx   = histEvents->GetBinContent(2);
+
+  if(fDebugLevel>1) {
+    cout << "BEFORE correction: " << noVtx << " (no vtx), " << vtx << " (vtx)" << endl;
+  }
+
+  if(!fUseMcNoVtxCorrection) {
+
+    TH1D* histVtxStatus = data->GetHistVtxStatus();
+    
+    Double_t outsideCut = histVtxStatus->GetBinContent(2);
+    Double_t insideCut  = histVtxStatus->GetBinContent(3);
+    Double_t ratio      = insideCut/(insideCut+outsideCut);
+    
+    if(fDebugLevel>1) {
+      cout << "Inside/Outside/Ratio(I/(I+O)):" << insideCut << "/" << outsideCut << "/" << ratio*100 << " %%" << endl;
+    }
+    
+    noVtx *= ratio;
+    histEvents->SetBinContent(1, noVtx);
+  
+    if(fDebugLevel>1) {
+      cout << ", AFTER correction: " << noVtx << endl;
+    }
+  } else {
+
+    hMcNoVtxCorrection = dynamic_cast<TH1D*>(mc->GetHistNeventsMcTrig()->Clone("hMcEventCorrection"));
+    hMcNoVtxCorrection->Divide(mc->GetHistNevents());
+
+    Double_t scaleNoVtx = hMcNoVtxCorrection->GetBinContent(1);
+    Double_t scaleVtx   = hMcNoVtxCorrection->GetBinContent(2);
+
+    if(fDebugLevel>1) {
+      cout << "Mc event correction: " 
+          << Form("%.1f %% (No vtx), %.1f %% (vtx - not corrected)", 
+                  Float_t(scaleNoVtx*100.0),
+                  Float_t(scaleVtx*100.0))
+          << endl;
+    }
+
+    noVtx *= scaleNoVtx;
+    //    vtx  *= scaleVtx;
+    histEvents->SetBinContent(1, noVtx);    
+    //    histEvents->SetBinContent(2, vtx);    
+  }
+  
+  if(fDebugLevel>1) {
+    cout << "AFTER correction: " << noVtx << " (no vtx), " << vtx << " (vtx)" << endl;
+  }
+
+  return histEvents;
+}
+
+
+//_________________________________________________________
+TH1D* AliHighPtDeDxSpectra::ConstructTrackCorrection(AliHighPtDeDxMc* mc)
+{
+  TH1D* histEff = dynamic_cast<TH1D*>(mc->GetHistPt()->Clone("hEfficiency"));
+  histEff->SetDirectory(0);
+  histEff->Divide(histEff,  mc->GetHistPtMc(0, 0), 1, 1, "B");
+  //  histEff->Divide(histEff,  mc->GetHistPtMc());
+  
+  return histEff;
+}
+
+//_________________________________________________________
+TF1* AliHighPtDeDxSpectra::FitEfficiency(TH1D* histEff)
+{
+  TF1* func = new TF1("fEfficiency", "[0]*(1-[1]/x)", 0, 50);
+  
+  histEff->Fit(func, "0N", "", 3, 50); 
+
+  return func;
+}
+
+//_________________________________________________________
+void AliHighPtDeDxSpectra::GetCorrectedSpectra(AliHighPtDeDxData* data,
+                                              AliHighPtDeDxMc* mc)
+{
+  //
+  // Noralize spectra
+  //
+
+  //
+  // Extract the corrected number of events
+  //
+  Double_t fNeventsVtx = data->GetHistNevents()->GetEntries() - data->GetHistNevents()->GetBinContent(1);
+  // hNevents = GetEventCount(data, mc);
+  // hTriggerEfficiency = ConstructTriggerEfficiency(mc);
+  // hNevents->Divide(hTriggerEfficiency);
+
+  // if(fDebugLevel>1) {
+  //   cout << "Events after efficiency: " << hNevents->GetBinContent(1)
+  //    << " (no vtx) " << hNevents->GetBinContent(2) << " (vtx)" << endl;
+  // }
+
+  //  fNevents = hNevents->GetBinContent(1) + hNevents->GetBinContent(2);
+  fNevents = fNeventsVtx/0.85;
+
+  //
+  // Extract the track correction
+  //
+  hEfficiency = ConstructTrackCorrection(mc);
+
+  hPt = dynamic_cast<TH1D*>(data->GetHistPt()->Clone("hPt"));
+  hPt->SetDirectory(0);
+
+  Double_t etaRange = data->GetEtaHigh() - data->GetEtaLow();
+
+  if(fDebugLevel>1) {
+    cout << "N events (corrected): " << fNevents << endl;
+    cout << "Eta range: " << etaRange << endl;
+
+    cout << endl << "fNeventsVtx(" << fNeventsVtx << ")/fNevents(" << fNevents << ") = " 
+        << fNeventsVtx/fNevents*100 << " %" << endl << endl;
+  }
+
+  hPt->Scale(1.0/etaRange);
+  NormalizePt(hPt);
+  hPt->Scale(1.0/fNevents);
+  
+  if (fUseFittedEfficiency) {
+
+    fEfficiency = FitEfficiency(hEfficiency);
+    hPt->Divide(fEfficiency);
+  } else
+    hPt->Divide(hEfficiency);
+
+  if (fUseBinCorrection) {
+
+    hBinCorrection = ConstructBinCorrection(hPt, data->GetHistMeanPt());
+    hPt->Divide(hBinCorrection);
+  }
+}
+
+//_________________________________________________________
+void AliHighPtDeDxSpectra::NormalizePt(TH1* hist)
+{
+  const Int_t n = hist->GetNbinsX();
+
+  for(Int_t bin = 1; bin <= n; bin++) {
+    
+    const Float_t width = hist->GetXaxis()->GetBinWidth(bin);
+    hist->SetBinError(bin, hist->GetBinError(bin)/width);
+    hist->SetBinContent(bin, hist->GetBinContent(bin)/width);
+  }
+}
+
+
+// //_________________________________________________________
+// void AliHighPtDeDxSpectra::FillTrackInfo(Float_t weight) 
+// {
+
+//   AliHighPtDeDxBase::FillTrackInfo(weight);
+  
+//   hPt->Fill(fTrackPt, weight);
+// }
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxSpectra.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/AliHighPtDeDxSpectra.h
new file mode 100644 (file)
index 0000000..0690390
--- /dev/null
@@ -0,0 +1,69 @@
+#ifndef ALIHIGHPTDEDXSPECTRA_H
+#define ALIHIGHPTDEDXSPECTRA_H
+
+#include <TNamed.h>
+#include <TH1.h>
+
+#include "AliHighPtDeDxData.h"
+#include "AliHighPtDeDxMc.h"
+
+class AliHighPtDeDxSpectra : public TNamed {
+ public:
+  AliHighPtDeDxSpectra(); // default constructor  
+  AliHighPtDeDxSpectra(const char* name, const char* title); // named constructor  
+  virtual ~AliHighPtDeDxSpectra(); // default destructor
+
+  void GetCorrectedSpectra(AliHighPtDeDxData* data,
+                          AliHighPtDeDxMc* mc);
+
+  void SetUseMcNoVtxCorrection(Bool_t value) { fUseMcNoVtxCorrection = value; };
+  void SetUseFittedEfficiency(Bool_t value) { fUseFittedEfficiency = value; };
+  void SetUseBinCorrection(Bool_t value) { fUseBinCorrection = value; };
+  void SetDebugLevel(Int_t value)  { fDebugLevel = value; };
+
+  Double_t GetNevents()        { return fNevents; };
+  TH1D* GetHistPt()            { return hPt; };
+  TH1D* GetHistNevents()       { return hNevents; };
+  TH1D* GetHistTriggerEfficiency() { return hTriggerEfficiency; };
+  TH1D* GetHistEfficiency()    { return hEfficiency; };
+  TH1D* GetHistBinCorrection() { return hBinCorrection; };
+  TH1D* GetHistMcNoVtxCorrection() { return hMcNoVtxCorrection; };
+  TH1D* GetHistMeanPt()        { return hMeanPt; };
+  TF1*  GetFuncEfficiency()    { return fEfficiency; };
+  TF1*  GetFuncBinFit()        { return fBinFit; };
+
+
+ private:
+
+  TH1D* ConstructBinCorrection(TH1D* histPt, TProfile* histMeanPt);
+  TH1D* ConstructTriggerEfficiency(AliHighPtDeDxMc* mc);
+  TH1D* GetEventCount(AliHighPtDeDxData* data, AliHighPtDeDxMc* mc);
+  TH1D* ConstructTrackCorrection(AliHighPtDeDxMc* mc);
+  TF1*  FitEfficiency(TH1D* histEff);
+  void NormalizePt(TH1* hist);
+
+  // members
+  Int_t    fDebugLevel;     // debug level
+  Bool_t   fUseMcNoVtxCorrection; 
+  Bool_t   fUseFittedEfficiency; 
+  Bool_t   fUseBinCorrection; 
+  // use MC to correct down the novtx fraction outside the vtx cut
+  // see AliHighPtDeDxMc::FillEventInfo() for details
+  Double_t fNevents;        // corrected number of events
+
+  // histograms
+  TH1D* hPt;                // pt spectrum for 
+  TH1D* hNevents;           // events
+  TH1D* hTriggerEfficiency; // trigger efficency
+  TH1D* hEfficiency;        // track correction
+  TH1D* hMcNoVtxCorrection; // mc no vtx correction
+  TH1D* hBinCorrection;     // bin correction
+  TH1D* hMeanPt;            // mean pt of data
+  TF1*  fEfficiency;        // fitted efficiency
+  TF1*  fBinFit;            // fit used for bin correction
+  
+  ClassDef(AliHighPtDeDxSpectra, 1)  // AliHighPtDeDxSpectra information
+    };
+
+#endif
+       
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/Include.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/Include.h
new file mode 100644 (file)
index 0000000..f6de390
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef ALIHIGHPTDEDXBASE_H
+#include "AliHighPtDeDxBase.h"
+#endif
+
+#ifndef ALIHIGHPTDEDXCALIB_H
+#include "AliHighPtDeDxCalib.h"
+#endif
+
+#ifndef ALIHIGHPTDEDXDATA_H
+#include "AliHighPtDeDxData.h"
+#endif
+
+#ifndef ALIHIGHPTDEDXMC_H
+#include "AliHighPtDeDxMc.h"
+#endif
+
+#ifndef ALIHIGHPTDEDXSPECTRA_H
+#include "AliHighPtDeDxSpectra.h"
+#endif
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/LinkDef.h b/PWGLF/SPECTRA/IdentifiedHighPt/lib/LinkDef.h
new file mode 100644 (file)
index 0000000..fda3e1b
--- /dev/null
@@ -0,0 +1,13 @@
+// four use by cint
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class AliHighPtDeDxBase+;
+#pragma link C++ class AliHighPtDeDxCalib+;
+#pragma link C++ class AliHighPtDeDxData+;
+#pragma link C++ class AliHighPtDeDxMc+;
+#pragma link C++ class AliHighPtDeDxSpectra+;
+#endif
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/lib/Makefile b/PWGLF/SPECTRA/IdentifiedHighPt/lib/Makefile
new file mode 100644 (file)
index 0000000..cd2f88a
--- /dev/null
@@ -0,0 +1,100 @@
+#
+# Config variables
+#
+
+MAJOR          = 0
+MINOR          = 1
+
+#PROGRAM               = maketracktree
+#PROGOBJS      = maketracktree.o
+PROGRAM                = 
+PROGOBJS       = 
+
+PROGRAM2       = 
+PROGOBJS2      = 
+
+LIBNAME                = MyDeDxAnalysis
+LIBRARY                = lib$(LIBNAME).so
+LIBOBJS                = AliHighPtDeDxBase.o   \
+                 AliHighPtDeDxCalib.o  \
+                 AliHighPtDeDxData.o   \
+                 AliHighPtDeDxMc.o     \
+                 AliHighPtDeDxSpectra.o        \
+                 AliHighPtDeDxBaseCint.o
+
+
+#
+# ROOT and BRAT variables
+#
+ROOTCINT       = rootcint 
+ROOTCFLAGS     = $(shell root-config --cflags)
+#ROOTLIBS      = $(shell root-config --glibs) -lEG -lGeom -lTreePlayer
+ROOTLIBS       = $(shell root-config --glibs)
+ROOTINCS       = -I./ 
+ACCPATH         = $(shell pwd)
+
+#
+#
+#
+ALILIBS         = -L$(ALICE_ROOT)/lib/tgt_linux/ -lESD
+#LIBS          = -L./ -l$(LIBNAME) $(ROOTLIBS) $(ALILIBS) -L$(HOME)/lib -lTOption
+LIBS           = -L./ -l$(LIBNAME) $(ROOTLIBS)
+ALIINCLUDE      = -I$(ALICE_ROOT)/include/ -I$(ALICE_ROOT)/STEER/ -I$(ALICE_ROOT)/TPC/
+#INCLUDES      = -I./ $(ALIINCLUDE) -I$(HOME)/include/ 
+INCLUDES       = -I./ 
+
+# 
+# Preprocessor, Compiler, and Linker variables 
+#
+CPPFLAGS       = $(INCLUDES) $(ROOTCFLAGS)
+CXX            = g++
+#CXXFLAGS      = -c -g -Wall -o  
+CXXFLAGS       = -c -g -Wall -fPIC -o  
+LD             = g++
+LDFLAGS                = -rdynamic -Wl,-rpath,$(ACCPATH) $(LIBS) -o 
+SOFLAGS         = -shared  -Wl,-soname,
+LN             = ln -fs 
+OUTOPT         = -o
+
+#
+# Rules
+#
+#%Cint.cxx:%Inc.h
+%Cint.cxx:Include.h LinkDef.h
+       rootcint -f $@ -c $(ROOTCFLAGS) -p -I./ $^ 
+#$*LinkDef.h
+
+%.o:%.cc
+       $(CXX) $(CPPFLAGS) $(CXXFLAGS) $@ $<
+
+%.o:%.cxx
+       $(CXX) $(CPPFLAGS) $(CXXFLAGS) $@ $<
+
+%.so:
+       $(LD) $(SOFLAGS)$@ $(OUTOPT) $@ $^
+
+%:%.o
+       $(LD) $(LDFLAGS) $@ $^
+
+
+#
+# Targets 
+#
+all:   $(LIBRARY) $(PROGRAM) $(PROGRAM2) 
+
+install: all
+       @echo "cannot install, don't know your install dir"
+clean:
+       rm -f core *~ *.o *Cint.* $(LIBRARY)* $(PROGRAM) $(PROGRAM2) 
+
+realclean: clean
+       rm -f $(LIBRARY)* $(PROGRAM) $(PROGRAM2) 
+
+#
+# Dependencies 
+#
+$(LIBRARY):$(LIBOBJS)
+$(PROGRAM):$(PROGOBJS)
+$(PROGRAM2):$(PROGOBJS2)
+
+
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/calibrate_de_dx.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/calibrate_de_dx.C
new file mode 100644 (file)
index 0000000..55c4905
--- /dev/null
@@ -0,0 +1,1202 @@
+
+#include <TFile.h>
+#include <TH1.h>
+#include <TProfile.h>
+#include <TF1.h>
+#include <TGraphErrors.h>
+#include <TCanvas.h>
+#include <TAxis.h>
+#include <TLegend.h>
+#include <TStyle.h>
+#include <TGraphAsymmErrors.h>
+#include <TList.h>
+#include <TMath.h>
+#include <TString.h>
+#include <TSystem.h>
+#include <TLatex.h>
+#include <TF1.h>
+#include <TF2.h>
+#include <TFitResultPtr.h>
+#include <TFitResult.h>
+
+#include "AliHighPtDeDxCalib.h"
+
+#include "my_tools.C"
+#include "my_functions.C"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+/*
+  Ideas to improve:
+  =================
+
+  Use the real mean p -> Might give some effect
+  Effect: Push the <dE/dx> down (let'a see if it is still needed in the fits)
+
+  Use the real <nCl> 
+  Effect: Increase sigma for p<15. For p>15 seems to saturate.
+  
+  To use:
+
+  =======
+  root is enough
+
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TPC")
+  gSystem->AddIncludePath("-I../lib")
+  gSystem->AddIncludePath("-I../grid")
+  gSystem->AddIncludePath("-I../macros")
+  gROOT->SetMacroPath(".:../macros:../grid:../lib/")
+  .L libMyDeDxAnalysis.so 
+  .L my_functions.C+
+  .L my_tools.C+
+  .L DebugClasses.C+
+  .L calibrate_de_dx.C+
+  
+  // Step 2: test calibrations done in step 1
+  DrawStep2("calib_eta/7tev_b.root", kFALSE);
+  DrawStep2("calib_eta/7tev_b.root", kTRUE);
+  TestResolutionVsDeDx("calib_eta/7tev_b.root");
+  TestResolutionVsEta("calib_eta/7tev_b.root", kTRUE);
+
+  // Here we want to see that the data is symmetric in eta and roughly symmetric for high vs low eta
+  CompareYields("calib_eta/7tev_b.root", 0, 3.0, 30.0, "eta-80", "eta08")
+  CompareYields("calib_eta/7tev_b.root", 0, 3.0, 30.0, "etaabs04", "etaabs48") 
+
+  // Step 3: extract
+  FitDeDxVsP("calib_eta/7tev_b.root", 3.0, 30.0, 4, 2, kTRUE)
+
+
+  // Step 4: inspect the results in results/calibdedx and results/calibplots
+  // using e.g. gwenview. Event the fit did not converge it is still ok if it
+  // describes the data!
+
+
+
+  //
+  // Test
+  //
+  // Step 2: test calibrations done in step 1
+  DrawStep2("calib_eta/7tev_b_test.root", kFALSE);
+  DrawStep2("calib_eta/7tev_b_test.root", kTRUE);
+  TestResolutionVsDeDx("calib_eta/7tev_b_test.root");
+  TestResolutionVsEta("calib_eta/7tev_b_test.root", kTRUE);
+  // Step 3: extract
+  FitDeDxVsP("calib_eta/7tev_b_test.root", 2.0, 10.0, 4, 2, kTRUE)
+
+
+ */
+
+
+//____________________________________________________________________________
+void FitDeDxVsP(const Char_t* calibFileName,
+               Double_t pStart, Double_t pStop,
+               Int_t optionDeDx, Int_t optionSigma,
+               Bool_t performFit = kFALSE,
+               Int_t run    = 0,
+               Int_t filter = 1,
+               Bool_t usePhiCut = kTRUE,
+               const Char_t* v0FileName=0,
+               Bool_t fixAllPar=kFALSE)
+{
+  gStyle->SetOptStat(0);
+
+  TString baseName(gSystem->BaseName(calibFileName));
+  baseName.ReplaceAll(".root", "");
+
+  TFile* calibFile = FindFileFresh(calibFileName);
+  if(!calibFile)
+    return;
+  AliHighPtDeDxCalib* calib = (AliHighPtDeDxCalib*)GetObject(calibFile, filter, usePhiCut, run);
+  calib->Print();
+
+  fixMIP      = calib->GetHistDeDx(kTRUE, 0)->GetMean();
+  fixPlateau  = calib->GetHistDeDx(kFALSE, 0)->GetMean();
+  hDeDxVsP = calib->GetHistDeDxVsP(0);
+  hMeanP = calib->GetHistMeanP();
+
+  AliHighPtDeDxCalib* lambdaCalib = 0;
+  AliHighPtDeDxCalib* kaonCalib   = 0;
+  TH2D* hDeDxVsPV0Lambda = 0;
+  TH2D* hDeDxVsPV0Kaon   = 0;
+  if(v0FileName) {
+    TFile* v0File = FindFileFresh(v0FileName);
+    if(!v0File)
+      return;
+    lambdaCalib = (AliHighPtDeDxCalib*)GetObject(v0File, 0, usePhiCut, run, "lambda");
+    lambdaCalib->Print();
+    hDeDxVsPV0Lambda = lambdaCalib->GetHistDeDxVsP(0);
+    kaonCalib   = (AliHighPtDeDxCalib*)GetObject(v0File, 0, usePhiCut, run, "kaon");
+    kaonCalib->Print();
+    hDeDxVsPV0Kaon = kaonCalib->GetHistDeDxVsP(0);
+  }
+
+  CreateDir("old");
+  gSystem->Exec("mv results/calibdedx/* old/");
+  if(calib->IsMc())
+    gSystem->Exec("mv debugmc/* old/");
+
+  if(hDeDxVsPV0Lambda) {
+    gSystem->Exec("mv debuglambda/* old/");
+    gSystem->Exec("mv debugkaon/* old/");
+  }
+
+  TH2D* hDeDxVsPPi = 0;
+  TH2D* hDeDxVsPK  = 0;
+  TH2D* hDeDxVsPP  = 0;
+  TH2D* hDeDxVsPMu = 0;
+
+  if(calib->IsMc()) {
+
+    hDeDxVsPPi = calib->GetHistDeDxVsP(1);
+    hDeDxVsPK  = calib->GetHistDeDxVsP(2);
+    hDeDxVsPP  = calib->GetHistDeDxVsP(3);
+    hDeDxVsPMu = calib->GetHistDeDxVsP(5);
+  }
+
+  TCanvas* cDeDxVsP = new TCanvas("cDeDxVsP", "dE/dx vs p", 400, 300);
+  cDeDxVsP->Clear();
+  cDeDxVsP->cd();
+  cDeDxVsP->SetLogz();
+  hDeDxVsP->SetTitle(0);
+  hDeDxVsP->Draw("COLZ");
+
+  TCanvas* cDeDxVsPLogX = new TCanvas("cDeDxVsPLogX", "dE/dx vs p", 400, 300);
+  cDeDxVsPLogX->Clear();
+  cDeDxVsPLogX->cd();
+  cDeDxVsPLogX->SetLogz();
+  cDeDxVsPLogX->SetLogx();
+  hDeDxVsP->Draw("COLZ");
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeDxVsP->GetXaxis()->FindBin(pStart+0.01);
+  pStart = hDeDxVsP->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeDxVsP->GetXaxis()->FindBin(pStop-0.01);
+  pStop = hDeDxVsP->GetXaxis()->GetBinUpEdge(binStop);
+  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing 2d fit from pTlow = " << pStart << " (bin: " << binStart
+       << ") to pThigh = " << pStop << " (bin: " << binStop << ")" << endl;
+  
+  // Double_t binSize = (histdEdxvsP->GetXaxis()->GetXmax() - histdEdxvsP->GetXaxis()->GetXmin())/ histdEdxvsP->GetXaxis()->GetNbins();
+  
+  Double_t parDeDx[3]  = {0, 0, 0};
+  Double_t parSigma[3] = {0, 0, 0};
+  
+  const Int_t nLocalParams  = 3; // pi, K, p yields
+  Int_t nDeDxPar      = 0;
+  Int_t nSigmaPar     = 0;
+
+  switch(optionDeDx) {
+    
+  case 1:
+    nDeDxPar = 2;
+    parDeDx[0] = 39.7;
+    parDeDx[1] =  6.3;
+    break;
+  case 2:
+    nDeDxPar = 1;
+    parDeDx[0] =  7.3;
+    break;
+  case 3:
+    nDeDxPar = 2;
+    parDeDx[0] =  6.85097;
+    parDeDx[1] =  29.5933;
+    break;
+  // case 4:
+  //   nDeDxPar = 3;
+  //   parDeDx[0] = 35.5471;
+  //   parDeDx[1] =  6.85097;
+  //   parDeDx[2] =  29.5933;
+  //   break;
+  case 4:
+    nDeDxPar = 3;
+    parDeDx[0] =  35.6694;
+    parDeDx[1] =  6.80835;
+    parDeDx[2] =  7.6542;
+    break;
+  default:
+
+    cout << "optionDeDx does not support option: " << optionDeDx << endl;
+    return;
+    break;
+  }
+
+  switch(optionSigma) {
+    
+  case 1:
+    nSigmaPar = 1;
+    parSigma[0] = 3.0;
+    break;
+  case 2:
+    nSigmaPar = 1;
+    parSigma[0] = 0.0655688;
+    break;
+  case 3:
+    nSigmaPar = 2;
+    parSigma[0] = 0.06;
+    parSigma[1] = -0.001;
+  case 4:
+    nSigmaPar = 2;
+    parSigma[0] = 0.06;
+    parSigma[1] = 1.0;
+    break;
+  case 5:
+    nSigmaPar = 2;
+    parSigma[0] = 0.06;
+    parSigma[1] = 1.0;
+    break;
+  default:
+
+    cout << "optionSigma does not support option: " << optionSigma << endl;
+    return;
+    break;
+  }
+
+  const Int_t nGlobalParams = 2  // binStart, binStop, 
+    + 2 + nDeDxPar               // optionDeDx, nDeDxPar, dedxpar0 ....
+    + 2 + nSigmaPar;             // nSigmaPar, sigmapar0 .....
+  
+  const Int_t nParams = nBins*nLocalParams + nGlobalParams;
+  
+  
+  TF2* fitAll = new TF2("fitAll", fitf3G, pStart, pStop, 30, 90, nParams);
+  Double_t parametersIn[nParams]; 
+  
+  parametersIn[0] = binStart;
+  fitAll->SetParName(0,"binStart");
+  fitAll->FixParameter(0, parametersIn[0]);
+
+  parametersIn[1] = binStop;
+  fitAll->SetParName(1,"binStop");
+  fitAll->FixParameter(1, parametersIn[1]);
+
+  // dE/dx parameters
+  parametersIn[2] = nDeDxPar;
+  fitAll->SetParName(2,"nDeDxPar");
+  fitAll->FixParameter(2, parametersIn[2]);
+
+  parametersIn[3] = optionDeDx;
+  fitAll->SetParName(3,"optionDeDx");
+  fitAll->FixParameter(3, parametersIn[3]);
+
+  for(Int_t i = 0; i < nDeDxPar; i++) {
+
+    parametersIn[4+i] = parDeDx[i];
+    fitAll->SetParName(4+i,Form("dEdXpar%d", i));
+    // if(optionDeDx == 4 && i <2) {
+      
+    //   fitAll->FixParameter(4+i, parametersIn[4+i]);
+    // }
+    if(fixAllPar) {
+
+      fitAll->FixParameter(4+i, parametersIn[4+i]);
+    }
+  }
+
+  // sigma parameters
+  parametersIn[4+nDeDxPar] = nSigmaPar;
+  fitAll->SetParName(4+nDeDxPar,"nSigmaPar");
+  fitAll->FixParameter(4+nDeDxPar, parametersIn[4+nDeDxPar]);
+
+  parametersIn[5+nDeDxPar] = optionSigma;
+  fitAll->SetParName(5+nDeDxPar,"optionSigma");
+  fitAll->FixParameter(5+nDeDxPar, parametersIn[5+nDeDxPar]);
+
+  for(Int_t i = 0; i < nSigmaPar; i++) {
+
+    parametersIn[6+nDeDxPar+i] = parSigma[i];
+    fitAll->SetParName(6+nDeDxPar+i,Form("sigmapar%d", i));
+    if(fixAllPar) {
+
+      fitAll->FixParameter(6+nDeDxPar+i, parametersIn[6+nDeDxPar+i]);
+    }
+  }
+  
+  // Initial yields
+
+  for(Int_t bin = binStart; bin <= binStop; bin++) {
+    
+    TH1D* hDeDxVsPProj =(TH1D*)hDeDxVsP->ProjectionY("hDeDxVsPProj", bin, bin);
+    
+    const Int_t offset = nGlobalParams + (bin - binStart)*nLocalParams;
+    const Double_t all = hDeDxVsPProj->Integral();
+    parametersIn[offset + 0] = (all)*0.6;
+    parametersIn[offset + 1] = (all)*0.3;
+    parametersIn[offset + 2] = (all)*0.1;
+    
+    fitAll->SetParName(offset + 0, Form("piYield%d", bin));
+    fitAll->SetParLimits(offset + 0, 0, 10*all);
+    fitAll->SetParName(offset + 1, Form("kYield%d", bin));
+    fitAll->SetParLimits(offset + 1, 0, 10*all);
+    fitAll->SetParName(offset + 2, Form("pYield%d", bin));
+    fitAll->SetParLimits(offset + 2, 0, 10*all);
+    // fitAll->SetParLimits(offset + 0, 0., histdEdxvsPpy->GetEntries());
+    // fitAll->SetParLimits(offset + 1, 0., histdEdxvsPpy->GetEntries());
+    // fitAll->SetParLimits(offset + 2, 0., histdEdxvsPpy->GetEntries());    
+  }
+  
+  fitAll->SetParameters(parametersIn);
+  fitAll->Print();
+
+  Bool_t converged = kFALSE;
+
+  if(performFit) {
+    for(Int_t i = 0; i < 4; i++) {
+      TFitResultPtr fitResultPtr =  hDeDxVsP->Fit(fitAll, "0S", "", pStart+0.01, pStop-0.01);
+      if(!fitResultPtr->Status()) {
+       //      if(!fitResultPtr->Status() && !fitResultPtr->CovMatrixStatus()) {
+       
+       converged = kTRUE;
+       break;
+      }
+    }
+  }
+  // else we just draw how the results looks with the input parameters
+
+  Double_t parametersOut[nParams];
+  fitAll->GetParameters(parametersOut);
+  const Double_t* parameterErrorsOut = fitAll->GetParErrors();
+
+  // overlay the fitfunction
+  
+
+  TF1* fDeDxPi = new TF1("fDeDxPi", FitFunc, 0, 50, nDeDxPar+1); // +1 because of option! 
+  fDeDxPi->SetParameters(&parametersOut[3]);
+  fDeDxPi->SetLineWidth(2);
+  cDeDxVsP->cd();
+  fDeDxPi->Draw("SAME");
+  cDeDxVsPLogX->cd();
+  fDeDxPi->Draw("SAME");
+
+  TF1* fDeDxK = new TF1("fDeDxK", FitFunc, 0, 50, nDeDxPar+1); 
+  fDeDxK->SetParameters(&parametersOut[3]);
+  fDeDxK->SetParameter(0, fDeDxK->GetParameter(0)+10);
+  fDeDxK->SetLineWidth(2);
+  cDeDxVsP->cd();
+  fDeDxK->Draw("SAME");
+  cDeDxVsPLogX->cd();
+  fDeDxK->Draw("SAME");
+
+  TF1* fDeDxP = new TF1("fDeDxP", FitFunc, 0, 50, nDeDxPar+1); 
+  fDeDxP->SetParameters(&parametersOut[3]);
+  fDeDxP->SetParameter(0, fDeDxP->GetParameter(0)+20);
+  fDeDxP->SetLineWidth(2);
+  cDeDxVsP->cd();
+  fDeDxP->Draw("SAME");
+  cDeDxVsPLogX->cd();
+  fDeDxP->Draw("SAME");
+
+  TF1* fDeDxE = new TF1("fDeDxE", FitFunc, 0, 50, nDeDxPar+1); 
+  fDeDxE->SetParameters(&parametersOut[3]);
+  fDeDxE->SetParameter(0, fDeDxE->GetParameter(0)+30);
+  fDeDxE->SetLineWidth(2);
+  cDeDxVsP->cd();
+  fDeDxE->Draw("SAME");
+  cDeDxVsPLogX->cd();
+  fDeDxE->Draw("SAME");
+
+  TF1* fSigma = new TF1("fSigma", SigmaFunc, 0, 50, nSigmaPar+1); 
+  fSigma->SetParameters(&parametersOut[5 + nDeDxPar]);
+
+  //  fitAll->Draw("same cont3"); 
+
+  CreateDir("results/calibdedx");
+
+  cDeDxVsP->cd();
+  cDeDxVsP->Modified();
+  cDeDxVsP->Update();
+  gROOT->ProcessLine(".x drawText.C");
+  cDeDxVsP->SaveAs("results/calibdedx/dedx_vs_p.gif");
+  cDeDxVsP->SaveAs("results/calibdedx/dedx_vs_p.pdf");
+
+  cDeDxVsPLogX->cd();
+  cDeDxVsPLogX->Modified();
+  cDeDxVsPLogX->Update();
+  gROOT->ProcessLine(".x drawText.C");
+  cDeDxVsPLogX->SaveAs("results/calibdedx/dedx_vs_p_logx.gif");
+  cDeDxVsPLogX->SaveAs("results/calibdedx/dedx_vs_p_logx.pdf");
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 5);
+
+  TF1* pion = new TF1("pion", "gausn", 30, 90);
+  pion->SetLineWidth(2);
+  pion->SetLineColor(kRed);
+  TF1* kaon = new TF1("kaon", "gausn", 30, 90);
+  kaon->SetLineWidth(2);
+  kaon->SetLineColor(kGreen);
+  TF1* proton = new TF1("proton", "gausn", 30, 90);
+  proton->SetLineWidth(2);
+  proton->SetLineColor(kBlue);
+  TF1* total = new TF1("total", "gausn(0)+gausn(3)+gausn(6)", 30, 90);
+  total->SetLineColor(kBlack);
+  total->SetLineWidth(2);
+  total->SetLineStyle(2);
+
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(total, "3-Gauss fit", "L");
+  legend->AddEntry(pion, "#pi", "L");
+  legend->AddEntry(kaon, "K", "L");
+  legend->AddEntry(proton, "p", "L");
+
+
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+
+  TH1D* hPionRatio =(TH1D*)hDeDxVsP->ProjectionX("hPionRatio", 1, 1);
+  hPionRatio->Reset();
+  hPionRatio->GetXaxis()->SetRangeUser(pStart+0.001, pStop-0.001);
+  hPionRatio->GetYaxis()->SetRangeUser(0.0, 1.0);
+  hPionRatio->SetTitle("particle fractions; p [GeV/c]; particle fraction");
+  TH1D* hKaonRatio   = (TH1D*)hPionRatio->Clone("hKaonRatio");
+  TH1D* hProtonRatio = (TH1D*)hPionRatio->Clone("hProtonRatio");
+
+  TH1D* hPionRatioMc = (TH1D*)hPionRatio->Clone("hPionRatioMc");
+  TH1D* hKaonRatioMc = (TH1D*)hPionRatio->Clone("hKaonRatioMc");
+  TH1D* hProtonRatioMc = (TH1D*)hPionRatio->Clone("hProtonRatioMc");
+  TH1D* hMuonRatioMc = (TH1D*)hPionRatio->Clone("hMuonRatioMc");
+  
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    cFits->cd();
+    cFits->cd(j + 1);
+    
+    TH1D* hDeDxVsPProj =(TH1D*)hDeDxVsP->ProjectionY(Form("hDeDxVsPProj%d", bin), bin, bin);
+    hDeDxVsPProj->GetXaxis()->SetRangeUser(40, 90);
+    hDeDxVsPProj->SetTitle(Form("%.1f<p<%.1f GeV/c", 
+                               hDeDxVsP->GetXaxis()->GetBinLowEdge(bin),
+                               hDeDxVsP->GetXaxis()->GetBinUpEdge(bin)));
+    hDeDxVsPProj->Draw();
+    
+    const Int_t offset = nGlobalParams + j*nLocalParams; 
+    const Double_t p = hDeDxVsP->GetXaxis()->GetBinCenter(bin);
+    const Double_t pKeff = p*piMass/kMass; // corresponding p of a pion with same dE/dx
+    const Double_t pPeff = p*piMass/pMass; // corresponding p of a pion with same dE/dx
+    const Double_t meanDeDxPi = fDeDxPi->Eval(p);
+    const Double_t meanDeDxK  = fDeDxPi->Eval(pKeff);
+    const Double_t meanDeDxP  = fDeDxPi->Eval(pPeff);
+    Double_t gausParams[9] = { 
+      parametersOut[offset + 0], 
+      meanDeDxPi, 
+      fSigma->Eval(meanDeDxPi) ,
+      parametersOut[offset + 1], 
+      meanDeDxK, 
+      fSigma->Eval(meanDeDxK) ,
+      parametersOut[offset + 2], 
+      meanDeDxP, 
+      fSigma->Eval(meanDeDxP) ,
+    };
+
+    for(Int_t i = 0; i < 9; i++) 
+      cout << gausParams[i] << ", ";
+
+    cout << endl;
+    
+    pion->SetParameters(&gausParams[0]);
+    pion->DrawCopy("same");
+    Double_t all =  hDeDxVsPProj->Integral();
+    hPionRatio->SetBinContent(bin, parametersOut[offset + 0]/all);
+    hPionRatio->SetBinError(bin, parameterErrorsOut[offset + 0]/all);
+
+    kaon->SetParameters(&gausParams[3]);
+    kaon->DrawCopy("same");
+    hKaonRatio->SetBinContent(bin, parametersOut[offset + 1]/all);
+    hKaonRatio->SetBinError(bin, parameterErrorsOut[offset + 1]/all);
+    
+    proton->SetParameters(&gausParams[6]);
+    proton->DrawCopy("same");
+    hProtonRatio->SetBinContent(bin, parametersOut[offset + 2]/all);
+    hProtonRatio->SetBinError(bin, parameterErrorsOut[offset + 2]/all);
+    
+    total->SetParameters(gausParams);
+    total->DrawCopy("same");
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    //    cSingleFit->SetLogy();
+    hDeDxVsPProj->Draw();
+    pion->DrawCopy("same");
+    kaon->DrawCopy("same");
+    proton->DrawCopy("same");
+    total->DrawCopy("same");
+    
+    gROOT->ProcessLine(".x drawText.C(2)");
+    cSingleFit->SaveAs(Form("results/calibdedx/ptspectrum_bin%d.gif", bin));
+    cSingleFit->SaveAs(Form("results/calibdedx/ptspectrum_bin%d.pdf", bin));
+    //    legend->Draw();
+
+    if(calib->IsMc()) {
+
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      TH1D* hDeDxVsPPiProj =(TH1D*)hDeDxVsPPi->ProjectionY(Form("hDeDxVsPPiProj%d", bin), bin, bin);
+      hDeDxVsPPiProj->SetMarkerStyle(20);
+      hDeDxVsPPiProj->SetMarkerColor(2);
+      hDeDxVsPPiProj->GetXaxis()->SetRangeUser(40, 90);
+      hDeDxVsPPiProj->SetTitle(Form("%.1f<p<%.1f GeV/c", 
+                                   hDeDxVsP->GetXaxis()->GetBinLowEdge(bin),
+                                   hDeDxVsP->GetXaxis()->GetBinUpEdge(bin)));
+      hDeDxVsPPiProj->Draw("P");
+      hPionRatioMc->SetBinContent(bin, hDeDxVsPPiProj->Integral()/all);
+      TH1D* hDeDxVsPKProj =(TH1D*)hDeDxVsPK->ProjectionY(Form("hDeDxVsPKProj%d", bin), bin, bin);
+      hDeDxVsPKProj->SetMarkerStyle(21);
+      hDeDxVsPKProj->SetMarkerColor(3);
+      hDeDxVsPKProj->Draw("SAME P");
+      hKaonRatioMc->SetBinContent(bin, hDeDxVsPKProj->Integral()/all);
+      TH1D* hDeDxVsPPProj =(TH1D*)hDeDxVsPP->ProjectionY(Form("hDeDxVsPPProj%d", bin), bin, bin);
+      hDeDxVsPPProj->SetMarkerStyle(22);
+      hDeDxVsPPProj->SetMarkerColor(4);
+      hDeDxVsPPProj->Draw("SAME P");
+      hProtonRatioMc->SetBinContent(bin, hDeDxVsPPProj->Integral()/all);
+      TH1D* hDeDxVsPMuProj =(TH1D*)hDeDxVsPMu->ProjectionY(Form("hDeDxVsPMuProj%d", bin), bin, bin);
+      hDeDxVsPMuProj->SetMarkerStyle(22);
+      hDeDxVsPMuProj->SetMarkerColor(6);
+      //      hDeDxVsPMuProj->Draw("SAME P");
+      hMuonRatioMc->SetBinContent(bin, hDeDxVsPMuProj->Integral()/all);
+      //    cSingleFit->SetLogy();
+      pion->DrawCopy("same");
+      kaon->DrawCopy("same");
+      proton->DrawCopy("same");
+      CreateDir("results/calibdedx/debugmc");
+      cSingleFit->SaveAs(Form("results/calibdedx/debugmc/ptspectrum_bin%d.gif", bin));
+    }
+
+    if(hDeDxVsPV0Lambda) {
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      TH1D* hDeDxVsPV0LambdaProj =(TH1D*)hDeDxVsPV0Lambda->ProjectionY(Form("hDeDxVsPV0LambdaProj%d", bin), bin, bin);
+      hDeDxVsPV0LambdaProj->SetMarkerStyle(20);
+      hDeDxVsPV0LambdaProj->SetMarkerColor(4);
+      hDeDxVsPV0LambdaProj->GetXaxis()->SetRangeUser(40, 90);
+      hDeDxVsPV0LambdaProj->SetTitle(Form("%.1f<p<%.1f GeV/c", 
+                                         hDeDxVsP->GetXaxis()->GetBinLowEdge(bin),
+                                         hDeDxVsP->GetXaxis()->GetBinUpEdge(bin)));
+      hDeDxVsPV0LambdaProj->Draw("P");
+      proton->SetParameter(0, hDeDxVsPV0LambdaProj->Integral());
+      proton->DrawCopy("same");
+
+      CreateDir("results/calibdedx/debuglambda");
+      cSingleFit->SaveAs(Form("results/calibdedx/debuglambda/ptspectrum_bin%d.gif", bin));
+    }
+
+    if(hDeDxVsPV0Kaon) {
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      TH1D* hDeDxVsPV0KaonProj =(TH1D*)hDeDxVsPV0Kaon->ProjectionY(Form("hDeDxVsPV0KaonProj%d", bin), bin, bin);
+      hDeDxVsPV0KaonProj->SetMarkerStyle(20);
+      hDeDxVsPV0KaonProj->SetMarkerColor(2);
+      hDeDxVsPV0KaonProj->GetXaxis()->SetRangeUser(40, 90);
+      hDeDxVsPV0KaonProj->SetTitle(Form("%.1f<p<%.1f GeV/c", 
+                                         hDeDxVsP->GetXaxis()->GetBinLowEdge(bin),
+                                         hDeDxVsP->GetXaxis()->GetBinUpEdge(bin)));
+      hDeDxVsPV0KaonProj->Draw("P");
+      pion->SetParameter(0, hDeDxVsPV0KaonProj->Integral());
+      pion->DrawCopy("same");
+      CreateDir("results/calibdedx/debugkaon");
+      cSingleFit->SaveAs(Form("results/calibdedx/debugkaon/ptspectrum_bin%d.gif", bin));
+    }
+  }
+
+  TCanvas* cRatio = new TCanvas("cRatio", "ratios/all vs p", 600, 400);
+  cRatio->Clear();
+  hPionRatio->SetMaximum(0.8);
+  hPionRatio->SetMarkerStyle(20);
+  hPionRatio->SetMarkerColor(2);
+  hPionRatio->Draw("P E");
+
+  hKaonRatio->SetMarkerStyle(20);
+  hKaonRatio->SetMarkerColor(3);
+  hKaonRatio->Draw("SAME P E");
+
+  hProtonRatio->SetMarkerStyle(20);
+  hProtonRatio->SetMarkerColor(4);
+  hProtonRatio->Draw("SAME P E");
+  gROOT->ProcessLine(".x drawText.C(2)");
+  cRatio->SaveAs("results/calibdedx/particle_ratios.gif");
+  cRatio->SaveAs("results/calibdedx/particle_ratios.pdf");
+
+  if(calib->IsMc()) {
+    
+    hPionRatioMc->SetMarkerStyle(24);
+    hPionRatioMc->SetMarkerColor(2);
+    hPionRatioMc->Draw("SAME P");
+    
+    hKaonRatioMc->SetMarkerStyle(24);
+    hKaonRatioMc->SetMarkerColor(3);
+    hKaonRatioMc->Draw("SAME P");
+    
+    hProtonRatioMc->SetMarkerStyle(24);
+    hProtonRatioMc->SetMarkerColor(4);
+    hProtonRatioMc->Draw("SAME P");
+
+    hMuonRatioMc->SetMarkerStyle(24);
+    hMuonRatioMc->SetMarkerColor(6);
+    //    hMuonRatioMc->Draw("SAME P");
+    cRatio->SaveAs("results/calibdedx/debugmc/particle_ratios_mc.gif");
+  }
+
+
+  cout << "MIP was fixed to: " << fixMIP << endl
+       << "Plateau was fixed to: " << fixPlateau << endl;
+
+  //
+  // Store the <dE/dx> parameters in a file that we can get them back to use for the Delta-pi!
+  //
+  DeDxFitInfo* fitInfo = new DeDxFitInfo();
+  fitInfo->MIP     = fixMIP;
+  fitInfo->plateau = fixPlateau; 
+  fitInfo->optionDeDx = optionDeDx; 
+  fitInfo->nDeDxPar = nDeDxPar; 
+  for(Int_t i = 0; i < nDeDxPar; i++) {
+    fitInfo->parDeDx[i] = fDeDxPi->GetParameter(i+1); // 1st parameter is option
+  }
+  fitInfo->optionSigma = optionSigma; 
+  fitInfo->nSigmaPar = nSigmaPar; 
+  for(Int_t i = 0; i < nSigmaPar; i++) {
+    fitInfo->parSigma[i] = fSigma->GetParameter(i+1); // 1st parameter is option 
+  }
+  if(!strstr(calibFileName, "no_calib_eta"))
+    fitInfo->calibFileName = calibFileName;
+
+  fitInfo->Print();
+
+  CreateDir("fitparameters");
+  TFile* outFile = new TFile(Form("fitparameters/%s", gSystem->BaseName(calibFileName)), "RECREATE");
+  fitInfo->Write("fitInfo");
+  outFile->Close();
+
+  if(converged) {
+
+    cout << "Fit converged and error matrix was ok" << endl;
+  } else {
+
+    cout << "WARNING!!!!!!!!!!!!!!! Fit did not converge, or error matrix was  not ok!" << endl;
+  }
+}
+
+
+
+//____________________________________________________________________________
+void DrawStep2(const Char_t* calibFileName,
+              Bool_t forMIP = kTRUE,
+              Int_t run    = 0,
+              Int_t filter = 1,
+              Bool_t usePhiCut = kTRUE)
+{
+  // option:
+  // 0 - compare to ALICE INEL
+  // 1 - compare to MC input spectrum
+  // 2 - compare to MC correct spectrum
+  gStyle->SetOptStat(0);
+
+  CreateDir("results/calibplots");
+  TString baseName(gSystem->BaseName(calibFileName));
+  baseName.ReplaceAll(".root", "");
+
+  TFile* calibFile = FindFileFresh(calibFileName);
+  if(!calibFile)
+    return;
+  AliHighPtDeDxCalib* calib = (AliHighPtDeDxCalib*)GetObject(calibFile, filter, usePhiCut, run);
+  calib->Print();
+  TCanvas* cPhiCut = calib->DrawPhiCutHistograms();
+  gROOT->ProcessLine(".x drawText.C(2)");
+  cPhiCut->SaveAs(Form("results/calibplots/phicut_%s.gif", baseName.Data())); 
+  cPhiCut->SaveAs(Form("results/calibplots/phicut_%s.pdf", baseName.Data())); 
+  TCanvas* cEta = calib->DrawEta(forMIP);
+  gROOT->ProcessLine(".x drawText.C(2)");
+  TCanvas* cEtaCal = calib->DrawEtaCalibrated(forMIP);
+  gROOT->ProcessLine(".x drawText.C(2)");
+  if(forMIP) {
+    cEta->cd();
+    cEta->SaveAs(Form("results/calibplots/MIP_dedx_vs_eta_nocal_%s.gif", baseName.Data())); 
+    cEta->SaveAs(Form("results/calibplots/MIP_dedx_vs_eta_nocal_%s.pdf", baseName.Data())); 
+    cEtaCal->cd();
+    cEtaCal->SaveAs(Form("results/calibplots/MIP_dedx_vs_eta_final_%s.gif", baseName.Data())); 
+    cEtaCal->SaveAs(Form("results/calibplots/MIP_dedx_vs_eta_final_%s.pdf", baseName.Data())); 
+  } else {
+    cEta->cd();
+    cEta->SaveAs(Form("results/calibplots/Electrons_dedx_vs_eta_nocal_%s.gif", baseName.Data())); 
+    cEta->SaveAs(Form("results/calibplots/Electrons_dedx_vs_eta_nocal_%s.pdf", baseName.Data())); 
+    cEtaCal->cd();
+    cEtaCal->SaveAs(Form("results/calibplots/Electrons_dedx_vs_eta_final_%s.gif", baseName.Data())); 
+    cEtaCal->SaveAs(Form("results/calibplots/Electrons_dedx_vs_eta_final_%s.pdf", baseName.Data())); 
+  }
+  TCanvas* cEtaSel = calib->DrawSelectionHistograms();
+  gROOT->ProcessLine(".x drawText.C(2)");
+  cEtaSel->SaveAs(Form("results/calibplots/selection_%s.gif", baseName.Data())); 
+  cEtaSel->SaveAs(Form("results/calibplots/selection_%s.pdf", baseName.Data())); 
+
+  // TCanvas* cNcl = calib->DrawNclCal();
+  // gROOT->ProcessLine(".x drawText.C");
+  // cNcl->SaveAs(Form("results/calibplots/dedx_vs_ncl_calib__%s.gif", baseName.Data())); 
+  // cNcl->SaveAs(Form("results/calibplots/dedx_vs_ncl_calib__%s.pdf", baseName.Data())); 
+}
+
+//____________________________________________________________________________
+void TestResolutionVsDeDx(const Char_t* calibFileName,
+                         Int_t run    = 0,
+                         Int_t filter = 1,
+                         Bool_t usePhiCut = kTRUE)
+{
+  gStyle->SetOptStat(0);
+  
+  TFile* calibFile = FindFileFresh(calibFileName);
+  if(!calibFile)
+    return;
+  AliHighPtDeDxCalib* calib = (AliHighPtDeDxCalib*)GetObject(calibFile, filter, usePhiCut, run);
+  calib->Print();
+  TH2D* hDeDxVsNcl  = calib->GetHistDeDxVsNcl(kTRUE, 0);
+  TH2D* hDeDxVsNclE = calib->GetHistDeDxVsNcl(kFALSE, 0);
+  TH1D* hDeDx       = calib->GetHistDeDx(kTRUE, 0);
+  TH1D* hDeDxE      = calib->GetHistDeDx(kFALSE, 0);
+
+  Double_t mdedx  = hDeDx->GetMean();
+  Double_t mdedxE = hDeDxE->GetMean();
+
+  TObjArray* helpArray = new TObjArray();
+
+  hDeDxVsNcl->FitSlicesY(0, 0, -1, 0, "QNR", helpArray);
+  TH1D* hMeanVsNcl =  (TH1D*)helpArray->At(1);
+  hMeanVsNcl->SetName("hMeanVsNcl");
+  hMeanVsNcl->SetMarkerStyle(29);
+  TH1D* hSigmaVsNcl =  (TH1D*)helpArray->At(2);
+  hSigmaVsNcl->SetName("hSigmaVsNcl");
+  hSigmaVsNcl->SetTitle("#sigma vs Ncl; Ncl; #sigma");
+  hSigmaVsNcl->SetMarkerStyle(29);
+  hSigmaVsNcl->SetMarkerColor(2);
+  hSigmaVsNcl->Scale(1.0/mdedx);
+
+  hDeDxVsNclE->FitSlicesY(0, 0, -1, 0, "QNR", helpArray);
+  TH1D* hMeanVsNclE =  (TH1D*)helpArray->At(1);
+  hMeanVsNclE->SetName("hSigmaVsNclE");
+  hMeanVsNclE->SetMarkerStyle(29);
+  TH1D* hSigmaVsNclE =  (TH1D*)helpArray->At(2);
+  hSigmaVsNclE->SetName("hSigmaVsNclE");
+  hSigmaVsNclE->SetTitle("#sigma vs Ncl; Ncl; #sigma");
+  hSigmaVsNclE->SetMarkerStyle(29);
+  hSigmaVsNclE->SetMarkerColor(kMagenta);
+  hSigmaVsNclE->Scale(1.0/mdedxE);
+
+  TLegend* legend = new TLegend(0.54, 0.67, 0.84, 0.87);
+  legend->SetFillColor(0);
+  legend->SetBorderSize(0);
+  legend->SetTextSize(0.05);
+  legend->AddEntry(hSigmaVsNcl, "MIP pions", "P");
+  legend->AddEntry(hSigmaVsNclE, "electrons", "P");
+
+  TCanvas* cTestDeDx = new TCanvas("cTestDeDx", "Comparing resolution for MIPs and electrons", 
+                                  1200, 400);
+  cTestDeDx->Clear();
+  cTestDeDx->Divide(3, 1);
+  
+  cTestDeDx->cd(1);
+  hDeDxVsNcl->Draw("COL");
+  hMeanVsNcl->Draw("SAME");
+
+  cTestDeDx->cd(2);
+  hDeDxVsNclE->Draw("COL");
+  hMeanVsNclE->Draw("SAME");
+
+  cTestDeDx->cd(3);
+  TF1* fSDedxVsNclSqrt = new TF1("fSDedxVsNclSqrt", "[0]*sqrt(159.0/x)",  0, 160);
+  fSDedxVsNclSqrt->SetParameter(0, 0.05);
+  hSigmaVsNcl->SetMinimum(0.0);
+  hSigmaVsNcl->SetMaximum(0.15);
+  hSigmaVsNcl->SetTitle("#sigma/<dE/dx> vs Ncl; Ncl; rel. #sigma");
+  //  hSigmaVsNcl->Fit(fSDedxVsNclSqrt);
+  hSigmaVsNcl->Draw();
+  hSigmaVsNclE->Draw("SAME");
+  legend->Draw();
+  gROOT->ProcessLine(".x drawText.C(2)");
+  TString baseName(gSystem->BaseName(calibFileName));
+  baseName.ReplaceAll(".root", "");
+  cTestDeDx->SaveAs(Form("results/calibplots/test_resolution_vs_dedx_%s.gif", baseName.Data())); 
+  cTestDeDx->SaveAs(Form("results/calibplots/test_resolution_vs_dedx_%s.pdf", baseName.Data()));   
+}  
+
+//___________________________________________________________________________________________
+void TestResolutionVsEta(const Char_t* calibFileName,
+                        Bool_t forMIP,
+                        Int_t run    = 0,
+                        Int_t filter = 1,
+                        Bool_t usePhiCut = kTRUE)
+{
+  gStyle->SetOptStat(0);
+  
+  TFile* calibFile = FindFileFresh(calibFileName);
+  if(!calibFile)
+    return;
+  AliHighPtDeDxCalib* calib = (AliHighPtDeDxCalib*)GetObject(calibFile, filter, usePhiCut, run);
+  calib->Print();
+  const Int_t nEta = 4;
+  Int_t color[nEta] = {kBlack, kBlue, kGreen+2, kRed};
+  TH1D* hDeDx[nEta] = {0, 0, 0, 0};
+  TH1D* hMeanVsNcl[nEta] = {0, 0, 0, 0};
+  TH1D* hSigmaVsNcl[nEta] = {0, 0, 0, 0};
+
+  const Double_t mdedx  = (calib->GetHistDeDx(forMIP, 0))->GetMean();
+  
+  TObjArray* helpArray = new TObjArray();
+  
+  for(Int_t bin = 1; bin <= nEta; bin++) {
+    
+    const Int_t i = bin - 1;
+    hDeDx[i]  = calib->GetHistDeDx(forMIP, bin);
+    hDeDx[i]->Scale(1.0/hDeDx[i]->GetEntries());
+    hDeDx[i]->SetMarkerStyle(24+i);
+    hDeDx[i]->SetMarkerColor(color[i]);
+
+    TH2D* hDeDxVsNcl  = calib->GetHistDeDxVsNcl(forMIP, bin);
+    hDeDxVsNcl->FitSlicesY(0, 0, -1, 0, "QNR", helpArray);
+
+    hMeanVsNcl[i] =  (TH1D*)helpArray->At(1);
+    hMeanVsNcl[i]->SetTitle("<dE/dx> vs Ncl; Ncl; #sigma");
+    hMeanVsNcl[i]->SetName(Form("hMeanVsNcl%d", bin));
+    hMeanVsNcl[i]->SetMarkerStyle(24+i);
+    hMeanVsNcl[i]->SetMarkerColor(color[i]);
+    hMeanVsNcl[i]->SetMinimum(mdedx*0.9);
+    hMeanVsNcl[i]->SetMaximum(mdedx*1.1);
+
+    hSigmaVsNcl[i] =  (TH1D*)helpArray->At(2);
+    hSigmaVsNcl[i]->SetName("hSigmaVsNcl");
+    hSigmaVsNcl[i]->SetTitle("#sigma/<dE/dx> vs Ncl; Ncl; rel. #sigma");
+    hSigmaVsNcl[i]->SetMarkerStyle(24+i);
+    hSigmaVsNcl[i]->SetMarkerColor(color[i]);
+    hSigmaVsNcl[i]->Scale(1.0/mdedx);
+    hSigmaVsNcl[i]->SetMinimum(0.0);
+    hSigmaVsNcl[i]->SetMaximum(0.15);
+  }
+
+  TLegend* legend = new TLegend(0.54, 0.67, 0.84, 0.87);
+  legend->SetFillColor(0);
+  legend->SetBorderSize(0);
+  legend->SetTextSize(0.05);
+  
+  legend->AddEntry(hDeDx[0], "|#eta|<0.2", "P");
+  legend->AddEntry(hDeDx[1], "0.2<|#eta|<0.4", "P");
+  legend->AddEntry(hDeDx[2], "0.4<|#eta|<0.6", "P");
+  legend->AddEntry(hDeDx[3], "0.6<|#eta|<0.8", "P");
+
+  TCanvas* cTestEta = new TCanvas("cTestEta", "Comparing resolution for MIPs and electrons", 
+                                  1200, 400);
+  cTestEta->Clear();
+  cTestEta->Divide(3, 1);
+  
+  for(Int_t i = 0; i < nEta; i++) {
+
+    cTestEta->cd(1);
+    if(i==0)
+      hDeDx[i]->Draw("P");
+    else
+      hDeDx[i]->Draw("SAME P");
+       
+    cTestEta->cd(2);
+    if(i==0)
+      hMeanVsNcl[i]->Draw("P");
+    else
+      hMeanVsNcl[i]->Draw("SAME P");
+
+    cTestEta->cd(3);
+    if(i==0) {
+      hSigmaVsNcl[i]->Draw("P");
+      legend->Draw();
+    } else
+      hSigmaVsNcl[i]->Draw("SAME P");
+  }
+
+  gROOT->ProcessLine(".x drawText.C(2)");
+  TString baseName(gSystem->BaseName(calibFileName));
+  baseName.ReplaceAll(".root", "");
+  cTestEta->SaveAs(Form("results/calibplots/test_resolution_vs_eta_%s.gif", baseName.Data())); 
+  cTestEta->SaveAs(Form("results/calibplots/test_resolution_vs_eta_%s.pdf", baseName.Data()));   
+}  
+  
+  // hMeanVsNcl =  (TH1D*)helpArray->At(1);
+  // hMeanVsNcl->SetName("hMeanVsNcl");
+  // hMeanVsNcl->SetTitle("Mean vs Ncl; Ncl; Mean");
+  // hMeanVsNcl->SetMarkerStyle(29);
+  // hMeanVsNcl->SetMinimum(45);
+  // hMeanVsNcl->SetMaximum(55);
+  
+  // if(isMC) {
+  //   hDeDxVsNclElectrons->FitSlicesY(0, 0, -1, 0, "QNR", helpArray);
+  //   hSigmaVsNclElectrons =  (TH1D*)helpArray->At(2);
+  //   hSigmaVsNclElectrons->SetName("hSigmaVsNcl");
+  //   hSigmaVsNclElectrons->SetTitle("#sigma vs Ncl; Ncl; #sigma");
+  //     }
+
+  //     TCanvas* cNcl2 = new TCanvas("cNcl2", "sigma dE/dx vs Ncl", 600, 400);
+  //     cNcl2->Clear();
+  //     cNcl2->cd();
+      
+  //     hSigmaVsNcl->DrawCopy();
+  //     hSigmaVsNcl->Fit(fSDeDxVsNcl, "0");
+  //     hSigmaVsNcl->Fit(fSDeDxVsNclSqrt, "0");
+      
+  //     fSDeDxVsNcl->DrawCopy("SAME");
+  //     fSDeDxVsNclSqrt->SetLineStyle(2);
+  //     fSDeDxVsNclSqrt->DrawCopy("SAME");
+
+  //     TLegend* legFit = new TLegend(0.64, 0.67, 0.84, 0.87);
+  //     legFit->SetFillColor(0);
+  //     legFit->SetBorderSize(0);
+  //     legFit->SetTextSize(0.05);
+  //     legFit->AddEntry(fSDeDxVsNcl, "Linear fit", "L");
+  //     legFit->AddEntry(fSDeDxVsNclSqrt, "1/Sqrt fit", "L");
+  //     legFit->Draw();
+
+  //     cNcl2->SaveAs(Form("%s/sigma_vs_ncl.gif", baseName.Data()));
+
+  //     if(isMC) {
+  //   TCanvas* cNcl2Electrons = new TCanvas("cNcl2Electrons", "sigma dE/dx vs Ncl (comparison)", 600, 400);
+  //   cNcl2Electrons->Clear();
+  //   cNcl2Electrons->cd();
+       
+  //   hSigmaVsNcl->SetMarkerStyle(29);
+  //   hSigmaVsNcl->DrawCopy();
+  //   hSigmaVsNclElectrons->Scale(50.0 / hDeDxVsEtaCalibratedElectrons->GetMean(2));
+  //   hSigmaVsNclElectrons->SetMarkerStyle(29);
+  //   hSigmaVsNclElectrons->SetMarkerColor(6);
+  //   hSigmaVsNclElectrons->DrawCopy("SAME");
+  //   fSDeDxVsNcl->DrawCopy("SAME");
+  //   fSDeDxVsNclSqrt->DrawCopy("SAME");
+       
+  //   TLegend* legSigma = new TLegend(0.64, 0.67, 0.84, 0.87);
+  //   legSigma->SetFillColor(0);
+  //   legSigma->SetBorderSize(0);
+  //   legSigma->SetTextSize(0.05);
+  //   legSigma->AddEntry(hSigmaVsNcl, "MIP pions", "P");
+  //   legSigma->AddEntry(fSDeDxVsNcl, "Linear fit", "L");
+  //   legSigma->AddEntry(fSDeDxVsNclSqrt, "1/Sqrt fit", "L");
+  //   legSigma->AddEntry(hSigmaVsNclElectrons, "Scaled electrons", "P");
+  //   legSigma->Draw();
+       
+  //   cNcl2Electrons->SaveAs(Form("%s/electrons_sigma_vs_ncl_comparison.gif", baseName.Data()));
+  //     }
+
+  //     TCanvas* cDeDx = new TCanvas("cDeDx", "dE/dx", 600, 400);
+  //     cDeDx->Clear();
+  //     hDeDx->Scale(1.0/hDeDx->GetEntries());
+  //     hDeDx->SetMarkerStyle(29);
+  //     hDeDx->DrawCopy();
+  //     TCanvas* cNcl3 = new TCanvas("cNcl3", "#sigma vs Ncl", 600, 400);
+  //     cNcl3->Clear();
+  //     hSigmaVsNcl->DrawCopy();
+  //     TCanvas* cNcl3Mean = new TCanvas("cNcl3Mean", "Mean vs Ncl", 600, 400);
+  //     cNcl3Mean->Clear();
+  //     hMeanVsNcl->DrawCopy();
+
+  //     TLegend* legDeDx = new TLegend(0.7, 0.67, 0.9, 0.87);
+  //     legDeDx->SetFillColor(0);
+  //     legDeDx->SetBorderSize(0);
+  //     legDeDx->SetTextSize(0.05);
+  //     legDeDx->AddEntry(hDeDx, "No #eta cut", "P");
+
+  //     TLegend* legScan = new TLegend(0.44, 0.67, 0.64, 0.87);
+  //     legScan->SetFillColor(0);
+  //     legScan->SetBorderSize(0);
+  //     legScan->SetTextSize(0.05);
+  //     legScan->AddEntry(hSigmaVsNcl, "No #eta cut", "P");
+
+  //     TH2D* hArray[4] = {hDeDxVsNcl0, hDeDxVsNcl1, hDeDxVsNcl2, hDeDxVsNcl3};
+  //     TH1D* hArrayDeDx[4] = {hDeDx0, hDeDx1, hDeDx3, hDeDx4};
+
+  //     Int_t color[4] = {2, kGreen+1, 4, 6};
+  //     Double_t x[4];
+  //     Double_t x_err[4];
+  //     Double_t slope[4];
+  //     Double_t slope_err[4];
+  //     Double_t offset[4];
+  //     Double_t offset_err[4];
+  //     for(Int_t i = 0; i < 4; i++) {
+
+  //   hArrayDeDx[i]->SetMarkerStyle(20);
+  //   hArrayDeDx[i]->SetMarkerColor(color[i]);
+  //   hArrayDeDx[i]->Scale(1.0/hArrayDeDx[i]->GetEntries());
+  //   cDeDx->cd();
+  //   hArrayDeDx[i]->DrawCopy("SAME");
+
+  //   x[i] = hMeanEta->GetBinContent(i+1);
+  //   x_err[i] = hMeanEta->GetBinError(i+1);
+
+  //   hArray[i]->FitSlicesY(0, 0, -1, 0, "QNR", helpArray);
+  //   hSigmaVsNclHelp =  (TH1D*)helpArray->At(2);
+  //   hSigmaVsNclHelp->SetName(Form("hSigmaVsNcl%d", i));
+  //   hSigmaVsNclHelp->SetTitle("#sigma vs Ncl; Ncl; #sigma");
+  //   hSigmaVsNclHelp->SetMarkerStyle(20);
+  //   hSigmaVsNclHelp->SetMarkerColor(color[i]);
+  //   hSigmaVsNclHelp->Fit(fSDeDxVsNclHelp, "0");
+  //   slope[i] = fSDeDxVsNclHelp->GetParameter(0);
+  //   slope_err[i] = fSDeDxVsNclHelp->GetParError(0);
+  //   offset[i] = fSDeDxVsNclHelp->GetParameter(1);
+  //   offset_err[i] = fSDeDxVsNclHelp->GetParError(1);
+  //   cNcl3->cd();
+  //   hSigmaVsNclHelp->DrawCopy("SAME");
+  //   //      fSDeDxVsNclHelp->DrawCopy("SAME");
+
+  //   if(i==0) {
+  //     legDeDx->AddEntry(hArrayDeDx[i], "|#eta|<0.2", "P");
+  //     legScan->AddEntry(hSigmaVsNclHelp, "|#eta|<0.2", "P");
+  //   } else if(i==1) {
+  //     legDeDx->AddEntry(hArrayDeDx[i], "0.2<|#eta|<0.4", "P");
+  //     legScan->AddEntry(hSigmaVsNclHelp, "0.2<|#eta|<0.4", "P");
+  //   } else if(i==2) {
+  //     legDeDx->AddEntry(hArrayDeDx[i], "0.4<|#eta|<0.6", "P");
+  //     legScan->AddEntry(hSigmaVsNclHelp, "0.4<|#eta|<0.6", "P");
+  //   } else if(i==3) {
+  //     legDeDx->AddEntry(hArrayDeDx[i], "0.6<|#eta|<0.8", "P");
+  //     legScan->AddEntry(hSigmaVsNclHelp, "0.6<|#eta|<0.8", "P");
+  //   }
+
+  //   cNcl3Mean->cd();
+  //   hMeanVsNclHelp =  (TH1D*)helpArray->At(1);
+  //   hMeanVsNclHelp->SetName(Form("hMeanVsNcl%d", i));
+  //   hMeanVsNclHelp->SetTitle("Mean vs Ncl; Ncl; Mean");
+  //   hMeanVsNclHelp->SetMarkerStyle(20);
+  //   hMeanVsNclHelp->SetMarkerColor(color[i]);
+  //   hMeanVsNclHelp->DrawCopy("SAME");
+  //     }
+
+  //     cDeDx->cd();
+  //     hDeDx->DrawCopy("SAME");
+  //     legDeDx->Draw();
+  //     cDeDx->SaveAs(Form("%s/dedx_resolution_vs_eta.gif", baseName.Data()));
+
+  //     cNcl3->cd();
+  //     hSigmaVsNcl->DrawCopy("SAME");
+  //     legScan->Draw();
+  //     cNcl3->SaveAs(Form("%s/sigma_vs_ncl_vs_eta.gif", baseName.Data()));
+
+  //     cNcl3Mean->cd();
+  //     hMeanVsNcl->DrawCopy("SAME");
+  //     legScan->Draw();
+  //     cNcl3Mean->SaveAs(Form("%s/mean_vs_ncl_vs_eta.gif", baseName.Data()));
+
+  //     TGraphErrors* graphSlope = new TGraphErrors(4, x, slope, x_err, slope_err);
+  //     graphSlope->SetTitle("slope vs <#eta>; <#eta>; slope");
+  //     graphSlope->SetMarkerStyle(29);
+  //     TCanvas* cNcl4 = new TCanvas("cNcl4", "Slope vs <eta>", 600, 400);
+  //     cNcl4->Clear();
+  //     graphSlope->Draw("AP");
+  //     cNcl4->SaveAs(Form("%s/fit_slope_vs_eta.gif", baseName.Data()));
+
+  //     TGraphErrors* graphOffset = new TGraphErrors(4, x, offset, x_err, offset_err);
+  //     graphOffset->SetMarkerStyle(29);
+  //     graphOffset->SetTitle("offset vs <#eta>; <#eta>; offset");
+  //     TCanvas* cNcl5 = new TCanvas("cNcl5", "Offset vs <eta>", 600, 400);
+  //     cNcl5->Clear();
+  //     graphOffset->Draw("AP");
+  //     cNcl5->SaveAs(Form("%s/fit_offset_vs_eta.gif", baseName.Data()));
+      
+  //   }
+
+//____________________________________________________________________________
+void CompareYields(const Char_t* dataFileName1,
+                  const Char_t* dataFileName2,
+                  Double_t ptStart, Double_t ptStop,
+                  const Char_t* endName1=0,
+                  const Char_t* endName2=0,
+                  Int_t run    = 0,
+                  Int_t filter = 1,
+                  Bool_t usePhiCut = kTRUE)
+{
+  gStyle->SetOptStat(0);
+
+  
+  TFile* dataFile1 = FindFileFresh(dataFileName1);
+  if(!dataFile1)
+    return;
+  AliHighPtDeDxCalib* data1 = (AliHighPtDeDxCalib*)GetObject(dataFile1, filter, usePhiCut, run, "filter", endName1);
+  data1->Print();
+
+  //  gSystem->Exec("mv debug/* olddebug/");
+
+
+  TH2D* hDeltaPiVsPt1 = data1->GetHistDeDxVsP(0);
+
+  AliHighPtDeDxCalib* data2 = data1;
+  if(dataFileName2) {
+    TFile* dataFile2 = FindFileFresh(dataFileName2);
+    if(!dataFile2)
+      return;
+    data2 = (AliHighPtDeDxCalib*)GetObject(dataFile2, filter, usePhiCut, run, "filter", endName2);
+    data2->Print();
+  } else if (endName2) {
+
+    data2 = (AliHighPtDeDxCalib*)GetObject(dataFile1, filter, usePhiCut, run, "filter", endName2);
+  }
+
+  TH2D* hDeltaPiVsPt2 = data2->GetHistDeDxVsP(0);
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeltaPiVsPt1->GetXaxis()->FindBin(ptStart+0.01);
+  ptStart = hDeltaPiVsPt1->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeltaPiVsPt1->GetXaxis()->FindBin(ptStop-0.01);
+  ptStop = hDeltaPiVsPt1->GetXaxis()->GetBinUpEdge(binStop);
+  //  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing fits from pTlow = " << ptStart << " (bin: " << binStart
+       << ") to pThigh = " << ptStop << " (bin: " << binStop << ")" << endl;
+  
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 4);
+
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    
+    TH1D* hDeltaPiVsPtProj1 =(TH1D*)hDeltaPiVsPt1->ProjectionY(Form("hDeltaPiVsPtProj1%d", bin), bin, bin);
+    //    hDeltaPiVsPtProj1->GetXaxis()->SetRangeUser(-20, 20);
+    hDeltaPiVsPtProj1->SetTitle(Form("%.1f<p<%.1f GeV/c", 
+                               hDeltaPiVsPt1->GetXaxis()->GetBinLowEdge(bin),
+                               hDeltaPiVsPt1->GetXaxis()->GetBinUpEdge(bin)));
+
+    TH1D* hDeltaPiVsPtProj2 =(TH1D*)hDeltaPiVsPt2->ProjectionY(Form("hDeltaPiVsPtProj2%d", bin), bin, bin);
+
+    hDeltaPiVsPtProj1->SetLineColor(4);
+    hDeltaPiVsPtProj2->SetLineColor(2);
+    hDeltaPiVsPtProj1->SetNormFactor();
+    hDeltaPiVsPtProj2->SetNormFactor();
+
+    cFits->cd();
+    cFits->cd(j + 1);
+    hDeltaPiVsPtProj1->DrawCopy();
+    hDeltaPiVsPtProj2->DrawCopy("SAME");
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    hDeltaPiVsPtProj1->DrawCopy();
+    hDeltaPiVsPtProj2->DrawCopy("SAME");
+
+    CreateDir("results/debug");
+    cSingleFit->SaveAs(Form("results/debug/ptspectrum_bin%d.gif", bin));
+  }
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/drawText.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/drawText.C
new file mode 100644 (file)
index 0000000..ac9a150
--- /dev/null
@@ -0,0 +1,12 @@
+void drawText(Int_t option=1)
+{
+  TLatex latex;
+  latex.SetNDC();
+  latex.SetTextSize(0.05);
+  if(option==1)
+      latex.DrawLatex(0.5, 0.95, "pp @ 7 TeV (LHC 10 b)");
+  else {
+    latex.SetTextAngle(90.0);
+    latex.DrawLatex(0.95, 0.2, "pp @ 7 TeV (LHC 10 b)");
+  }
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/draw_separation.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/draw_separation.C
new file mode 100644 (file)
index 0000000..722e85d
--- /dev/null
@@ -0,0 +1,163 @@
+#include <TFile.h>
+#include <TList.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <TClonesArray.h>
+#include <TObjString.h>
+#include <TString.h>
+#include <TROOT.h>
+#include <TLegend.h>
+#include <TStyle.h>
+#include <TCanvas.h>
+
+#include "my_tools.C"
+#include "my_functions.C"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+/*
+  To run calibrations:
+  ====================
+
+  Use root:
+
+  .L libMyDeDxAnalysis.so 
+  .L my_functions.C+
+  .L my_tools.C+
+  .L draw_separation.C+
+
+  DrawSeparation("fitparameters/lhc10h_aod_all.root", 0, 50)
+ */
+
+
+TF1* piFunc = 0;
+TF1* kFunc  = 0;
+TF1* pFunc = 0;
+TF1* sigmaFunc = 0;
+
+Double_t Sep(Double_t* xx, Double_t* par);
+
+//____________________________________________________________________________
+void DrawSeparation(const Char_t* fitFileName, Double_t pLow, Double_t pHigh)
+{
+  gStyle->SetOptStat(0);
+  
+  TFile* fitFile = FindFileFresh(fitFileName);
+  if(!fitFile)
+    return;
+  DeDxFitInfo* fitPar = (DeDxFitInfo*)fitFile->Get("fitInfo");
+  fitPar->Print();
+  
+  fixMIP      = fitPar->MIP;
+  fixPlateau  = fitPar->plateau;
+  
+  Double_t dedxPar[6]  = {0, 0, 0, 0, 0, 0};
+  Double_t sigmaPar[6] = {0, 0, 0, 0, 0, 0};
+  
+  dedxPar[0] = fitPar->optionDeDx;
+  for(Int_t i = 0; i < fitPar->nDeDxPar; i++) {
+    dedxPar[i+1] = fitPar->parDeDx[i];
+  }
+  
+  sigmaPar[0] = fitPar->optionSigma;
+  for(Int_t i = 0; i < fitPar->nSigmaPar; i++) {
+    sigmaPar[i+1] = fitPar->parSigma[i];
+  }
+  
+  piFunc = new TF1("piFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+  piFunc->SetParameters(dedxPar);
+  
+  kFunc = new TF1("kFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+  kFunc->SetParameters(dedxPar);
+  kFunc->SetParameter(0, kFunc->GetParameter(0)+10);
+  
+  pFunc = new TF1("pFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+  pFunc->SetParameters(dedxPar);
+  pFunc->SetParameter(0, pFunc->GetParameter(0)+20);
+  
+  sigmaFunc = new TF1("sigmaFunc", SigmaFunc, 0, 100, fitPar->nSigmaPar+1); 
+  sigmaFunc->SetParameters(sigmaPar);
+
+  TCanvas* c1 = new TCanvas("c1", "c1"); 
+  
+  TH1F* hist = new TH1F("hist", "Separation in pp vs p; p [GeV/c]; Separation",
+                       100, 0, pHigh);
+  hist->SetMinimum(0.0);
+  hist->SetMaximum(6.0);
+  hist->Draw();
+  
+  TLegend* legend = new TLegend(0.74, 0.64, 0.89, 0.89);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+
+  TF1* pipFunc = new TF1("pipFunc", Sep,
+                        pLow, pHigh, 1);
+  pipFunc->SetParameter(0, 0);
+  pipFunc->SetLineColor(2);
+  pipFunc->Draw("SAME");
+
+  TF1* pikFunc = new TF1("pikFunc", Sep,
+                        pLow, pHigh, 1);
+  pikFunc->SetParameter(0, 1);
+  pikFunc->SetLineColor(3);
+  pikFunc->Draw("SAME");
+
+  TF1* kpFunc = new TF1("kpFunc", Sep,
+                        pLow, pHigh, 1);
+  kpFunc->SetParameter(0, 2);
+  kpFunc->SetLineColor(4);
+  kpFunc->Draw("SAME");
+
+  legend->AddEntry(pipFunc, "#pi-p", "L");
+  legend->AddEntry(pikFunc, "#pi-K", "L");
+  legend->AddEntry(kpFunc, "K-p", "L");
+  legend->Draw();
+  gROOT->ProcessLine(".x drawText.C");
+  c1->SaveAs("separation.gif");
+  c1->SaveAs("separation.pdf");
+}
+  
+//______________________________________________________________________________
+Double_t Sep(Double_t* xx, Double_t* par)
+{
+  //
+  // Could speed up fit by forcing it to use <p>. In that way the parameters
+  // could be amde statis cand only changed when going to a new p bin
+  //
+  Double_t p = xx[0];
+
+  Int_t option = Int_t(par[0]);
+
+  TF1* f1 = 0;
+  TF1* f2 = 0;
+  switch (option) {
+    
+  case 0: // pi - p
+    f1 = piFunc;
+    f2 = pFunc;
+    break;
+  case 1: // pi - k
+    f1 = piFunc;
+    f2 = kFunc;
+    break;
+  case 2: // k - p
+    f1 = kFunc;
+    f2 = pFunc;
+    break;
+  default:
+    cout << "Error in Sep: option " << option << " not supported!!!!!" << endl;
+    return 0;
+    break;
+  }
+
+  Double_t dedx1  = f1->Eval(p);
+  Double_t dedx2  = f2->Eval(p);
+  Double_t sigma1 = sigmaFunc->Eval(dedx1);
+  Double_t sigma2 = sigmaFunc->Eval(dedx2);
+  
+  return (dedx1-dedx2)/TMath::Sqrt(sigma1*sigma2);
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/fit_yields_final.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/fit_yields_final.C
new file mode 100644 (file)
index 0000000..2502915
--- /dev/null
@@ -0,0 +1,1372 @@
+
+#include <TFile.h>
+#include <TH1.h>
+#include <TProfile.h>
+#include <TF1.h>
+#include <TGraphErrors.h>
+#include <TCanvas.h>
+#include <TAxis.h>
+#include <TLegend.h>
+#include <TStyle.h>
+#include <TGraphAsymmErrors.h>
+#include <TList.h>
+#include <TMath.h>
+#include <TSystem.h>
+#include <TLatex.h>
+#include <TF1.h>
+#include <TF2.h>
+
+#include "AliHighPtDeDxData.h"
+
+#include "my_tools.C"
+#include "my_functions.C"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+/*
+
+  To use:
+  =======
+  root is enough
+  
+  gSystem->AddIncludePath("-I../lib")
+  gSystem->AddIncludePath("-I../grid")
+  gSystem->AddIncludePath("-I../macros")
+  gROOT->SetMacroPath(".:../macros:../grid:../lib/")
+  .L libMyDeDxAnalysis.so 
+  .L my_functions.C+
+  .L my_tools.C+
+  .L fit_yields_final.C+
+
+  Step 6: Extract ratios = Final real step!
+  FitYields("data/7tev_b.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b.root", 0, "results/fits_final") 
+
+  Step 7: Compare positive and negative tracks
+  CompareYields("data/7tev_b.root", 0, 3.0, 20.0, 1, -1);
+
+  Step 8: Check that extracted positions match with 
+  FitYieldsV0("data/7tev_b.root", "data/7tev_b_v0_loose.root", "lambda", 3.0, 10.0) 
+  FitYieldsV0("data/7tev_b.root", "data/7tev_b_v0_loose.root", "kaon", 3.0, 10.0) 
+
+  Step 9: Check eta stability of fits
+
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_86.root", "eta-8-6", "results/eta86") 
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_64.root", "eta-6-4", "results/eta64") 
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_42.root", "eta-4-2", "results/eta42") 
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_20.root", "eta-20", "results/eta20") 
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_02.root", "eta02", "results/eta02") 
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_24.root", "eta24", "results/eta24") 
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_46.root", "eta46", "results/eta46") 
+  FitYields("data/7tev_b.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_68.root", "eta68", "results/eta68") 
+
+  Compare(3.1, "7tev_b");
+  Compare(5.1, "7tev_b");
+  Compare(7.1, "7tev_b");
+  Compare(9.1, "7tev_b");
+
+  There is a lot of other tests than can be done! One can have a look in an older version of this code in ../macros/fit_yields_old.C
+
+
+
+  //
+  // Test
+  //
+
+  Step 6: Extract ratios = Final real step!
+  FitYields("data/7tev_b_test.root", 3.0, 10.0, 0, kTRUE, 0, 1, kTRUE, "7tev_b_test.root", 0, "results/fits_final") 
+
+  Step 7: Check that extracted positions match with 
+  FitYieldsV0("data/7tev_b_test.root", "data/7tev_b_test_v0_loose.root", "lambda", 3.0, 10.0) 
+  FitYieldsV0("data/7tev_b_test.root", "data/7tev_b_test_v0_loose.root", "kaon", 3.0, 10.0) 
+
+ */
+
+void MakeRatios(const Char_t* file1Name, const Char_t* file2Name, 
+               Bool_t drawFractionRatios,
+               Bool_t drawYieldRatios);
+
+
+//____________________________________________________________________________
+void FitYields(const Char_t* dataFileName,
+              Double_t ptStart, Double_t ptStop,
+              Int_t charge,
+              Bool_t performFit = kFALSE,
+              Int_t run    = 0,
+              Int_t filter = 1,
+              Bool_t usePhiCut = kTRUE,
+              const Char_t* outFileName=0,
+              const Char_t* endName=0,
+              const Char_t* dirName="debugfits")
+{
+  gStyle->SetOptStat(0);
+
+  
+  TFile* dataFile = FindFileFresh(dataFileName);
+  if(!dataFile)
+    return;
+  AliHighPtDeDxData* data = (AliHighPtDeDxData*)GetObject(dataFile, filter, usePhiCut, run, "filter", endName);
+  data->Print();
+
+  TH2D* hDeltaPiVsPt = data->GetHistDeltaPiVsPt(0, charge);
+  hDeDxVsP = hDeltaPiVsPt; // for the 2d fit to pick up the right bin
+
+  TH2D* hDeltaPiVsPtPiGen = data->GetHistDeltaPiVsPt(1, charge);
+  TH2D* hDeltaPiVsPtKGen  = data->GetHistDeltaPiVsPt(2, charge);
+  TH2D* hDeltaPiVsPtPGen  = data->GetHistDeltaPiVsPt(3, charge);
+  TH2D* hDeltaPiVsPtEGen  = data->GetHistDeltaPiVsPt(4, charge);
+
+  TH2D* hDeltaPiVsPtPi = 0;
+  TH2D* hDeltaPiVsPtK  = 0;
+  TH2D* hDeltaPiVsPtP  = 0;
+
+  if(data->IsMc()) {
+
+    hDeltaPiVsPtPi = data->GetHistDeltaPiVsPtMc(1, charge);
+    hDeltaPiVsPtK  = data->GetHistDeltaPiVsPtMc(2, charge);
+    hDeltaPiVsPtP  = data->GetHistDeltaPiVsPtMc(3, charge);
+  }
+
+
+
+  TProfile* hPiGenProfile = hDeltaPiVsPtPiGen->ProfileX();
+  hPiGenProfile->SetMarkerStyle(29);
+  TProfile* hKGenProfile = hDeltaPiVsPtKGen->ProfileX();
+  hKGenProfile->SetMarkerStyle(29);
+  TProfile* hPGenProfile = hDeltaPiVsPtPGen->ProfileX();
+  hPGenProfile->SetMarkerStyle(29);
+  TProfile* hEGenProfile = hDeltaPiVsPtEGen->ProfileX();
+  hEGenProfile->SetMarkerStyle(29);
+
+  TCanvas* cDeltaPiVsPt = new TCanvas("cDeltaPiVsPt", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPt->Clear();
+  cDeltaPiVsPt->cd();
+  cDeltaPiVsPt->SetLogz();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+  hEGenProfile->Draw("SAME P");
+  gROOT->ProcessLine(".x drawText.C");
+  CreateDir(dirName);
+  cDeltaPiVsPt->SaveAs(Form("%s/deltapi_vs_pt.gif", dirName));
+  cDeltaPiVsPt->SaveAs(Form("%s/deltapi_vs_pt.pdf", dirName));
+
+  TCanvas* cDeltaPiVsPtLogX = new TCanvas("cDeltaPiVsPtLogX", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPtLogX->Clear();
+  cDeltaPiVsPtLogX->cd();
+  cDeltaPiVsPtLogX->SetLogz();
+  cDeltaPiVsPtLogX->SetLogx();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+  hEGenProfile->Draw("SAME P");
+  gROOT->ProcessLine(".x drawText.C");
+  cDeltaPiVsPtLogX->SaveAs(Form("%s/deltapi_vs_pt_logx.gif", dirName));
+  cDeltaPiVsPtLogX->SaveAs(Form("%s/deltapi_vs_pt_logx.pdf", dirName));
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeltaPiVsPt->GetXaxis()->FindBin(ptStart+0.01);
+  ptStart = hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeltaPiVsPt->GetXaxis()->FindBin(ptStop-0.01);
+  ptStop = hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(binStop);
+  //  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing fits from pTlow = " << ptStart << " (bin: " << binStart
+       << ") to pThigh = " << ptStop << " (bin: " << binStop << ")" << endl;
+  
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 4);
+
+  // TF1* pionGen = new TF1("pionGen", "[0]/sqrt(6.2832*[2]*[2])*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])", -30, 20);
+  // pionGen->SetLineWidth(2);
+  // pionGen->SetLineColor(kRed);
+
+  TF1* pion = new TF1("pion", "gausn", -30, 30);
+  pion->SetLineWidth(2);
+  pion->SetLineColor(kRed);
+  TF1* kaon = new TF1("kaon", "gausn", -30, 30);
+  kaon->SetLineWidth(2);
+  kaon->SetLineColor(kGreen);
+  TF1* proton = new TF1("proton", "gausn", -30, 30);
+  proton->SetLineWidth(2);
+  proton->SetLineColor(kBlue);
+  TF1* electron = new TF1("electron", "gausn", -30, 30);
+  electron->SetLineWidth(2);
+  electron->SetLineColor(kMagenta);
+  //  TF1* total = new TF1("total", "gausn(0)+gausn(3)+gausn(6)+gausn(9)", -30, 30);
+  TF1* total = new TF1("total", "([0]+[12])*gausn(1)+[4]*gausn(5)+[8]*gausn(9)+[12]*gausn(13)", -30, 30);
+  total->SetLineColor(kBlack);
+  total->SetLineWidth(2);
+  total->SetLineStyle(2);
+  
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(total, "4-Gauss fit", "L");
+  legend->AddEntry(pion, "#pi", "L");
+  legend->AddEntry(kaon, "K", "L");
+  legend->AddEntry(proton, "p", "L");
+  legend->AddEntry(electron, "e", "L");
+
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+  //  cSingleFit->SetLogy();
+
+  TH1D* hPionRatio =(TH1D*)hDeltaPiVsPt->ProjectionX("hPionRatio", 1, 1);
+  hPionRatio->SetTitle("particle fractions; p_{T} [GeV/c]; particle fraction");
+  hPionRatio->Reset();
+  TH1D* hKaonRatio   = (TH1D*)hPionRatio->Clone("hKaonRatio");
+  TH1D* hProtonRatio = (TH1D*)hPionRatio->Clone("hProtonRatio");
+  TH1D* hElectronRatio = (TH1D*)hPionRatio->Clone("hElectronRatio");
+  TH1D* hPionRatioMc = (TH1D*)hPionRatio->Clone("hPionRatioMc");
+  TH1D* hKaonRatioMc = (TH1D*)hPionRatio->Clone("hKaonRatioMc");
+  TH1D* hProtonRatioMc = (TH1D*)hPionRatio->Clone("hProtonRatioMc");
+
+  TH1D* hPionYield =(TH1D*)hDeltaPiVsPt->ProjectionX("hPionYield", 1, 1);
+  hPionYield->SetTitle("particle fractions; p_{T} [GeV/c]; particle fraction");
+  hPionYield->Reset();
+  TH1D* hKaonYield   = (TH1D*)hPionYield->Clone("hKaonYield");
+  TH1D* hProtonYield = (TH1D*)hPionYield->Clone("hProtonYield");
+  TH1D* hElectronYield = (TH1D*)hPionYield->Clone("hElectronYield");
+  TH1D* hPionYieldMc = (TH1D*)hPionYield->Clone("hPionYieldMc");
+  TH1D* hKaonYieldMc = (TH1D*)hPionYield->Clone("hKaonYieldMc");
+  TH1D* hProtonYieldMc = (TH1D*)hPionYield->Clone("hProtonYieldMc");
+
+  TF1* fElectronFraction = new TF1("fElectronFraction", "[0]+(x<10.0)*[1]*(x-10.0)", 0, ptStop);
+  fElectronFraction->SetParameters(0.01, 0.0);
+
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    
+    TH1D* hDeltaPiVsPtProj =(TH1D*)hDeltaPiVsPt->ProjectionY(Form("hDeltaPiVsPtProj%d", bin), bin, bin);
+    //    hDeltaPiVsPtProj->GetXaxis()->SetRangeUser(-25, 20);
+    hDeltaPiVsPtProj->GetXaxis()->SetRangeUser(-25, 30);
+    hDeltaPiVsPtProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                                   hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+                                   hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+    
+    Double_t all =  hDeltaPiVsPtProj->GetEntries();
+    
+    TH1D* hDeltaPiVsPtPiGenProj =(TH1D*)hDeltaPiVsPtPiGen->ProjectionY(Form("hDeltaPiVsPtPiGenProj%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtKGenProj =(TH1D*)hDeltaPiVsPtKGen->ProjectionY(Form("hDeltaPiVsPtKGenProj%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtPGenProj =(TH1D*)hDeltaPiVsPtPGen->ProjectionY(Form("hDeltaPiVsPtPGenProj%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtEGenProj =(TH1D*)hDeltaPiVsPtEGen->ProjectionY(Form("hDeltaPiVsPtEGenProj%d", bin), bin, bin);
+    
+
+    const Int_t nPar = 16;
+    Double_t gausParams[nPar] = { 
+      0.59,
+      all,
+      hDeltaPiVsPtPiGenProj->GetMean(), 
+      hDeltaPiVsPtPiGenProj->GetRMS(), 
+      0.3,
+      all,
+      hDeltaPiVsPtKGenProj->GetMean(), 
+      hDeltaPiVsPtKGenProj->GetRMS(), 
+      0.1,
+      all,
+      hDeltaPiVsPtPGenProj->GetMean(), 
+      hDeltaPiVsPtPGenProj->GetRMS(), 
+      0.01,
+      all,
+      hDeltaPiVsPtEGenProj->GetMean(), 
+      hDeltaPiVsPtEGenProj->GetRMS(), 
+    };
+    
+    cFits->cd();
+    cFits->cd(j + 1);
+    
+    total->SetParameters(gausParams);
+
+
+    for(Int_t i = 0; i < nPar; i++) {
+      
+      if((i%4) > 0)
+       total->FixParameter(i, gausParams[i]);
+    }
+
+    if(bin==50) {
+      hElectronRatio->Fit(fElectronFraction, "N", "", 3.0, 10.0);
+      fElectronFraction->SetRange(0, ptStop);
+    }
+
+    if(bin>=50) {
+      total->FixParameter(12, fElectronFraction->Eval(hDeltaPiVsPt->GetXaxis()->GetBinCenter(bin)));
+    }
+    
+    if(performFit) {
+      
+      hDeltaPiVsPtProj->Fit(total, "0L");
+      
+    } 
+    
+    hDeltaPiVsPtProj->Draw();
+    total->DrawCopy("same");    
+    
+    Double_t parametersOut[nPar];
+    total->GetParameters(parametersOut);
+    const Double_t* parameterErrorsOut = total->GetParErrors();
+
+    for(Int_t i = 0; i < nPar; i++) 
+      cout << parametersOut[i] << ", ";
+    cout << endl;
+
+
+    pion->SetParameters(&parametersOut[1]);
+    pion->SetParameter(0,all*(parametersOut[0]+parametersOut[12]));
+    pion->DrawCopy("same");
+    hPionRatio->SetBinContent(bin, parametersOut[0]);
+    hPionRatio->SetBinError(bin, parameterErrorsOut[0]);
+    hPionYield->SetBinContent(bin, parametersOut[0]*all);
+    hPionYield->SetBinError(bin, parameterErrorsOut[0]*all);
+
+    kaon->SetParameters(&parametersOut[5]);
+    kaon->SetParameter(0,all*parametersOut[4]);
+    kaon->DrawCopy("same");
+    hKaonRatio->SetBinContent(bin, parametersOut[4]);
+    hKaonRatio->SetBinError(bin, parameterErrorsOut[4]);
+    hKaonYield->SetBinContent(bin, parametersOut[4]*all);
+    hKaonYield->SetBinError(bin, parameterErrorsOut[4]*all);
+    
+    proton->SetParameters(&parametersOut[9]);
+    proton->SetParameter(0,all*parametersOut[8]);
+    proton->DrawCopy("same");
+    hProtonRatio->SetBinContent(bin, parametersOut[8]);
+    hProtonRatio->SetBinError(bin, parameterErrorsOut[8]);
+    hProtonYield->SetBinContent(bin, parametersOut[8]*all);
+    hProtonYield->SetBinError(bin, parameterErrorsOut[8]*all);
+
+    electron->SetParameters(&parametersOut[13]);
+    electron->SetParameter(0,all*parametersOut[12]);
+    electron->DrawCopy("same");
+    hElectronRatio->SetBinContent(bin, parametersOut[12]);
+    hElectronRatio->SetBinError(bin, parameterErrorsOut[12]);
+    hElectronYield->SetBinContent(bin, parametersOut[12]*all);
+    hElectronYield->SetBinError(bin, parameterErrorsOut[12]*all);
+
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    //    cSingleFit->SetLogy();
+    hDeltaPiVsPtProj->Draw();
+    pion->DrawCopy("same");
+    kaon->DrawCopy("same");
+    proton->DrawCopy("same");
+    electron->DrawCopy("same");
+    total->DrawCopy("same");
+    
+    if(bin==42 || bin==49) {
+
+      TFile* fileOut = new TFile(Form("%s/ptspectrum_bin%d.root", dirName, bin), "RECREATE");
+
+      TH1D* hist = (TH1D*)hDeltaPiVsPtProj->Clone("hist");
+
+      TF1* sumFit    = (TF1*)total->Clone("sumFit");
+      TF1* pionFit   = (TF1*)pion->Clone("pionFit");
+      TF1* kaonFit   = (TF1*)kaon->Clone("kaonFit");
+      TF1* protonFit = (TF1*)proton->Clone("protonFit");
+      TF1* electronFit = (TF1*)electron->Clone("electronFit");
+
+      hist->Write();
+
+      sumFit->Write();
+      pionFit->Write();
+      kaonFit->Write();
+      protonFit->Write();
+      electronFit->Write();
+
+      fileOut->Close();
+    }
+
+    gROOT->ProcessLine(".x drawText.C");
+    cSingleFit->SaveAs(Form("%s/ptspectrum_bin%d.gif", dirName, bin));
+    cSingleFit->SaveAs(Form("%s/ptspectrum_bin%d.pdf", dirName, bin));
+    //    legend->Draw();
+
+    if(data->IsMc()) {
+
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      TH1D* hDeltaPiVsPtPiProj =(TH1D*)hDeltaPiVsPtPi->ProjectionY(Form("hDeltaPiVsPtPiProj%d", bin), bin, bin);
+      hDeltaPiVsPtPiProj->SetMarkerStyle(20);
+      hDeltaPiVsPtPiProj->SetMarkerColor(2);
+      hDeltaPiVsPtPiProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                                       hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+                                       hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+      hDeltaPiVsPtPiProj->Draw("P");
+      Double_t integral = hDeltaPiVsPtPiProj->Integral();
+      hPionRatioMc->SetBinContent(bin, integral/all);
+      hPionRatioMc->SetBinError(bin, TMath::Sqrt(integral)/all);
+      hPionYieldMc->SetBinContent(bin, integral);
+      hPionYieldMc->SetBinError(bin, TMath::Sqrt(integral));
+      TH1D* hDeltaPiVsPtKProj =(TH1D*)hDeltaPiVsPtK->ProjectionY(Form("hDeltaPiVsPtKProj%d", bin), bin, bin);
+      hDeltaPiVsPtKProj->SetMarkerStyle(21);
+      hDeltaPiVsPtKProj->SetMarkerColor(3);
+      hDeltaPiVsPtKProj->Draw("SAME P");
+      integral = hDeltaPiVsPtKProj->Integral();
+      hKaonRatioMc->SetBinContent(bin, integral/all);
+      hKaonRatioMc->SetBinError(bin, TMath::Sqrt(integral)/all);
+      hKaonYieldMc->SetBinContent(bin, integral);
+      hKaonYieldMc->SetBinError(bin, TMath::Sqrt(integral));
+      TH1D* hDeltaPiVsPtPProj =(TH1D*)hDeltaPiVsPtP->ProjectionY(Form("hDeltaPiVsPtPProj%d", bin), bin, bin);
+      hDeltaPiVsPtPProj->SetMarkerStyle(22);
+      hDeltaPiVsPtPProj->SetMarkerColor(4);
+      hDeltaPiVsPtPProj->Draw("SAME P");
+      integral = hDeltaPiVsPtPProj->Integral();
+      hProtonRatioMc->SetBinContent(bin, integral/all);
+      hProtonRatioMc->SetBinError(bin, TMath::Sqrt(integral)/all);
+      hProtonYieldMc->SetBinContent(bin, integral);
+      hProtonYieldMc->SetBinError(bin, TMath::Sqrt(integral));
+
+      pion->DrawCopy("same");
+      kaon->DrawCopy("same");
+      proton->DrawCopy("same");
+      cSingleFit->SaveAs(Form("debugfitsmc/ptspectrum_bin%d.gif", bin));
+    }
+  }
+
+  TCanvas* cRatio = new TCanvas("cRatio", "ratios/all vs p", 600, 400);
+
+  cRatio->Clear();
+  cRatio->SetGridy();
+  hElectronRatio->GetYaxis()->SetRangeUser(-0.05, 0.1);
+  hElectronRatio->DrawCopy("P E");
+  fElectronFraction->DrawCopy("SAME");
+
+  gROOT->ProcessLine(".x drawText.C");
+  cRatio->SaveAs(Form("%s/electron_ratio.gif", dirName));
+  cRatio->SaveAs(Form("%s/electron_ratio.pdf", dirName));
+
+  cRatio->Clear();
+  cRatio->SetGridy(kFALSE);
+  hPionRatio->SetMarkerStyle(20);
+  hPionRatio->SetMarkerColor(2);
+  hPionRatio->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+  hPionRatio->GetYaxis()->SetRangeUser(0.0, 1.0);
+  hPionRatio->DrawCopy("P E");
+  hPionYield->SetMarkerStyle(20);
+  hPionYield->SetMarkerColor(2);
+  hPionYield->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+
+  hKaonRatio->SetMarkerStyle(20);
+  hKaonRatio->SetMarkerColor(3);
+  hKaonRatio->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+  hKaonRatio->DrawCopy("SAME P E");
+  hKaonYield->SetMarkerStyle(20);
+  hKaonYield->SetMarkerColor(3);
+  hKaonYield->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+
+  hProtonRatio->SetMarkerStyle(20);
+  hProtonRatio->SetMarkerColor(4);
+  hProtonRatio->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+  hProtonRatio->DrawCopy("SAME P E");
+  hProtonYield->SetMarkerStyle(20);
+  hProtonYield->SetMarkerColor(4);
+  hProtonYield->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+
+  hElectronRatio->SetMarkerStyle(20);
+  hElectronRatio->SetMarkerColor(6);
+  hElectronRatio->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+  hElectronRatio->DrawCopy("SAME P E");
+  hElectronYield->SetMarkerStyle(20);
+  hElectronYield->SetMarkerColor(6);
+  hElectronYield->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+
+  gROOT->ProcessLine(".x drawText.C");
+  cRatio->SaveAs(Form("%s/particle_ratios.gif", dirName));
+  cRatio->SaveAs(Form("%s/particle_ratios.pdf", dirName));
+
+  if(data->IsMc()) {
+    
+    hPionRatioMc->SetMarkerStyle(24);
+    hPionRatioMc->SetMarkerColor(2);
+    hPionRatioMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hPionYieldMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hPionYieldMc->SetMarkerStyle(24);
+    hPionYieldMc->SetMarkerColor(2);
+    hPionRatioMc->DrawCopy("SAME P");
+    
+    hKaonRatioMc->SetMarkerStyle(24);
+    hKaonRatioMc->SetMarkerColor(3);
+    hKaonRatioMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hKaonYieldMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hKaonYieldMc->SetMarkerStyle(24);
+    hKaonYieldMc->SetMarkerColor(3);
+    hKaonRatioMc->DrawCopy("SAME P");
+    
+    hProtonRatioMc->SetMarkerStyle(24);
+    hProtonRatioMc->SetMarkerColor(4);
+    hProtonRatioMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hProtonYieldMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hProtonYieldMc->SetMarkerStyle(24);
+    hProtonYieldMc->SetMarkerColor(4);
+    hProtonRatioMc->DrawCopy("SAME P");
+
+    cRatio->SaveAs("debugfitsmc/particle_ratios.gif");
+  }
+
+  if(outFileName) {
+
+    CreateDir("fit_yields_results");
+    TFile* fileOut = new TFile(Form("fit_yields_results/%s", outFileName), "RECREATE");
+
+    // Histograms for normalization
+    data->GetHistVtxStatus()->Write();
+    TH1D* hPhiCutEff = data->GetHistNclVsPhiVsPtAfter()->ProjectionX("hPhiCutEff");
+    TH1D* hHelp = data->GetHistNclVsPhiVsPtBefore()->ProjectionX("hHelp");
+    hPhiCutEff->Divide(hPhiCutEff, hHelp, 1.0, 1.0, "B");
+    hPhiCutEff->Write();
+    delete hHelp;
+    delete hPhiCutEff;
+
+    hPionRatio->Write();
+    hKaonRatio->Write();
+    hProtonRatio->Write();
+    hElectronRatio->Write();
+
+    hPionYield->Write();
+    hKaonYield->Write();
+    hProtonYield->Write();
+    hElectronYield->Write();
+
+    fElectronFraction->Write();
+
+    if(data->IsMc()) {
+      hPionRatioMc->Write();
+      hKaonRatioMc->Write();
+      hProtonRatioMc->Write();
+
+      hPionYieldMc->Write();
+      hKaonYieldMc->Write();
+      hProtonYieldMc->Write();                        
+    }
+
+    fileOut->Close();
+  }
+}
+
+//____________________________________________________________________________
+void FitYieldsV0(const Char_t* dataFileName,
+                const Char_t* v0FileName,
+                const Char_t* v0Name,
+                Double_t ptStart, Double_t ptStop,
+                Int_t charge = 0,
+                Bool_t performFit = kTRUE,
+                Int_t filter = 1,
+                Int_t run    = 0,
+                Bool_t usePhiCut = kTRUE,
+                const Char_t* endName=0)
+{
+  gStyle->SetOptStat(0);
+  
+  TFile* dataFile = FindFileFresh(dataFileName);
+  if(!dataFile)
+    return;
+  AliHighPtDeDxData* data = (AliHighPtDeDxData*)GetObject(dataFile, filter, usePhiCut, run, "filter", endName);
+  data->Print();
+
+  TFile* v0File = FindFileFresh(v0FileName);
+  if(!v0File)
+    return;
+  AliHighPtDeDxData* v0 = (AliHighPtDeDxData*)GetObject(v0File, 0, usePhiCut, run, v0Name, endName);
+  v0->Print();
+
+  TH2D* hDeltaPiVsPt = v0->GetHistDeltaPiVsPt(0, charge);
+  hDeDxVsP = hDeltaPiVsPt; // for the 2d fit to pick up the right bin
+
+  TH2D* hDeltaPiVsPtPiGen = data->GetHistDeltaPiVsPt(1, charge);
+  TH2D* hDeltaPiVsPtKGen  = data->GetHistDeltaPiVsPt(2, charge);
+  TH2D* hDeltaPiVsPtPGen  = data->GetHistDeltaPiVsPt(3, charge);
+
+  TProfile* hPiGenProfile = hDeltaPiVsPtPiGen->ProfileX();
+  hPiGenProfile->SetMarkerStyle(29);
+  TProfile* hKGenProfile = hDeltaPiVsPtKGen->ProfileX();
+  hKGenProfile->SetMarkerStyle(29);
+  TProfile* hPGenProfile = hDeltaPiVsPtPGen->ProfileX();
+  hPGenProfile->SetMarkerStyle(29);
+
+  TCanvas* cDeltaPiVsPt = new TCanvas("cDeltaPiVsPt", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPt->Clear();
+  cDeltaPiVsPt->cd();
+  cDeltaPiVsPt->SetLogz();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+
+  TCanvas* cDeltaPiVsPtLogX = new TCanvas("cDeltaPiVsPtLogX", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPtLogX->Clear();
+  cDeltaPiVsPtLogX->cd();
+  cDeltaPiVsPtLogX->SetLogz();
+  cDeltaPiVsPtLogX->SetLogx();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeltaPiVsPt->GetXaxis()->FindBin(ptStart+0.01);
+  ptStart = hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeltaPiVsPt->GetXaxis()->FindBin(ptStop-0.01);
+  ptStop = hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(binStop);
+  //  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing fits from pTlow = " << ptStart << " (bin: " << binStart
+       << ") to pThigh = " << ptStop << " (bin: " << binStop << ")" << endl;
+  
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 4);
+
+  TF1* pion = new TF1("pion", "[0]/sqrt(6.2832*[2]*[2])*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])", -30, 20);
+    //  TF1* pion = new TF1("pion", "gausn", -30, 20);
+  pion->SetLineWidth(2);
+  pion->SetLineColor(kRed);
+  // TF1* kaon = new TF1("kaon", "gausn", -30, 20);
+  // kaon->SetLineWidth(2);
+  // kaon->SetLineColor(kGreen);
+  TF1* proton = new TF1("proton", "[0]/sqrt(6.2832*[2]*[2])*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])", -30, 20);
+  //  TF1* proton = new TF1("proton", "gausn", -30, 20);
+  proton->SetLineWidth(2);
+  proton->SetLineColor(kBlue);
+
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(pion, "#pi", "L");
+  //  legend->AddEntry(kaon, "K", "L");
+  legend->AddEntry(proton, "p", "L");
+
+  if(strstr(v0Name, "lambda")) {
+    gSystem->Exec("mv debugfitslambda/* olddebugfitslambda/");
+  } else {
+    gSystem->Exec("mv debugfitskaon/* olddebugfitskaon/");
+  }
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    
+    TH1D* hDeltaPiVsPtProj =(TH1D*)hDeltaPiVsPt->ProjectionY(Form("hDeltaPiVsPtProj%d", bin), bin, bin);
+    //    hDeltaPiVsPtProj->GetXaxis()->SetRangeUser(40, 85);
+    hDeltaPiVsPtProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                               hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+                               hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+
+    Double_t all =  hDeltaPiVsPtProj->GetEntries();
+
+    TH1D* hDeltaPiVsPtPiGenProj =(TH1D*)hDeltaPiVsPtPiGen->ProjectionY(Form("hDeltaPiVsPtPiGenProj%d", bin), bin, bin);
+    //    TH1D* hDeltaPiVsPtKGenProj =(TH1D*)hDeltaPiVsPtKGen->ProjectionY(Form("hDeltaPiVsPtKGenProj%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtPGenProj =(TH1D*)hDeltaPiVsPtPGen->ProjectionY(Form("hDeltaPiVsPtPGenProj%d", bin), bin, bin);
+    
+    cFits->cd();
+    cFits->cd(j + 1);
+
+    hDeltaPiVsPtProj->Draw();
+
+    if(strstr(v0Name, "lambda")) {
+    
+      Double_t mean  = hDeltaPiVsPtPGenProj->GetMean();
+      Double_t sigma = hDeltaPiVsPtPGenProj->GetRMS();
+
+      cout << "Bin: " << bin 
+          <<   " (" << hDeltaPiVsPtProj->GetTitle()                            
+          << "), sigma: " << sigma << endl;
+      proton->SetParameters(all, mean, sigma);
+      proton->FixParameter(1, mean);
+      proton->FixParameter(2, sigma);
+
+      if(performFit) {
+       
+       hDeltaPiVsPtProj->Fit(proton, "L0", "", mean-sigma, mean+sigma);
+       
+       cout << "Bin: " << bin 
+            <<   " (" << hDeltaPiVsPtProj->GetTitle()                          
+            << "), sigma: " << proton->GetParameter(2) << endl;
+      } 
+
+      proton->DrawCopy("same");
+
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      hDeltaPiVsPtProj->Draw();
+      proton->DrawCopy("same");
+    } else {
+
+      Double_t mean  = hDeltaPiVsPtPiGenProj->GetMean();
+      Double_t sigma = hDeltaPiVsPtPiGenProj->GetRMS();
+      cout << "Bin: " << bin 
+          <<   " (" << hDeltaPiVsPtProj->GetTitle()                            
+          << "), sigma: " << sigma << endl;
+      pion->SetParameters(all, mean, sigma);
+      pion->FixParameter(1, mean);
+      pion->FixParameter(2, sigma);
+      
+      if(performFit) {
+       
+       hDeltaPiVsPtProj->Fit(pion, "L0", "", mean-sigma, mean+sigma);
+
+       cout << "Bin: " << bin 
+            <<   " (" << hDeltaPiVsPtProj->GetTitle()                          
+            << "), sigma: " << pion->GetParameter(2) << endl;  
+      } 
+      pion->DrawCopy("same");
+
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      hDeltaPiVsPtProj->Draw();
+      pion->DrawCopy("same");
+    }
+    
+    //    cSingleFit->SetLogy();
+    
+    gROOT->ProcessLine(".x drawText.C");
+
+    if(strstr(v0Name, "lambda")) {
+
+      if(!endName) {
+       CreateDir("results/lambda");
+       cSingleFit->SaveAs(Form("results/lambda/ptspectrum_bin%d.gif", bin));
+       cSingleFit->SaveAs(Form("results/lambda/ptspectrum_bin%d.pdf", bin));
+      } else {
+       CreateDir(Form("results%s/lambda", endName));
+       cSingleFit->SaveAs(Form("results/lambda%s/ptspectrum_bin%d.gif", endName, bin));
+       cSingleFit->SaveAs(Form("results/lambda%s/ptspectrum_bin%d.pdf", endName, bin));
+      }
+    } else {
+      if(!endName) {
+       CreateDir("results/kaon");
+       cSingleFit->SaveAs(Form("results/kaon/ptspectrum_bin%d.gif", bin));
+       cSingleFit->SaveAs(Form("results/kaon/ptspectrum_bin%d.pdf", bin));
+      }else {
+       CreateDir(Form("results%s/kaons", endName));
+       cSingleFit->SaveAs(Form("results/kaon%s/ptspectrum_bin%d.gif", endName, bin));
+       cSingleFit->SaveAs(Form("results/kaon%s/ptspectrum_bin%d.pdf", endName, bin));
+      }
+    }
+    //    legend->Draw();
+  }
+
+}
+
+//____________________________________________________________________________
+void CompareYields(const Char_t* dataFileName1,
+                  const Char_t* dataFileName2,
+                  Double_t ptStart, Double_t ptStop,
+                  Int_t charge1,
+                  Int_t charge2,
+                  const Char_t* endName1=0,
+                  const Char_t* endName2=0,
+                  Bool_t performFit = kFALSE,
+                  Int_t run    = 0,
+                  Int_t filter = 1,
+                  Bool_t usePhiCut = kTRUE)
+{
+  gStyle->SetOptStat(0);
+
+  
+  TFile* dataFile1 = FindFileFresh(dataFileName1);
+  if(!dataFile1)
+    return;
+  AliHighPtDeDxData* data1 = (AliHighPtDeDxData*)GetObject(dataFile1, filter, usePhiCut, run, "filter", endName1);
+  data1->Print();
+
+  gSystem->Exec("mv debugfits/* olddebugfits/");
+  gSystem->Exec("mv debugfitsratio/* olddebugfitsratio/");
+  // if(data1->IsMc())
+  //   gSystem->Exec("mv debugfitsmc/* olddebugfitsmc/");
+
+
+  TH2D* hDeltaPiVsPt1 = data1->GetHistDeltaPiVsPt(0, charge1);
+  hDeDxVsP = hDeltaPiVsPt1; // for the 2d fit to pick up the right bin
+
+  TH2D* hDeltaPiVsPtPiGen1 = data1->GetHistDeltaPiVsPt(1, charge1);
+  TH2D* hDeltaPiVsPtKGen1  = data1->GetHistDeltaPiVsPt(2, charge1);
+  TH2D* hDeltaPiVsPtPGen1  = data1->GetHistDeltaPiVsPt(3, charge1);
+
+  // TH2D* hDeltaPiVsPtPi1 = 0;
+  // TH2D* hDeltaPiVsPtK1  = 0;
+  // TH2D* hDeltaPiVsPtP1  = 0;
+
+  // if(data1->IsMc()) {
+
+  //   hDeltaPiVsPtPi1 = data1->GetHistDeltaPiVsPtPiMc();
+  //   hDeltaPiVsPtK1  = data1->GetHistDeltaPiVsPtKMc();
+  //   hDeltaPiVsPtP1  = data1->GetHistDeltaPiVsPtPMc();
+  // }
+
+  AliHighPtDeDxData* data2 = data1;
+  if(dataFileName2) {
+    TFile* dataFile2 = FindFileFresh(dataFileName2);
+    if(!dataFile2)
+      return;
+    data2 = (AliHighPtDeDxData*)GetObject(dataFile2, filter, usePhiCut, run, "filter", endName2);
+    data2->Print();
+  } else if (endName2) {
+
+    data2 = (AliHighPtDeDxData*)GetObject(dataFile1, filter, usePhiCut, run, "filter", endName2);
+  }
+
+  TH2D* hDeltaPiVsPt2 = data2->GetHistDeltaPiVsPt(0, charge2);
+  hDeDxVsP = hDeltaPiVsPt2; // for the 2d fit to pick up the right bin
+
+  // TH2D* hDeltaPiVsPtPiGen2 = data2->GetHistDeltaPiVsPt(1, charge2);
+  // TH2D* hDeltaPiVsPtKGen2  = data2->GetHistDeltaPiVsPt(2, charge2);
+  // TH2D* hDeltaPiVsPtPGen2  = data2->GetHistDeltaPiVsPt(3, charge2);
+
+  // TH2D* hDeltaPiVsPtPi2 = 0;
+  // TH2D* hDeltaPiVsPtK2  = 0;
+  // TH2D* hDeltaPiVsPtP2  = 0;
+
+  // if(data2->IsMc()) {
+
+  //   hDeltaPiVsPtPi2 = data2->GetHistDeltaPiVsPtPiMc();
+  //   hDeltaPiVsPtK2  = data2->GetHistDeltaPiVsPtKMc();
+  //   hDeltaPiVsPtP2  = data2->GetHistDeltaPiVsPtPMc();
+  // }
+
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeltaPiVsPt1->GetXaxis()->FindBin(ptStart+0.01);
+  ptStart = hDeltaPiVsPt1->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeltaPiVsPt1->GetXaxis()->FindBin(ptStop-0.01);
+  ptStop = hDeltaPiVsPt1->GetXaxis()->GetBinUpEdge(binStop);
+  //  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing fits from pTlow = " << ptStart << " (bin: " << binStart
+       << ") to pThigh = " << ptStop << " (bin: " << binStop << ")" << endl;
+  
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 4);
+
+  TF1* pion = new TF1("pion", "gausn", -30, 20);
+  pion->SetLineWidth(2);
+  pion->SetLineColor(kRed);
+  TF1* kaon = new TF1("kaon", "gausn", -30, 20);
+  kaon->SetLineWidth(2);
+  kaon->SetLineColor(kGreen);
+  TF1* proton = new TF1("proton", "gausn", -30, 20);
+  proton->SetLineWidth(2);
+  proton->SetLineColor(kBlue);
+  TF1* total = new TF1("total", "gausn(0)+gausn(3)+gausn(6)", -30, 20);
+  total->SetLineColor(kBlack);
+  total->SetLineWidth(2);
+  total->SetLineStyle(2);
+
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(total, "3-Gauss fit", "L");
+  legend->AddEntry(pion, "#pi", "L");
+  legend->AddEntry(kaon, "K", "L");
+  legend->AddEntry(proton, "p", "L");
+
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    
+    TH1D* hDeltaPiVsPtProj1 =(TH1D*)hDeltaPiVsPt1->ProjectionY(Form("hDeltaPiVsPtProj1%d", bin), bin, bin);
+    hDeltaPiVsPtProj1->GetXaxis()->SetRangeUser(-25, 20);
+    hDeltaPiVsPtProj1->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                               hDeltaPiVsPt1->GetXaxis()->GetBinLowEdge(bin),
+                               hDeltaPiVsPt1->GetXaxis()->GetBinUpEdge(bin)));
+
+    TH1D* hDeltaPiVsPtProj2 =(TH1D*)hDeltaPiVsPt2->ProjectionY(Form("hDeltaPiVsPtProj2%d", bin), bin, bin);
+
+    Double_t all1 =  hDeltaPiVsPtProj1->GetEntries();
+
+    TH1D* hDeltaPiVsPtPiGenProj1 =(TH1D*)hDeltaPiVsPtPiGen1->ProjectionY(Form("hDeltaPiVsPtPiGenProj1%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtKGenProj1 =(TH1D*)hDeltaPiVsPtKGen1->ProjectionY(Form("hDeltaPiVsPtKGenProj1%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtPGenProj1 =(TH1D*)hDeltaPiVsPtPGen1->ProjectionY(Form("hDeltaPiVsPtPGenProj1%d", bin), bin, bin);
+    
+    Double_t gausParams[9] = { 
+      0.6*all1,
+      hDeltaPiVsPtPiGenProj1->GetMean(), 
+      hDeltaPiVsPtPiGenProj1->GetRMS(), 
+      0.2*all1,
+      hDeltaPiVsPtKGenProj1->GetMean(), 
+      hDeltaPiVsPtKGenProj1->GetRMS(), 
+      0.2*all1,
+      hDeltaPiVsPtPGenProj1->GetMean(), 
+      hDeltaPiVsPtPGenProj1->GetRMS(), 
+    };
+
+    cFits->cd();
+    cFits->cd(j + 1);
+
+    total->SetParameters(gausParams);
+    for(Int_t i = 0; i < 9; i++) {
+
+      if((i%3) > 0)
+       total->FixParameter(i, gausParams[i]);
+    }
+    
+    if(performFit) {
+
+      hDeltaPiVsPtProj1->Fit(total, "0L");
+
+    } 
+
+    hDeltaPiVsPtProj1->SetLineColor(4);
+    hDeltaPiVsPtProj2->SetLineColor(2);
+    hDeltaPiVsPtProj1->DrawCopy();
+    hDeltaPiVsPtProj2->DrawCopy("SAME");
+    if(performFit)
+      total->DrawCopy("same");    
+    
+    Double_t parametersOut[9];
+    total->GetParameters(parametersOut);
+    //    const Double_t* parameterErrorsOut = total->GetParErrors();
+
+    for(Int_t i = 0; i < 9; i++) 
+      cout << parametersOut[i] << ", ";
+    cout << endl;
+
+
+    if(performFit) {
+      pion->SetParameters(&parametersOut[0]);
+      pion->DrawCopy("same");
+      
+      kaon->SetParameters(&parametersOut[3]);
+      kaon->DrawCopy("same");
+      
+      proton->SetParameters(&parametersOut[6]);
+      proton->DrawCopy("same");
+    }
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    //    cSingleFit->SetLogy();
+    hDeltaPiVsPtProj1->DrawCopy();
+    hDeltaPiVsPtProj2->DrawCopy("SAME");
+    if(performFit) {
+      pion->DrawCopy("same");
+      kaon->DrawCopy("same");
+      proton->DrawCopy("same");
+      total->DrawCopy("same");
+    }
+
+    cSingleFit->SaveAs(Form("debugfits/ptspectrum_bin%d.gif", bin));
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    //    cSingleFit->SetLogy();
+    hDeltaPiVsPtProj1->Divide(hDeltaPiVsPtProj2);
+    hDeltaPiVsPtProj1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hDeltaPiVsPtProj1->DrawCopy();
+
+    cSingleFit->SaveAs(Form("debugfitsratio/ptspectrum_bin%d.gif", bin));
+    //    legend->Draw();
+
+    // if(data->IsMc()) {
+
+    //   cSingleFit->cd();
+    //   cSingleFit->Clear();
+    //   TH1D* hDeltaPiVsPtPiProj =(TH1D*)hDeltaPiVsPtPi->ProjectionY(Form("hDeltaPiVsPtPiProj%d", bin), bin, bin);
+    //   hDeltaPiVsPtPiProj->SetMarkerStyle(20);
+    //   hDeltaPiVsPtPiProj->SetMarkerColor(2);
+    //   hDeltaPiVsPtPiProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+    //                                         hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+    //                                         hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+    //   hDeltaPiVsPtPiProj->Draw("P");
+    //   hPionRatioMc->SetBinContent(bin, hDeltaPiVsPtPiProj->Integral()/all);
+    //   hPionYieldMc->SetBinContent(bin, hDeltaPiVsPtPiProj->Integral());
+    //   TH1D* hDeltaPiVsPtKProj =(TH1D*)hDeltaPiVsPtK->ProjectionY(Form("hDeltaPiVsPtKProj%d", bin), bin, bin);
+    //   hDeltaPiVsPtKProj->SetMarkerStyle(21);
+    //   hDeltaPiVsPtKProj->SetMarkerColor(3);
+    //   hDeltaPiVsPtKProj->Draw("SAME P");
+    //   hKaonRatioMc->SetBinContent(bin, hDeltaPiVsPtKProj->Integral()/all);
+    //   hKaonYieldMc->SetBinContent(bin, hDeltaPiVsPtKProj->Integral());
+    //   TH1D* hDeltaPiVsPtPProj =(TH1D*)hDeltaPiVsPtP->ProjectionY(Form("hDeltaPiVsPtPProj%d", bin), bin, bin);
+    //   hDeltaPiVsPtPProj->SetMarkerStyle(22);
+    //   hDeltaPiVsPtPProj->SetMarkerColor(4);
+    //   hDeltaPiVsPtPProj->Draw("SAME P");
+    //   hProtonRatioMc->SetBinContent(bin, hDeltaPiVsPtPProj->Integral()/all);
+    //   hProtonYieldMc->SetBinContent(bin, hDeltaPiVsPtPProj->Integral());
+
+    //   pion->DrawCopy("same");
+    //   kaon->DrawCopy("same");
+    //   proton->DrawCopy("same");
+    //   cSingleFit->SaveAs(Form("debugfitsmc/ptspectrum_bin%d.gif", bin));
+    // }
+  }
+}
+
+//___________________________________________________________________________________________
+void MakeRatios(const Char_t* file1Name, const Char_t* file2Name, 
+               Bool_t drawFractionRatios,
+               Bool_t drawYieldRatios)
+{
+  /*
+    For yields we assume that file 1 is negative charge and file
+    2 is positive charge.
+   */
+  
+  TFile* file1 = FindFileFresh(file1Name);
+  if(!file1)
+    return;
+  
+  TH1D* hPionRatio1   = (TH1D*)file1->Get("hPionRatio");
+  TH1D* hKaonRatio1   = (TH1D*)file1->Get("hKaonRatio");
+  TH1D* hProtonRatio1 = (TH1D*)file1->Get("hProtonRatio");
+
+  TH1D* hPionYield1   = (TH1D*)file1->Get("hPionYield");
+  TH1D* hKaonYield1   = (TH1D*)file1->Get("hKaonYield");
+  TH1D* hProtonYield1 = (TH1D*)file1->Get("hProtonYield");
+
+  TH1D* hPionRatioMc1   = (TH1D*)file1->Get("hPionRatioMc");
+  TH1D* hKaonRatioMc1   = (TH1D*)file1->Get("hKaonRatioMc");
+  TH1D* hProtonRatioMc1 = (TH1D*)file1->Get("hProtonRatioMc");
+
+  TH1D* hPionYieldMc1   = (TH1D*)file1->Get("hPionYieldMc");
+  TH1D* hKaonYieldMc1   = (TH1D*)file1->Get("hKaonYieldMc");
+  TH1D* hProtonYieldMc1 = (TH1D*)file1->Get("hProtonYieldMc");
+
+  TFile* file2 = FindFileFresh(file2Name);
+  if(!file2)
+    return;
+  
+  TH1D* hPionRatio2   = (TH1D*)file2->Get("hPionRatio");
+  TH1D* hKaonRatio2   = (TH1D*)file2->Get("hKaonRatio");
+  TH1D* hProtonRatio2 = (TH1D*)file2->Get("hProtonRatio");
+
+  TH1D* hPionYield2   = (TH1D*)file2->Get("hPionYield");
+  TH1D* hKaonYield2   = (TH1D*)file2->Get("hKaonYield");
+  TH1D* hProtonYield2 = (TH1D*)file2->Get("hProtonYield");
+
+  TH1D* hPionRatioMc2   = (TH1D*)file2->Get("hPionRatioMc");
+  TH1D* hKaonRatioMc2   = (TH1D*)file2->Get("hKaonRatioMc");
+  TH1D* hProtonRatioMc2 = (TH1D*)file2->Get("hProtonRatioMc");
+
+  TH1D* hPionYieldMc2   = (TH1D*)file2->Get("hPionYieldMc");
+  TH1D* hKaonYieldMc2   = (TH1D*)file2->Get("hKaonYieldMc");
+  TH1D* hProtonYieldMc2 = (TH1D*)file2->Get("hProtonYieldMc");
+  
+  hPionRatio1->Divide(hPionRatio2);
+  hPionRatio1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hPionRatio1->SetTitle("Xcheck: pion fraction ratios; p_{T} [GeV/c]; pion fraction ratio");
+
+  hKaonRatio1->Divide(hKaonRatio2);
+  hKaonRatio1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hKaonRatio1->SetTitle("Xcheck: kaon fraction ratios; p_{T} [GeV/c]; kaon fraction ratio");
+
+  hProtonRatio1->Divide(hProtonRatio2);
+  hProtonRatio1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hProtonRatio1->SetTitle("Xcheck: proton fraction ratios; p_{T} [GeV/c]; proton fraction ratio");
+
+  hPionYield1->Divide(hPionYield2);
+  hPionYield1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hPionYield1->SetTitle("#pi^{-}/#pi^{+} vs p_{T}; p_{T} [GeV/c]; #pi^{-}/#pi^{+}");
+
+  hKaonYield1->Divide(hKaonYield2);
+  hKaonYield1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hKaonYield1->SetTitle("K^{-}/K^{+} vs p_{T}; p_{T} [GeV/c]; K^{-}/K^{+}");
+
+  hProtonYield1->Divide(hProtonYield2);
+  hProtonYield1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hProtonYield1->SetTitle("#bar{p}/p vs p_{T}; p_{T} [GeV/c]; #bar{p}/p");
+
+  if(hPionRatioMc1) {
+    hPionRatioMc1->Divide(hPionRatioMc2);
+    hPionRatioMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hPionRatioMc1->SetTitle("Xcheck: pion fraction ratios (MC TRUTH); p_{T} [GeV/c]; pion fraction ratio");
+    
+    hKaonRatioMc1->Divide(hKaonRatioMc2);
+    hKaonRatioMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hKaonRatioMc1->SetTitle("Xcheck: kaon fraction ratios (MC TRUTH); p_{T} [GeV/c]; kaon fraction ratio");
+    
+    hProtonRatioMc1->Divide(hProtonRatioMc2);
+    hProtonRatioMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hProtonRatioMc1->SetTitle("Xcheck: proton fraction ratios (MC TRUTH); p_{T} [GeV/c]; proton fraction ratio");
+    
+    hPionYieldMc1->Divide(hPionYieldMc2);
+    hPionYieldMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hPionYieldMc1->SetTitle("#pi^{-}/#pi^{+} vs p_{T} (MC TRUTH); p_{T} [GeV/c]; #pi^{-}/#pi^{+}");
+    
+    hKaonYieldMc1->Divide(hKaonYieldMc2);
+    hKaonYieldMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hKaonYieldMc1->SetTitle("K^{-}/K^{+} vs p_{T} (MC TRUTH); p_{T} [GeV/c]; K^{-}/K^{+}");
+    
+    hProtonYieldMc1->Divide(hProtonYieldMc2);
+    hProtonYieldMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hProtonYieldMc1->SetTitle("#bar{p}/p vs p_{T} (MC TRUTH); p_{T} [GeV/c]; #bar{p}/p");
+  }
+
+  if(drawFractionRatios) {
+    TCanvas* cPionFractionRatio = new TCanvas("cPionFractionRatio", "pion fraction ratio", 400, 300);
+    cPionFractionRatio->Clear();
+    cPionFractionRatio->SetGridy();
+    cPionFractionRatio->cd();
+    hPionRatio1->Draw();
+    cPionFractionRatio->SaveAs("results/fits_w_e/pion_frac_ratio.gif");
+
+    TCanvas* cKaonFractionRatio = new TCanvas("cKaonFractionRatio", "kaon fraction ratio", 400, 300);
+    cKaonFractionRatio->Clear();
+    cKaonFractionRatio->SetGridy();
+    cKaonFractionRatio->cd();
+    hKaonRatio1->Draw();
+    cKaonFractionRatio->SaveAs("kaon_frac_ratio.gif");
+
+    TCanvas* cProtonFractionRatio = new TCanvas("cProtonFractionRatio", "proton fraction ratio", 400, 300);
+    cProtonFractionRatio->Clear();
+    cProtonFractionRatio->SetGridy();
+    cProtonFractionRatio->cd();
+    hProtonRatio1->Draw();
+    cProtonFractionRatio->SaveAs("proton_frac_ratio.gif");
+
+    if(hPionRatioMc1) {
+      TCanvas* cPionFractionRatioMc = new TCanvas("cPionFractionRatioMc", "pion fraction ratio", 400, 300);
+      cPionFractionRatioMc->Clear();
+      cPionFractionRatioMc->SetGridy();
+      cPionFractionRatioMc->cd();
+      hPionRatioMc1->Draw();
+      cPionFractionRatioMc->SaveAs("pion_frac_ratio_mc.gif");
+      
+      TCanvas* cKaonFractionRatioMc = new TCanvas("cKaonFractionRatioMc", "kaon fraction ratio", 400, 300);
+      cKaonFractionRatioMc->Clear();
+      cKaonFractionRatioMc->SetGridy();
+      cKaonFractionRatioMc->cd();
+      hKaonRatioMc1->Draw();
+      cKaonFractionRatioMc->SaveAs("kaon_frac_ratio_mc.gif");
+      
+      TCanvas* cProtonFractionRatioMc = new TCanvas("cProtonFractionRatioMc", "proton fraction ratio", 400, 300);
+      cProtonFractionRatioMc->Clear();
+      cProtonFractionRatioMc->SetGridy();
+      cProtonFractionRatioMc->cd();
+      hProtonRatioMc1->Draw();
+      cProtonFractionRatioMc->SaveAs("proton_frac_ratio_mc.gif");
+    }
+  }
+  
+  if(drawYieldRatios) {
+    TCanvas* cPionRatio = new TCanvas("cPionRatio", "pion yields ratio", 400, 300);
+    cPionRatio->Clear();
+    cPionRatio->cd();
+    cPionRatio->SetGridy();
+    hPionYield1->Draw();
+    cPionRatio->SaveAs("pion_ratio.gif");
+
+    TCanvas* cKaonRatio = new TCanvas("cKaonRatio", "kaon yields ratio", 400, 300);
+    cKaonRatio->Clear();
+    cKaonRatio->cd();
+    cKaonRatio->SetGridy();
+    hKaonYield1->Draw();
+    cKaonRatio->SaveAs("kaon_ratio.gif");
+
+    TCanvas* cProtonRatio = new TCanvas("cProtonRatio", "proton yields ratio", 400, 300);
+    cProtonRatio->Clear();
+    cProtonRatio->cd();
+    cProtonRatio->SetGridy();
+    hProtonYield1->Draw();
+    cProtonRatio->SaveAs("proton_ratio.gif");
+
+    if(hPionRatioMc1) {
+      
+      TCanvas* cPionRatioMc = new TCanvas("cPionRatioMc", "pion yields ratio", 400, 300);
+      cPionRatioMc->Clear();
+      cPionRatioMc->cd();
+      cPionRatioMc->SetGridy();
+      hPionYieldMc1->Draw();
+      cPionRatioMc->SaveAs("pion_ratio_mc.gif");
+      
+      TCanvas* cKaonRatioMc = new TCanvas("cKaonRatioMc", "kaon yields ratio", 400, 300);
+      cKaonRatioMc->Clear();
+      cKaonRatioMc->cd();
+      cKaonRatioMc->SetGridy();
+      hKaonYieldMc1->Draw();
+      cKaonRatioMc->SaveAs("kaon_ratio_mc.gif");
+      
+      TCanvas* cProtonRatioMc = new TCanvas("cProtonRatioMc", "proton yields ratio", 400, 300);
+      cProtonRatioMc->Clear();
+      cProtonRatioMc->cd();
+      cProtonRatioMc->SetGridy();
+      hProtonYieldMc1->Draw();
+      cProtonRatioMc->SaveAs("proton_ratio_mc.gif");
+    }
+  }
+}
+
+//___________________________________________________________________________________________
+void Compare(const Char_t* file1Name, const Char_t* file2Name, const Char_t* file3Name, 
+            const Char_t* legend2, const Char_t* legend3, const Char_t* outfilename)
+{
+  /*
+    filename1 is the default
+   */
+  
+  TLegend* legend = new TLegend(0.11, 0.68, 0.35, 0.88);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+
+  TFile* file1 = FindFileFresh(file1Name);
+  if(!file1)
+    return;
+  
+  TH1D* hPionRatio1   = (TH1D*)file1->Get("hPionRatio");
+  hPionRatio1->SetMarkerStyle(29);
+  TH1D* hPionRatio1Clone = (TH1D*)hPionRatio1->Clone("hPionsRatio1Clone");
+  hPionRatio1Clone->SetMarkerColor(1);
+  legend->AddEntry(hPionRatio1Clone, "default", "P");
+  TH1D* hKaonRatio1   = (TH1D*)file1->Get("hKaonRatio");
+  hKaonRatio1->SetMarkerStyle(29);
+  TH1D* hProtonRatio1 = (TH1D*)file1->Get("hProtonRatio");
+  hProtonRatio1->SetMarkerStyle(29);
+
+  TFile* file2 = FindFileFresh(file2Name);
+  if(!file2)
+    return;
+  
+  TH1D* hPionRatio2   = (TH1D*)file2->Get("hPionRatio");
+  hPionRatio2->SetMarkerStyle(20);
+  TH1D* hPionRatio2Clone = (TH1D*)hPionRatio2->Clone("hPionsRatio2Clone");
+  hPionRatio2Clone->SetMarkerColor(1);
+  legend->AddEntry(hPionRatio2Clone, legend2, "P");
+  TH1D* hKaonRatio2   = (TH1D*)file2->Get("hKaonRatio");
+  hKaonRatio2->SetMarkerStyle(20);
+  TH1D* hProtonRatio2 = (TH1D*)file2->Get("hProtonRatio");
+  hProtonRatio2->SetMarkerStyle(20);
+
+  TFile* file3 = FindFileFresh(file3Name);
+  if(!file3)
+    return;
+  
+  TH1D* hPionRatio3   = (TH1D*)file3->Get("hPionRatio");
+  hPionRatio3->SetMarkerStyle(24);
+  TH1D* hPionRatio3Clone = (TH1D*)hPionRatio3->Clone("hPionsRatio3Clone");
+  hPionRatio3Clone->SetMarkerColor(1);
+  legend->AddEntry(hPionRatio3Clone, legend3, "P");
+  TH1D* hKaonRatio3   = (TH1D*)file3->Get("hKaonRatio");
+  hKaonRatio3->SetMarkerStyle(24);
+  TH1D* hProtonRatio3 = (TH1D*)file3->Get("hProtonRatio");
+  hProtonRatio3->SetMarkerStyle(24);
+
+  TCanvas* cRatios = new TCanvas("cRatios", "pion fraction ratio", 400, 300);
+  cRatios->Clear();
+  cRatios->SetGridy();
+  cRatios->cd();
+  hPionRatio1->Draw("EP");
+  hKaonRatio1->Draw("SAME EP");
+  hProtonRatio1->Draw("SAME EP");
+  hPionRatio2->Draw("HIST SAME P");
+  hKaonRatio2->Draw("HIST SAME P");
+  hProtonRatio2->Draw("HIST SAME P");
+  hPionRatio3->Draw("HIST SAME P");
+  hKaonRatio3->Draw("HIST SAME P");
+  hProtonRatio3->Draw("HIST SAME P");
+  legend->Draw();
+  gROOT->ProcessLine(".x drawText.C");
+  cRatios->SaveAs(Form("%s.gif", outfilename));
+  cRatios->SaveAs(Form("%s.pdf", outfilename));
+  
+}
+
+//___________________________________________________________________________________________
+void Compare(Double_t x, const Char_t* baseName)
+{
+  /*
+    filename1 is the default
+   */
+  gStyle->SetOptStat(0);
+
+  TCanvas* cRatios = new TCanvas("cRatios", "Ratios", 400, 300);
+
+  const Int_t nEtaBins = 8;
+  Double_t etaLimits[nEtaBins+1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8};
+
+  TGraphErrors* graphPionFractions = new TGraphErrors(nEtaBins);
+  graphPionFractions->SetMarkerStyle(29);
+  graphPionFractions->SetMarkerColor(2);
+
+  TGraphErrors* graphKaonFractions = new TGraphErrors(nEtaBins);
+  graphKaonFractions->SetMarkerStyle(29);
+  graphKaonFractions->SetMarkerColor(3);
+
+  TGraphErrors* graphProtonFractions = new TGraphErrors(nEtaBins);
+  graphProtonFractions->SetMarkerStyle(29);
+  graphProtonFractions->SetMarkerColor(4);
+
+  TH1F* hHelp = new TH1F("hHelp", "particle fractions vs #eta; #eta; particle fraction",
+                        nEtaBins, etaLimits[0], etaLimits[nEtaBins]);
+  hHelp->SetMinimum(0.0);
+  hHelp->SetMaximum(1.0);
+  hHelp->SetDirectory(0);
+
+  for(Int_t i = 0; i < nEtaBins; i++) {
+
+    Double_t etaCenter = (etaLimits[i] + etaLimits[i+1])/2.0;
+    Double_t etaWidth  = TMath::Abs(etaCenter - etaLimits[i]);
+
+    Int_t etaLow  = Int_t(TMath::Abs(etaLimits[i]*10.0));
+    Int_t etaHigh = Int_t(TMath::Abs(etaLimits[i+1]*10.0));
+
+    cout << etaCenter << ", " << etaWidth << ", " << etaLow << ", " << etaHigh << endl;
+
+    TFile* file = FindFileFresh(Form("fit_yields_results/%s_%d%d.root", 
+                                    baseName, etaLow, etaHigh));
+    if(!file)
+      return;
+    
+    TH1D* hPionRatio   = (TH1D*)file->Get("hPionRatio");
+
+    Int_t bin = hPionRatio->FindBin(x);
+    if(i==0)
+      hHelp->SetTitle(Form("%s (%.1f<p_{T}<%.1f GeV/c)", 
+                          hHelp->GetTitle(),
+                          hPionRatio->GetXaxis()->GetBinLowEdge(bin),
+                          hPionRatio->GetXaxis()->GetBinUpEdge(bin)));
+
+    
+    graphPionFractions->SetPoint(i, etaCenter, hPionRatio->GetBinContent(bin)); 
+    graphPionFractions->SetPointError(i, etaWidth, hPionRatio->GetBinError(bin)); 
+    
+    TH1D* hKaonRatio   = (TH1D*)file->Get("hKaonRatio");
+    graphKaonFractions->SetPoint(i, etaCenter, hKaonRatio->GetBinContent(bin)); 
+    graphKaonFractions->SetPointError(i, etaWidth, hKaonRatio->GetBinError(bin)); 
+
+    TH1D* hProtonRatio = (TH1D*)file->Get("hProtonRatio");
+    graphProtonFractions->SetPoint(i, etaCenter, hProtonRatio->GetBinContent(bin)); 
+    graphProtonFractions->SetPointError(i, etaWidth, hProtonRatio->GetBinError(bin));     
+  }
+  
+
+  cRatios->Clear();
+  cRatios->cd();
+  hHelp->DrawCopy();
+  graphPionFractions->Draw("P");
+  graphKaonFractions->Draw("P");
+  graphProtonFractions->Draw("P");
+  gROOT->ProcessLine(".x drawText.C(2)");
+  CreateDir("results/eta_fine");
+  cRatios->SaveAs(Form("results/eta_fine/ratios_vs_eta_%d.gif", Int_t(x)));
+  cRatios->SaveAs(Form("results/eta_fine/ratios_vs_eta_%d.pdf", Int_t(x)));
+  
+  delete hHelp;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/fit_yields_old.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/fit_yields_old.C
new file mode 100644 (file)
index 0000000..f1c5aae
--- /dev/null
@@ -0,0 +1,1459 @@
+
+#include <TFile.h>
+#include <TH1.h>
+#include <TProfile.h>
+#include <TF1.h>
+#include <TGraphErrors.h>
+#include <TCanvas.h>
+#include <TAxis.h>
+#include <TLegend.h>
+#include <TStyle.h>
+#include <TGraphAsymmErrors.h>
+#include <TList.h>
+#include <TMath.h>
+#include <TSystem.h>
+#include <TLatex.h>
+#include <TF1.h>
+#include <TF2.h>
+
+#include "AliHighPtDeDxData.h"
+
+#include "my_tools.C"
+#include "my_functions.C"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+/*
+  Ideas to improve:
+  =================
+
+  Use the real mean p -> Might give some effect
+  Effect: Push the <dE/dx> down (let'a see if it is still needed in the fits)
+
+  Use the real <nCl> 
+  Effect: Increase sigma for p<15. For p>15 seems to saturate.
+  
+  To use:
+  =======
+  root is enough
+  .L libMyDeDxAnalysis.so 
+  .L my_tools.C+
+  .L my_functions.C+
+  .L fit_yields.C+
+
+
+  mkdir results
+  mkdir results/fits
+  mkdir results/eta04
+  mkdir results/eta48
+  mkdir results/etaneg
+  mkdir results/etapos
+  mkdir results/neg
+  mkdir results/pos
+  mkdir results/comparison
+  mkdir results/kaon
+  mkdir results/lambda
+
+
+  *********************
+       ALL ETAS
+  *********************
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all.root", 0, "results/fits") 
+
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, -1, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_neg.root", 0, "results/neg") 
+
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, +1, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_pos.root", 0, "results/pos") 
+
+  Compare("fit_yields_results/lhc10h_aod_all.root", "fit_yields_results/lhc10h_aod_all_neg.root", "fit_yields_results/lhc10h_aod_all_pos.root", "q<0", "q>0", "results/comparison/neg_vs_pos")
+
+  CompareYields("data/lhc10h_aod_all.root", 0, 3.0, 20.0, -1, +1, 0, 0, kFALSE, 0, 1, kFALSE)
+
+
+
+  *********************
+     ETA LOW & HIGH
+  *********************
+
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_low.root", "etaabs04", "results/eta04") 
+
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_high.root", "etaabs48", "results/eta48") 
+
+  Compare("fit_yields_results/lhc10h_aod_all.root", "fit_yields_results/lhc10h_aod_all_eta_low.root", "fit_yields_results/lhc10h_aod_all_eta_high.root", "|#eta|<0.4", "0.4<|#eta|<0.8", "results/comparison/low_vs_high")
+
+  CompareYields("data/lhc10h_aod_all.root", 0, 3.0, 20.0, 0, 0, "etaabs04", "etaabs48")
+
+
+  *********************
+     ETA NEG & POS
+  *********************
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_neg.root", "eta-80", "results/etaneg") 
+
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_pos.root", "eta08", "results/etapos") 
+
+  Compare("fit_yields_results/lhc10h_aod_all.root", "fit_yields_results/lhc10h_aod_all_eta_neg.root", "fit_yields_results/lhc10h_aod_all_eta_pos.root", "#eta < 0", "#eta > 0", "results/comparison/etaneg_vs_etapos")
+
+  CompareYields("data/lhc10h_aod_all.root", 0, 3.0, 20.0, 0, 0, "eta-80", "eta08")
+
+
+  *********************
+     V0 ETA LOW & HIGH
+  *********************
+  FitYieldsV0("data/lhc10h_aod_all.root", "data/lhc10h_v0_all_loose.root", "kaon", 3.0, 20.0, 0, kTRUE, 1, 0, kTRUE, "etaabs04") 
+  FitYieldsV0("data/lhc10h_aod_all.root", "data/lhc10h_v0_all_loose.root", "kaon", 3.0, 20.0, 0, kTRUE, 1, 0, kTRUE, "etaabs48") 
+  FitYieldsV0("data/lhc10h_aod_all.root", "data/lhc10h_v0_all_loose.root", "lambda", 3.0, 20.0, 0, kTRUE, 1, 0, kTRUE, "etaabs04") 
+  FitYieldsV0("data/lhc10h_aod_all.root", "data/lhc10h_v0_all_loose.root", "lambda", 3.0, 20.0, 0, kTRUE, 1, 0, kTRUE, "etaabs48") 
+
+  *********************
+
+  *********************
+     ETA FINE
+  *********************
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_86.root", "eta-8-6", "results/eta86") 
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_64.root", "eta-6-4", "results/eta64") 
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_42.root", "eta-4-2", "results/eta42") 
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_20.root", "eta-20", "results/eta20") 
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_02.root", "eta02", "results/eta02") 
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_24.root", "eta24", "results/eta24") 
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_46.root", "eta46", "results/eta46") 
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE, 0, 1, kTRUE, "lhc10h_aod_all_eta_68.root", "eta68", "results/eta68") 
+
+  Compare(3.1)
+  Compare(5.1)
+  Compare(7.1)
+  Compare(9.1)
+
+ FitYields("data/lhc10h_mc_aod_all.root", 3.0, 20.0, 0, kTRUE)   
+
+  FitYields("data/lhc10h_aod_test.root", 3.0, 20.0, 0, kTRUE)
+
+  FitYields("data/lhc10h_aod_all.root", 3.0, 20.0, 0, kTRUE)
+
+  FitYieldsV0("data/lhc10h_aod_all.root", "data/lhc10h_v0_all_loose.root", "kaon", 3.0, 20.0, 0, kTRUE)
+  FitYieldsV0("data/lhc10h_aod_all.root", "data/lhc10h_v0_all_loose.root", "lambda", 3.0, 20.0, 0, kTRUE)
+
+
+
+  MakeRatios("../ptspectraPP/fit_yields_results/lhc10h_aod_all_neg.root", "../ptspectraPP/fit_yields_results/lhc10h_aod_all_pos.root", "../ptspectraPP/results/comparison/")
+
+  MakeRatios("../ptspectraPbPb_60_80/fit_yields_results/lhc10h_aod_all_neg.root", "../ptspectraPbPb_60_80/fit_yields_results/lhc10h_aod_all_pos.root", "../ptspectraPbPb_60_80/results/comparison/")
+
+  MakeRatios("../ptspectraPbPb_40_60/fit_yields_results/lhc10h_aod_all_neg.root", "../ptspectraPbPb_40_60/fit_yields_results/lhc10h_aod_all_pos.root", "../ptspectraPbPb_40_60/results/comparison/")
+
+  MakeRatios("../ptspectraPbPb_20_40/fit_yields_results/lhc10h_aod_all_neg.root", "../ptspectraPbPb_20_40/fit_yields_results/lhc10h_aod_all_pos.root", "../ptspectraPbPb_20_40/results/comparison/")
+
+  MakeRatios("../ptspectraPbPb_10_20/fit_yields_results/lhc10h_aod_all_neg.root", "../ptspectraPbPb_10_20/fit_yields_results/lhc10h_aod_all_pos.root", "../ptspectraPbPb_10_20/results/comparison/")
+
+  MakeRatios("../ptspectraPbPb_0_5/fit_yields_results/lhc10h_aod_all_neg.root", "../ptspectraPbPb_0_5/fit_yields_results/lhc10h_aod_all_pos.root", "../ptspectraPbPb_0_5/results/comparison/")
+
+  MakeRatios("fit_yields_results/lhc10h_aod_all_neg.root", "fit_yields_results/lhc10h_aod_all_pos.root", "results/comparison/")
+
+
+ */
+
+void MakeRatios(const Char_t* file1Name, const Char_t* file2Name, 
+               Bool_t drawFractionRatios,
+               Bool_t drawYieldRatios);
+
+
+//___________________________________________________________________________________________
+void MakeRatios(const Char_t* fileNeg, const Char_t* filePos, 
+               const Char_t* outdirname)
+{
+  /*
+    For yields we assume that file 1 is negative charge and file
+    2 is positive charge.
+   */
+  
+  TFile* file1 = FindFileFresh(fileNeg);
+  if(!file1)
+    return;
+  
+  TH1D* hPionRatio1   = (TH1D*)file1->Get("hPionYield");
+  SetHistError(hPionRatio1, 0.0);
+  // TH1D* hKaonRatio1   = (TH1D*)file1->Get("hKaonRatio");
+  // TH1D* hProtonRatio1 = (TH1D*)file1->Get("hProtonRatio");
+
+
+  TFile* file2 = FindFileFresh(filePos);
+  if(!file2)
+    return;
+  
+  TH1D* hPionRatio2   = (TH1D*)file2->Get("hPionYield");
+  // TH1D* hKaonRatio2   = (TH1D*)file2->Get("hKaonRatio");
+  // TH1D* hProtonRatio2 = (TH1D*)file2->Get("hProtonRatio");
+
+  
+  TH1D* hPionAssymetry = (TH1D*)hPionRatio1->Clone("hPionAssymetry");
+  hPionAssymetry->Divide(hPionRatio2);
+  TF1 f1("f1", "-1.0", 0.0, 50.0);
+  hPionAssymetry->Add(&f1); // correct for muons and electrons
+  CutHistogram(hPionAssymetry, 3.0, 20.0);
+  hPionAssymetry->GetYaxis()->SetRangeUser(-0.25, 0.25);
+  hPionAssymetry->SetTitle("Syst. error evaluation: Assymetry; p_{T} [GeV/c]; pion assymmetry: (neg-pos)/pos");
+  
+  
+  hPionRatio1->Divide(hPionRatio2);
+  hPionRatio1->GetYaxis()->SetRangeUser(0.75, 1.25);
+  hPionRatio1->SetTitle("Syst. error evaluation: Ratio; p_{T} [GeV/c]; pion fraction ratio: neg/pos");
+
+
+  TCanvas* cPionFractionRatio = new TCanvas("cPionFractionRatio", "pion fraction ratio", 400, 300);
+  cPionFractionRatio->Clear();
+  cPionFractionRatio->SetGridy();
+  cPionFractionRatio->cd();
+  hPionRatio1->Draw();
+  if(strstr(fileNeg, "PP"))
+    gROOT->ProcessLine(".x ../ptspectraPP/drawText.C");
+  else if(strstr(fileNeg, "0_5"))
+    gROOT->ProcessLine(".x ../ptspectraPbPb_0_5/drawText.C");
+  else if(strstr(fileNeg, "5_10"))
+    gROOT->ProcessLine(".x ../ptspectraPbPb_5_10/drawText.C");
+  else if(strstr(fileNeg, "10_20"))
+    gROOT->ProcessLine(".x ../ptspectraPbPb_10_20/drawText.C");
+  else if(strstr(fileNeg, "20_40"))
+    gROOT->ProcessLine(".x ../ptspectraPbPb_20_40/drawText.C");
+  else if(strstr(fileNeg, "40_60"))
+    gROOT->ProcessLine(".x ../ptspectraPbPb_40_60/drawText.C");
+  else if(strstr(fileNeg, "60_80"))
+    gROOT->ProcessLine(".x ../ptspectraPbPb_60_80/drawText.C");
+
+  cPionFractionRatio->SaveAs(Form("%s/pion_frac_ratio_neg_over_pos.gif", outdirname));
+  cPionFractionRatio->SaveAs(Form("%s/pion_frac_ratio_neg_over_pos.pdf", outdirname));
+
+
+  // TCanvas* cPionAssymetry = new TCanvas("cPionAssymetry", "pion fraction assymetry", 400, 300);
+  // cPionAssymetry->Clear();
+  // cPionAssymetry->SetGridy();
+  // cPionAssymetry->cd();
+  // hPionAssymetry->Draw();
+  // if(strstr(fileNeg, "PP"))
+  //   gROOT->ProcessLine(".x ../ptspectraPP/drawText.C");
+  // else if(strstr(fileNeg, "0_5"))
+  //   gROOT->ProcessLine(".x ../ptspectraPbPb_0_5/drawText.C");
+  // else if(strstr(fileNeg, "5_10"))
+  //   gROOT->ProcessLine(".x ../ptspectraPbPb_5_10/drawText.C");
+  // else if(strstr(fileNeg, "10_20"))
+  //   gROOT->ProcessLine(".x ../ptspectraPbPb_10_20/drawText.C");
+  // else if(strstr(fileNeg, "20_40"))
+  //   gROOT->ProcessLine(".x ../ptspectraPbPb_20_40/drawText.C");
+  // else if(strstr(fileNeg, "40_60"))
+  //   gROOT->ProcessLine(".x ../ptspectraPbPb_40_60/drawText.C");
+  // else if(strstr(fileNeg, "60_80"))
+  //   gROOT->ProcessLine(".x ../ptspectraPbPb_60_80/drawText.C");
+  // cPionAssymetry->SaveAs(Form("%s/pion_assymetry_between_neg_and_pos.gif", outdirname));
+  // cPionAssymetry->SaveAs(Form("%s/pion_assymetry_between_neg_and_pos.pdf", outdirname));  
+
+
+}
+
+//____________________________________________________________________________
+void FitYields(const Char_t* dataFileName,
+              Double_t ptStart, Double_t ptStop,
+              Int_t charge,
+              Bool_t performFit = kFALSE,
+              Int_t run    = 0,
+              Int_t filter = 1,
+              Bool_t usePhiCut = kTRUE,
+              const Char_t* outFileName=0,
+              const Char_t* endName=0,
+              const Char_t* dirName="debugfits")
+{
+  gStyle->SetOptStat(0);
+
+  
+  TFile* dataFile = FindFileFresh(dataFileName);
+  if(!dataFile)
+    return;
+  AliHighPtDeDxData* data = (AliHighPtDeDxData*)GetObject(dataFile, filter, usePhiCut, run, "filter", endName);
+  data->Print();
+
+  gSystem->Exec(Form("mv %s/* old/", dirName));
+  if(data->IsMc())
+    gSystem->Exec("mv debugfitsmc/* olddebugfitsmc/");
+
+
+  TH2D* hDeltaPiVsPt = data->GetHistDeltaPiVsPt(0, charge);
+  hDeDxVsP = hDeltaPiVsPt; // for the 2d fit to pick up the right bin
+
+  TH2D* hDeltaPiVsPtPiGen = data->GetHistDeltaPiVsPt(1, charge);
+  TH2D* hDeltaPiVsPtKGen  = data->GetHistDeltaPiVsPt(2, charge);
+  TH2D* hDeltaPiVsPtPGen  = data->GetHistDeltaPiVsPt(3, charge);
+
+  TH2D* hDeltaPiVsPtPi = 0;
+  TH2D* hDeltaPiVsPtK  = 0;
+  TH2D* hDeltaPiVsPtP  = 0;
+
+  if(data->IsMc()) {
+
+    hDeltaPiVsPtPi = data->GetHistDeltaPiVsPtMc(1, charge);
+    hDeltaPiVsPtK  = data->GetHistDeltaPiVsPtMc(2, charge);
+    hDeltaPiVsPtP  = data->GetHistDeltaPiVsPtMc(3, charge);
+  }
+
+
+
+  TProfile* hPiGenProfile = hDeltaPiVsPtPiGen->ProfileX();
+  hPiGenProfile->SetMarkerStyle(29);
+  TProfile* hKGenProfile = hDeltaPiVsPtKGen->ProfileX();
+  hKGenProfile->SetMarkerStyle(29);
+  TProfile* hPGenProfile = hDeltaPiVsPtPGen->ProfileX();
+  hPGenProfile->SetMarkerStyle(29);
+
+  TCanvas* cDeltaPiVsPt = new TCanvas("cDeltaPiVsPt", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPt->Clear();
+  cDeltaPiVsPt->cd();
+  cDeltaPiVsPt->SetLogz();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+  gROOT->ProcessLine(".x drawText.C");
+  cDeltaPiVsPt->SaveAs(Form("%s/deltapi_vs_pt.gif", dirName));
+  cDeltaPiVsPt->SaveAs(Form("%s/deltapi_vs_pt.pdf", dirName));
+
+  TCanvas* cDeltaPiVsPtLogX = new TCanvas("cDeltaPiVsPtLogX", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPtLogX->Clear();
+  cDeltaPiVsPtLogX->cd();
+  cDeltaPiVsPtLogX->SetLogz();
+  cDeltaPiVsPtLogX->SetLogx();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+  gROOT->ProcessLine(".x drawText.C");
+  cDeltaPiVsPtLogX->SaveAs(Form("%s/deltapi_vs_pt_logx.gif", dirName));
+  cDeltaPiVsPtLogX->SaveAs(Form("%s/deltapi_vs_pt_logx.pdf", dirName));
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeltaPiVsPt->GetXaxis()->FindBin(ptStart+0.01);
+  ptStart = hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeltaPiVsPt->GetXaxis()->FindBin(ptStop-0.01);
+  ptStop = hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(binStop);
+  //  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing fits from pTlow = " << ptStart << " (bin: " << binStart
+       << ") to pThigh = " << ptStop << " (bin: " << binStop << ")" << endl;
+  
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 4);
+
+  // TF1* pionGen = new TF1("pionGen", "[0]/sqrt(6.2832*[2]*[2])*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])", -30, 20);
+  // pionGen->SetLineWidth(2);
+  // pionGen->SetLineColor(kRed);
+
+  TF1* pion = new TF1("pion", "gausn", -30, 20);
+  pion->SetLineWidth(2);
+  pion->SetLineColor(kRed);
+  TF1* kaon = new TF1("kaon", "gausn", -30, 20);
+  kaon->SetLineWidth(2);
+  kaon->SetLineColor(kGreen);
+  TF1* proton = new TF1("proton", "gausn", -30, 20);
+  proton->SetLineWidth(2);
+  proton->SetLineColor(kBlue);
+  TF1* total = new TF1("total", "gausn(0)+gausn(3)+gausn(6)", -30, 20);
+  total->SetLineColor(kBlack);
+  total->SetLineWidth(2);
+  total->SetLineStyle(2);
+
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(total, "3-Gauss fit", "L");
+  legend->AddEntry(pion, "#pi", "L");
+  legend->AddEntry(kaon, "K", "L");
+  legend->AddEntry(proton, "p", "L");
+
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+  //  cSingleFit->SetLogy();
+
+  TH1D* hPionRatio =(TH1D*)hDeltaPiVsPt->ProjectionX("hPionRatio", 1, 1);
+  hPionRatio->SetTitle("particle fractions; p_{T} [GeV/c]; particle fraction");
+  hPionRatio->Reset();
+  TH1D* hKaonRatio   = (TH1D*)hPionRatio->Clone("hKaonRatio");
+  TH1D* hProtonRatio = (TH1D*)hPionRatio->Clone("hProtonRatio");
+  TH1D* hPionRatioMc = (TH1D*)hPionRatio->Clone("hPionRatioMc");
+  TH1D* hKaonRatioMc = (TH1D*)hPionRatio->Clone("hKaonRatioMc");
+  TH1D* hProtonRatioMc = (TH1D*)hPionRatio->Clone("hProtonRatioMc");
+
+  TH1D* hPionYield =(TH1D*)hDeltaPiVsPt->ProjectionX("hPionYield", 1, 1);
+  hPionYield->SetTitle("particle fractions; p_{T} [GeV/c]; particle fraction");
+  hPionYield->Reset();
+  TH1D* hKaonYield   = (TH1D*)hPionYield->Clone("hKaonYield");
+  TH1D* hProtonYield = (TH1D*)hPionYield->Clone("hProtonYield");
+  TH1D* hPionYieldMc = (TH1D*)hPionYield->Clone("hPionYieldMc");
+  TH1D* hKaonYieldMc = (TH1D*)hPionYield->Clone("hKaonYieldMc");
+  TH1D* hProtonYieldMc = (TH1D*)hPionYield->Clone("hProtonYieldMc");
+  
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    
+    TH1D* hDeltaPiVsPtProj =(TH1D*)hDeltaPiVsPt->ProjectionY(Form("hDeltaPiVsPtProj%d", bin), bin, bin);
+    hDeltaPiVsPtProj->GetXaxis()->SetRangeUser(-25, 20);
+    hDeltaPiVsPtProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                               hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+                               hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+
+    Double_t all =  hDeltaPiVsPtProj->GetEntries();
+
+    TH1D* hDeltaPiVsPtPiGenProj =(TH1D*)hDeltaPiVsPtPiGen->ProjectionY(Form("hDeltaPiVsPtPiGenProj%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtKGenProj =(TH1D*)hDeltaPiVsPtKGen->ProjectionY(Form("hDeltaPiVsPtKGenProj%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtPGenProj =(TH1D*)hDeltaPiVsPtPGen->ProjectionY(Form("hDeltaPiVsPtPGenProj%d", bin), bin, bin);
+    
+    Double_t gausParams[9] = { 
+      0.6*all,
+      hDeltaPiVsPtPiGenProj->GetMean(), 
+      hDeltaPiVsPtPiGenProj->GetRMS(), 
+      0.2*all,
+      hDeltaPiVsPtKGenProj->GetMean(), 
+      hDeltaPiVsPtKGenProj->GetRMS(), 
+      0.2*all,
+      hDeltaPiVsPtPGenProj->GetMean(), 
+      hDeltaPiVsPtPGenProj->GetRMS(), 
+    };
+
+    cFits->cd();
+    cFits->cd(j + 1);
+
+    total->SetParameters(gausParams);
+    for(Int_t i = 0; i < 9; i++) {
+
+      if((i%3) > 0)
+       total->FixParameter(i, gausParams[i]);
+      // else {
+      //       if(bin>56)
+      //         total->SetParLimits(i, 0, 10*all);
+      // }
+    }
+    
+    if(performFit) {
+
+      hDeltaPiVsPtProj->Fit(total, "0L");
+
+    } 
+
+    hDeltaPiVsPtProj->DrawCopy();
+    total->DrawCopy("same");    
+    
+    Double_t parametersOut[9];
+    total->GetParameters(parametersOut);
+    const Double_t* parameterErrorsOut = total->GetParErrors();
+
+    for(Int_t i = 0; i < 9; i++) 
+      cout << parametersOut[i] << ", ";
+    cout << endl;
+
+
+    pion->SetParameters(&parametersOut[0]);
+    pion->DrawCopy("same");
+    hPionRatio->SetBinContent(bin, parametersOut[0]/all);
+    hPionRatio->SetBinError(bin, parameterErrorsOut[0]/all);
+    hPionYield->SetBinContent(bin, parametersOut[0]);
+    hPionYield->SetBinError(bin, parameterErrorsOut[0]);
+
+    kaon->SetParameters(&parametersOut[3]);
+    kaon->DrawCopy("same");
+    hKaonRatio->SetBinContent(bin, parametersOut[3]/all);
+    hKaonRatio->SetBinError(bin, parameterErrorsOut[3]/all);
+    hKaonYield->SetBinContent(bin, parametersOut[3]);
+    hKaonYield->SetBinError(bin, parameterErrorsOut[3]);
+    
+    proton->SetParameters(&parametersOut[6]);
+    proton->DrawCopy("same");
+    hProtonRatio->SetBinContent(bin, parametersOut[6]/all);
+    hProtonRatio->SetBinError(bin, parameterErrorsOut[6]/all);
+    hProtonYield->SetBinContent(bin, parametersOut[6]);
+    hProtonYield->SetBinError(bin, parameterErrorsOut[6]);
+
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    //    cSingleFit->SetLogy();
+    hDeltaPiVsPtProj->Draw();
+    pion->DrawCopy("same");
+    kaon->DrawCopy("same");
+    proton->DrawCopy("same");
+    total->DrawCopy("same");
+    
+    if(bin==42 || bin==49) {
+
+      TFile* fileOut = new TFile(Form("%s/ptspectrum_bin%d.root", dirName, bin), "RECREATE");
+
+      TH1D* hist = (TH1D*)hDeltaPiVsPtProj->Clone("hist");
+
+      TF1* sumFit    = (TF1*)total->Clone("sumFit");
+      TF1* pionFit   = (TF1*)pion->Clone("pionFit");
+      TF1* kaonFit   = (TF1*)kaon->Clone("kaonFit");
+      TF1* protonFit = (TF1*)proton->Clone("protonFit");
+
+      hist->Write();
+
+      sumFit->Write();
+      pionFit->Write();
+      kaonFit->Write();
+      protonFit->Write();
+
+      fileOut->Close();
+    }
+
+    gROOT->ProcessLine(".x drawText.C");
+    cSingleFit->SaveAs(Form("%s/ptspectrum_bin%d.gif", dirName, bin));
+    cSingleFit->SaveAs(Form("%s/ptspectrum_bin%d.pdf", dirName, bin));
+    //    legend->Draw();
+
+    if(data->IsMc()) {
+
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      TH1D* hDeltaPiVsPtPiProj =(TH1D*)hDeltaPiVsPtPi->ProjectionY(Form("hDeltaPiVsPtPiProj%d", bin), bin, bin);
+      hDeltaPiVsPtPiProj->SetMarkerStyle(20);
+      hDeltaPiVsPtPiProj->SetMarkerColor(2);
+      hDeltaPiVsPtPiProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                                       hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+                                       hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+      hDeltaPiVsPtPiProj->Draw("P");
+      Double_t integral = hDeltaPiVsPtPiProj->Integral();
+      hPionRatioMc->SetBinContent(bin, integral/all);
+      hPionRatioMc->SetBinError(bin, TMath::Sqrt(integral)/all);
+      hPionYieldMc->SetBinContent(bin, integral);
+      hPionYieldMc->SetBinError(bin, TMath::Sqrt(integral));
+      TH1D* hDeltaPiVsPtKProj =(TH1D*)hDeltaPiVsPtK->ProjectionY(Form("hDeltaPiVsPtKProj%d", bin), bin, bin);
+      hDeltaPiVsPtKProj->SetMarkerStyle(21);
+      hDeltaPiVsPtKProj->SetMarkerColor(3);
+      hDeltaPiVsPtKProj->Draw("SAME P");
+      integral = hDeltaPiVsPtKProj->Integral();
+      hKaonRatioMc->SetBinContent(bin, integral/all);
+      hKaonRatioMc->SetBinError(bin, TMath::Sqrt(integral)/all);
+      hKaonYieldMc->SetBinContent(bin, integral);
+      hKaonYieldMc->SetBinError(bin, TMath::Sqrt(integral));
+      TH1D* hDeltaPiVsPtPProj =(TH1D*)hDeltaPiVsPtP->ProjectionY(Form("hDeltaPiVsPtPProj%d", bin), bin, bin);
+      hDeltaPiVsPtPProj->SetMarkerStyle(22);
+      hDeltaPiVsPtPProj->SetMarkerColor(4);
+      hDeltaPiVsPtPProj->Draw("SAME P");
+      integral = hDeltaPiVsPtPProj->Integral();
+      hProtonRatioMc->SetBinContent(bin, integral/all);
+      hProtonRatioMc->SetBinError(bin, TMath::Sqrt(integral)/all);
+      hProtonYieldMc->SetBinContent(bin, integral);
+      hProtonYieldMc->SetBinError(bin, TMath::Sqrt(integral));
+
+      pion->DrawCopy("same");
+      kaon->DrawCopy("same");
+      proton->DrawCopy("same");
+      cSingleFit->SaveAs(Form("debugfitsmc/ptspectrum_bin%d.gif", bin));
+    }
+  }
+
+  TCanvas* cRatio = new TCanvas("cRatio", "ratios/all vs p", 600, 400);
+  cRatio->Clear();
+  hPionRatio->SetMarkerStyle(20);
+  hPionRatio->SetMarkerColor(2);
+  hPionRatio->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+  hPionRatio->GetYaxis()->SetRangeUser(0.0, 1.0);
+  hPionRatio->DrawCopy("P E");
+  hPionYield->SetMarkerStyle(20);
+  hPionYield->SetMarkerColor(2);
+  hPionYield->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+
+  hKaonRatio->SetMarkerStyle(20);
+  hKaonRatio->SetMarkerColor(3);
+  hKaonRatio->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+  hKaonRatio->DrawCopy("SAME P E");
+  hKaonYield->SetMarkerStyle(20);
+  hKaonYield->SetMarkerColor(3);
+  hKaonYield->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+
+  hProtonRatio->SetMarkerStyle(20);
+  hProtonRatio->SetMarkerColor(4);
+  hProtonRatio->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+  hProtonRatio->DrawCopy("SAME P E");
+  hProtonYield->SetMarkerStyle(20);
+  hProtonYield->SetMarkerColor(4);
+  hProtonYield->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+
+  gROOT->ProcessLine(".x drawText.C");
+  cRatio->SaveAs(Form("%s/particle_ratios.gif", dirName));
+  cRatio->SaveAs(Form("%s/particle_ratios.pdf", dirName));
+
+  if(data->IsMc()) {
+    
+    hPionRatioMc->SetMarkerStyle(24);
+    hPionRatioMc->SetMarkerColor(2);
+    hPionRatioMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hPionYieldMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hPionYieldMc->SetMarkerStyle(24);
+    hPionYieldMc->SetMarkerColor(2);
+    hPionRatioMc->DrawCopy("SAME P");
+    
+    hKaonRatioMc->SetMarkerStyle(24);
+    hKaonRatioMc->SetMarkerColor(3);
+    hKaonRatioMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hKaonYieldMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hKaonYieldMc->SetMarkerStyle(24);
+    hKaonYieldMc->SetMarkerColor(3);
+    hKaonRatioMc->DrawCopy("SAME P");
+    
+    hProtonRatioMc->SetMarkerStyle(24);
+    hProtonRatioMc->SetMarkerColor(4);
+    hProtonRatioMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hProtonYieldMc->GetXaxis()->SetRangeUser(0.0, ptStop-0.001);
+    hProtonYieldMc->SetMarkerStyle(24);
+    hProtonYieldMc->SetMarkerColor(4);
+    hProtonRatioMc->DrawCopy("SAME P");
+
+    cRatio->SaveAs("debugfitsmc/particle_ratios.gif");
+  }
+
+  if(outFileName) {
+
+    TFile* fileOut = new TFile(Form("fit_yields_results/%s", outFileName), "RECREATE");
+
+    // Histograms for normalization
+    data->GetHistVtxStatus()->Write();
+    TH1D* hPhiCutEff = data->GetHistNclVsPhiVsPtAfter()->ProjectionX("hPhiCutEff");
+    TH1D* hHelp = data->GetHistNclVsPhiVsPtBefore()->ProjectionX("hHelp");
+    hPhiCutEff->Divide(hPhiCutEff, hHelp, 1.0, 1.0, "B");
+    hPhiCutEff->Write();
+    delete hHelp;
+    delete hPhiCutEff;
+
+    hPionRatio->Write();
+    hKaonRatio->Write();
+    hProtonRatio->Write();
+
+    hPionYield->Write();
+    hKaonYield->Write();
+    hProtonYield->Write();
+
+    if(data->IsMc()) {
+      hPionRatioMc->Write();
+      hKaonRatioMc->Write();
+      hProtonRatioMc->Write();
+
+      hPionYieldMc->Write();
+      hKaonYieldMc->Write();
+      hProtonYieldMc->Write();                        
+    }
+
+    fileOut->Close();
+  }
+}
+
+//____________________________________________________________________________
+void FitYieldsV0(const Char_t* dataFileName,
+                const Char_t* v0FileName,
+                const Char_t* v0Name,
+                Double_t ptStart, Double_t ptStop,
+                Int_t charge,
+                Bool_t performFit = kFALSE,
+                Int_t filter = 1,
+                Int_t run    = 0,
+                Bool_t usePhiCut = kTRUE,
+                const Char_t* endName=0)
+{
+  gStyle->SetOptStat(0);
+  
+  TFile* dataFile = FindFileFresh(dataFileName);
+  if(!dataFile)
+    return;
+  AliHighPtDeDxData* data = (AliHighPtDeDxData*)GetObject(dataFile, filter, usePhiCut, run, "filter", endName);
+  data->Print();
+
+  TFile* v0File = FindFileFresh(v0FileName);
+  if(!v0File)
+    return;
+  AliHighPtDeDxData* v0 = (AliHighPtDeDxData*)GetObject(v0File, 0, usePhiCut, run, v0Name, endName);
+  v0->Print();
+
+  TH2D* hDeltaPiVsPt = v0->GetHistDeltaPiVsPt(0, charge);
+  hDeDxVsP = hDeltaPiVsPt; // for the 2d fit to pick up the right bin
+
+  TH2D* hDeltaPiVsPtPiGen = data->GetHistDeltaPiVsPt(1, charge);
+  TH2D* hDeltaPiVsPtKGen  = data->GetHistDeltaPiVsPt(2, charge);
+  TH2D* hDeltaPiVsPtPGen  = data->GetHistDeltaPiVsPt(3, charge);
+
+  TProfile* hPiGenProfile = hDeltaPiVsPtPiGen->ProfileX();
+  hPiGenProfile->SetMarkerStyle(29);
+  TProfile* hKGenProfile = hDeltaPiVsPtKGen->ProfileX();
+  hKGenProfile->SetMarkerStyle(29);
+  TProfile* hPGenProfile = hDeltaPiVsPtPGen->ProfileX();
+  hPGenProfile->SetMarkerStyle(29);
+
+  TCanvas* cDeltaPiVsPt = new TCanvas("cDeltaPiVsPt", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPt->Clear();
+  cDeltaPiVsPt->cd();
+  cDeltaPiVsPt->SetLogz();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+
+  TCanvas* cDeltaPiVsPtLogX = new TCanvas("cDeltaPiVsPtLogX", "dE/dx vs p", 400, 300);
+  cDeltaPiVsPtLogX->Clear();
+  cDeltaPiVsPtLogX->cd();
+  cDeltaPiVsPtLogX->SetLogz();
+  cDeltaPiVsPtLogX->SetLogx();
+  hDeltaPiVsPt->Draw("COLZ");
+  hPiGenProfile->Draw("SAME P");
+  hKGenProfile->Draw("SAME P");
+  hPGenProfile->Draw("SAME P");
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeltaPiVsPt->GetXaxis()->FindBin(ptStart+0.01);
+  ptStart = hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeltaPiVsPt->GetXaxis()->FindBin(ptStop-0.01);
+  ptStop = hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(binStop);
+  //  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing fits from pTlow = " << ptStart << " (bin: " << binStart
+       << ") to pThigh = " << ptStop << " (bin: " << binStop << ")" << endl;
+  
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 4);
+
+  TF1* pion = new TF1("pion", "[0]/sqrt(6.2832*[2]*[2])*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])", -30, 20);
+    //  TF1* pion = new TF1("pion", "gausn", -30, 20);
+  pion->SetLineWidth(2);
+  pion->SetLineColor(kRed);
+  // TF1* kaon = new TF1("kaon", "gausn", -30, 20);
+  // kaon->SetLineWidth(2);
+  // kaon->SetLineColor(kGreen);
+  TF1* proton = new TF1("proton", "[0]/sqrt(6.2832*[2]*[2])*exp(-(x-[1])*(x-[1])/2.0/[2]/[2])", -30, 20);
+  //  TF1* proton = new TF1("proton", "gausn", -30, 20);
+  proton->SetLineWidth(2);
+  proton->SetLineColor(kBlue);
+
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(pion, "#pi", "L");
+  //  legend->AddEntry(kaon, "K", "L");
+  legend->AddEntry(proton, "p", "L");
+
+  if(strstr(v0Name, "lambda")) {
+    gSystem->Exec("mv debugfitslambda/* olddebugfitslambda/");
+  } else {
+    gSystem->Exec("mv debugfitskaon/* olddebugfitskaon/");
+  }
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    
+    TH1D* hDeltaPiVsPtProj =(TH1D*)hDeltaPiVsPt->ProjectionY(Form("hDeltaPiVsPtProj%d", bin), bin, bin);
+    //    hDeltaPiVsPtProj->GetXaxis()->SetRangeUser(40, 85);
+    hDeltaPiVsPtProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                               hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+                               hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+
+    Double_t all =  hDeltaPiVsPtProj->GetEntries();
+
+    TH1D* hDeltaPiVsPtPiGenProj =(TH1D*)hDeltaPiVsPtPiGen->ProjectionY(Form("hDeltaPiVsPtPiGenProj%d", bin), bin, bin);
+    //    TH1D* hDeltaPiVsPtKGenProj =(TH1D*)hDeltaPiVsPtKGen->ProjectionY(Form("hDeltaPiVsPtKGenProj%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtPGenProj =(TH1D*)hDeltaPiVsPtPGen->ProjectionY(Form("hDeltaPiVsPtPGenProj%d", bin), bin, bin);
+    
+    cFits->cd();
+    cFits->cd(j + 1);
+
+    hDeltaPiVsPtProj->Draw();
+
+    if(strstr(v0Name, "lambda")) {
+    
+      Double_t mean  = hDeltaPiVsPtPGenProj->GetMean();
+      Double_t sigma = hDeltaPiVsPtPGenProj->GetRMS();
+
+      cout << "Bin: " << bin 
+          <<   " (" << hDeltaPiVsPtProj->GetTitle()                            
+          << "), sigma: " << sigma << endl;
+      proton->SetParameters(all, mean, sigma);
+      proton->FixParameter(1, mean);
+      proton->FixParameter(2, sigma);
+
+      if(performFit) {
+       
+       hDeltaPiVsPtProj->Fit(proton, "L0", "", mean-sigma, mean+sigma);
+       
+       cout << "Bin: " << bin 
+            <<   " (" << hDeltaPiVsPtProj->GetTitle()                          
+            << "), sigma: " << proton->GetParameter(2) << endl;
+      } 
+
+      proton->DrawCopy("same");
+
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      hDeltaPiVsPtProj->Draw();
+      proton->DrawCopy("same");
+    } else {
+
+      Double_t mean  = hDeltaPiVsPtPiGenProj->GetMean();
+      Double_t sigma = hDeltaPiVsPtPiGenProj->GetRMS();
+      cout << "Bin: " << bin 
+          <<   " (" << hDeltaPiVsPtProj->GetTitle()                            
+          << "), sigma: " << sigma << endl;
+      pion->SetParameters(all, mean, sigma);
+      pion->FixParameter(1, mean);
+      pion->FixParameter(2, sigma);
+      
+      if(performFit) {
+       
+       hDeltaPiVsPtProj->Fit(pion, "L0", "", mean-sigma, mean+sigma);
+
+       cout << "Bin: " << bin 
+            <<   " (" << hDeltaPiVsPtProj->GetTitle()                          
+            << "), sigma: " << pion->GetParameter(2) << endl;  
+      } 
+      pion->DrawCopy("same");
+
+      cSingleFit->cd();
+      cSingleFit->Clear();
+      hDeltaPiVsPtProj->Draw();
+      pion->DrawCopy("same");
+    }
+    
+    //    cSingleFit->SetLogy();
+    
+    gROOT->ProcessLine(".x drawText.C");
+
+    if(strstr(v0Name, "lambda")) {
+
+      if(!endName) {
+       cSingleFit->SaveAs(Form("results/lambda/ptspectrum_bin%d.gif", bin));
+       cSingleFit->SaveAs(Form("results/lambda/ptspectrum_bin%d.pdf", bin));
+      } else {
+       cSingleFit->SaveAs(Form("results/lambda%s/ptspectrum_bin%d.gif", endName, bin));
+       cSingleFit->SaveAs(Form("results/lambda%s/ptspectrum_bin%d.pdf", endName, bin));
+      }
+    } else {
+      if(!endName) {
+       cSingleFit->SaveAs(Form("results/kaon/ptspectrum_bin%d.gif", bin));
+       cSingleFit->SaveAs(Form("results/kaon/ptspectrum_bin%d.pdf", bin));
+      }else {
+       cSingleFit->SaveAs(Form("results/kaon%s/ptspectrum_bin%d.gif", endName, bin));
+       cSingleFit->SaveAs(Form("results/kaon%s/ptspectrum_bin%d.pdf", endName, bin));
+      }
+    }
+    //    legend->Draw();
+  }
+
+}
+
+//____________________________________________________________________________
+void CompareYields(const Char_t* dataFileName1,
+                  const Char_t* dataFileName2,
+                  Double_t ptStart, Double_t ptStop,
+                  Int_t charge1,
+                  Int_t charge2,
+                  const Char_t* endName1=0,
+                  const Char_t* endName2=0,
+                  Bool_t performFit = kFALSE,
+                  Int_t run    = 0,
+                  Int_t filter = 1,
+                  Bool_t usePhiCut = kTRUE)
+{
+  gStyle->SetOptStat(0);
+
+  
+  TFile* dataFile1 = FindFileFresh(dataFileName1);
+  if(!dataFile1)
+    return;
+  AliHighPtDeDxData* data1 = (AliHighPtDeDxData*)GetObject(dataFile1, filter, usePhiCut, run, "filter", endName1);
+  data1->Print();
+
+  gSystem->Exec("mv debugfits/* olddebugfits/");
+  gSystem->Exec("mv debugfitsratio/* olddebugfitsratio/");
+  // if(data1->IsMc())
+  //   gSystem->Exec("mv debugfitsmc/* olddebugfitsmc/");
+
+
+  TH2D* hDeltaPiVsPt1 = data1->GetHistDeltaPiVsPt(0, charge1);
+  hDeDxVsP = hDeltaPiVsPt1; // for the 2d fit to pick up the right bin
+
+  TH2D* hDeltaPiVsPtPiGen1 = data1->GetHistDeltaPiVsPt(1, charge1);
+  TH2D* hDeltaPiVsPtKGen1  = data1->GetHistDeltaPiVsPt(2, charge1);
+  TH2D* hDeltaPiVsPtPGen1  = data1->GetHistDeltaPiVsPt(3, charge1);
+
+  // TH2D* hDeltaPiVsPtPi1 = 0;
+  // TH2D* hDeltaPiVsPtK1  = 0;
+  // TH2D* hDeltaPiVsPtP1  = 0;
+
+  // if(data1->IsMc()) {
+
+  //   hDeltaPiVsPtPi1 = data1->GetHistDeltaPiVsPtPiMc();
+  //   hDeltaPiVsPtK1  = data1->GetHistDeltaPiVsPtKMc();
+  //   hDeltaPiVsPtP1  = data1->GetHistDeltaPiVsPtPMc();
+  // }
+
+  AliHighPtDeDxData* data2 = data1;
+  if(dataFileName2) {
+    TFile* dataFile2 = FindFileFresh(dataFileName2);
+    if(!dataFile2)
+      return;
+    data2 = (AliHighPtDeDxData*)GetObject(dataFile2, filter, usePhiCut, run, "filter", endName2);
+    data2->Print();
+  } else if (endName2) {
+
+    data2 = (AliHighPtDeDxData*)GetObject(dataFile1, filter, usePhiCut, run, "filter", endName2);
+  }
+
+  TH2D* hDeltaPiVsPt2 = data2->GetHistDeltaPiVsPt(0, charge2);
+  hDeDxVsP = hDeltaPiVsPt2; // for the 2d fit to pick up the right bin
+
+  // TH2D* hDeltaPiVsPtPiGen2 = data2->GetHistDeltaPiVsPt(1, charge2);
+  // TH2D* hDeltaPiVsPtKGen2  = data2->GetHistDeltaPiVsPt(2, charge2);
+  // TH2D* hDeltaPiVsPtPGen2  = data2->GetHistDeltaPiVsPt(3, charge2);
+
+  // TH2D* hDeltaPiVsPtPi2 = 0;
+  // TH2D* hDeltaPiVsPtK2  = 0;
+  // TH2D* hDeltaPiVsPtP2  = 0;
+
+  // if(data2->IsMc()) {
+
+  //   hDeltaPiVsPtPi2 = data2->GetHistDeltaPiVsPtPiMc();
+  //   hDeltaPiVsPtK2  = data2->GetHistDeltaPiVsPtKMc();
+  //   hDeltaPiVsPtP2  = data2->GetHistDeltaPiVsPtPMc();
+  // }
+
+
+  // Root is a bit stupid with finidng bins so we have to add and subtract a
+  // little to be sure we get the right bin as we typically put edges as
+  // limits
+  const Int_t binStart = hDeltaPiVsPt1->GetXaxis()->FindBin(ptStart+0.01);
+  ptStart = hDeltaPiVsPt1->GetXaxis()->GetBinLowEdge(binStart);
+  const Int_t binStop  = hDeltaPiVsPt1->GetXaxis()->FindBin(ptStop-0.01);
+  ptStop = hDeltaPiVsPt1->GetXaxis()->GetBinUpEdge(binStop);
+  //  const Int_t nBins    = binStop - binStart + 1;
+
+  cout << "Doing fits from pTlow = " << ptStart << " (bin: " << binStart
+       << ") to pThigh = " << ptStop << " (bin: " << binStop << ")" << endl;
+  
+
+  //cross check
+  TCanvas* cFits = new TCanvas("cFits", "Fit comparison to data", 1200, 800);
+  cFits->Clear();
+  cFits->Divide(7, 4);
+
+  TF1* pion = new TF1("pion", "gausn", -30, 20);
+  pion->SetLineWidth(2);
+  pion->SetLineColor(kRed);
+  TF1* kaon = new TF1("kaon", "gausn", -30, 20);
+  kaon->SetLineWidth(2);
+  kaon->SetLineColor(kGreen);
+  TF1* proton = new TF1("proton", "gausn", -30, 20);
+  proton->SetLineWidth(2);
+  proton->SetLineColor(kBlue);
+  TF1* total = new TF1("total", "gausn(0)+gausn(3)+gausn(6)", -30, 20);
+  total->SetLineColor(kBlack);
+  total->SetLineWidth(2);
+  total->SetLineStyle(2);
+
+  TLegend* legend = new TLegend(0.11, 0.6, 0.35, 0.85);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+  legend->AddEntry(total, "3-Gauss fit", "L");
+  legend->AddEntry(pion, "#pi", "L");
+  legend->AddEntry(kaon, "K", "L");
+  legend->AddEntry(proton, "p", "L");
+
+  TCanvas* cSingleFit = new TCanvas("cSingleFit", "single fit");
+
+  for(Int_t bin = binStart; bin <= binStop; bin++){
+    
+    cout << "Making projection for bin: " << bin << endl;
+    
+    const Int_t j = bin-binStart;
+    
+    TH1D* hDeltaPiVsPtProj1 =(TH1D*)hDeltaPiVsPt1->ProjectionY(Form("hDeltaPiVsPtProj1%d", bin), bin, bin);
+    hDeltaPiVsPtProj1->GetXaxis()->SetRangeUser(-25, 20);
+    hDeltaPiVsPtProj1->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+                               hDeltaPiVsPt1->GetXaxis()->GetBinLowEdge(bin),
+                               hDeltaPiVsPt1->GetXaxis()->GetBinUpEdge(bin)));
+
+    TH1D* hDeltaPiVsPtProj2 =(TH1D*)hDeltaPiVsPt2->ProjectionY(Form("hDeltaPiVsPtProj2%d", bin), bin, bin);
+
+    Double_t all1 =  hDeltaPiVsPtProj1->GetEntries();
+
+    TH1D* hDeltaPiVsPtPiGenProj1 =(TH1D*)hDeltaPiVsPtPiGen1->ProjectionY(Form("hDeltaPiVsPtPiGenProj1%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtKGenProj1 =(TH1D*)hDeltaPiVsPtKGen1->ProjectionY(Form("hDeltaPiVsPtKGenProj1%d", bin), bin, bin);
+    TH1D* hDeltaPiVsPtPGenProj1 =(TH1D*)hDeltaPiVsPtPGen1->ProjectionY(Form("hDeltaPiVsPtPGenProj1%d", bin), bin, bin);
+    
+    Double_t gausParams[9] = { 
+      0.6*all1,
+      hDeltaPiVsPtPiGenProj1->GetMean(), 
+      hDeltaPiVsPtPiGenProj1->GetRMS(), 
+      0.2*all1,
+      hDeltaPiVsPtKGenProj1->GetMean(), 
+      hDeltaPiVsPtKGenProj1->GetRMS(), 
+      0.2*all1,
+      hDeltaPiVsPtPGenProj1->GetMean(), 
+      hDeltaPiVsPtPGenProj1->GetRMS(), 
+    };
+
+    cFits->cd();
+    cFits->cd(j + 1);
+
+    total->SetParameters(gausParams);
+    for(Int_t i = 0; i < 9; i++) {
+
+      if((i%3) > 0)
+       total->FixParameter(i, gausParams[i]);
+    }
+    
+    if(performFit) {
+
+      hDeltaPiVsPtProj1->Fit(total, "0L");
+
+    } 
+
+    hDeltaPiVsPtProj1->SetLineColor(4);
+    hDeltaPiVsPtProj2->SetLineColor(2);
+    hDeltaPiVsPtProj1->DrawCopy();
+    hDeltaPiVsPtProj2->DrawCopy("SAME");
+    if(performFit)
+      total->DrawCopy("same");    
+    
+    Double_t parametersOut[9];
+    total->GetParameters(parametersOut);
+    //    const Double_t* parameterErrorsOut = total->GetParErrors();
+
+    for(Int_t i = 0; i < 9; i++) 
+      cout << parametersOut[i] << ", ";
+    cout << endl;
+
+
+    if(performFit) {
+      pion->SetParameters(&parametersOut[0]);
+      pion->DrawCopy("same");
+      
+      kaon->SetParameters(&parametersOut[3]);
+      kaon->DrawCopy("same");
+      
+      proton->SetParameters(&parametersOut[6]);
+      proton->DrawCopy("same");
+    }
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    //    cSingleFit->SetLogy();
+    hDeltaPiVsPtProj1->DrawCopy();
+    hDeltaPiVsPtProj2->DrawCopy("SAME");
+    if(performFit) {
+      pion->DrawCopy("same");
+      kaon->DrawCopy("same");
+      proton->DrawCopy("same");
+      total->DrawCopy("same");
+    }
+
+    cSingleFit->SaveAs(Form("debugfits/ptspectrum_bin%d.gif", bin));
+
+    cSingleFit->cd();
+    cSingleFit->Clear();
+    //    cSingleFit->SetLogy();
+    hDeltaPiVsPtProj1->Divide(hDeltaPiVsPtProj2);
+    hDeltaPiVsPtProj1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hDeltaPiVsPtProj1->DrawCopy();
+
+    cSingleFit->SaveAs(Form("debugfitsratio/ptspectrum_bin%d.gif", bin));
+    //    legend->Draw();
+
+    // if(data->IsMc()) {
+
+    //   cSingleFit->cd();
+    //   cSingleFit->Clear();
+    //   TH1D* hDeltaPiVsPtPiProj =(TH1D*)hDeltaPiVsPtPi->ProjectionY(Form("hDeltaPiVsPtPiProj%d", bin), bin, bin);
+    //   hDeltaPiVsPtPiProj->SetMarkerStyle(20);
+    //   hDeltaPiVsPtPiProj->SetMarkerColor(2);
+    //   hDeltaPiVsPtPiProj->SetTitle(Form("%.1f<p_{T}<%.1f GeV/c", 
+    //                                         hDeltaPiVsPt->GetXaxis()->GetBinLowEdge(bin),
+    //                                         hDeltaPiVsPt->GetXaxis()->GetBinUpEdge(bin)));
+    //   hDeltaPiVsPtPiProj->Draw("P");
+    //   hPionRatioMc->SetBinContent(bin, hDeltaPiVsPtPiProj->Integral()/all);
+    //   hPionYieldMc->SetBinContent(bin, hDeltaPiVsPtPiProj->Integral());
+    //   TH1D* hDeltaPiVsPtKProj =(TH1D*)hDeltaPiVsPtK->ProjectionY(Form("hDeltaPiVsPtKProj%d", bin), bin, bin);
+    //   hDeltaPiVsPtKProj->SetMarkerStyle(21);
+    //   hDeltaPiVsPtKProj->SetMarkerColor(3);
+    //   hDeltaPiVsPtKProj->Draw("SAME P");
+    //   hKaonRatioMc->SetBinContent(bin, hDeltaPiVsPtKProj->Integral()/all);
+    //   hKaonYieldMc->SetBinContent(bin, hDeltaPiVsPtKProj->Integral());
+    //   TH1D* hDeltaPiVsPtPProj =(TH1D*)hDeltaPiVsPtP->ProjectionY(Form("hDeltaPiVsPtPProj%d", bin), bin, bin);
+    //   hDeltaPiVsPtPProj->SetMarkerStyle(22);
+    //   hDeltaPiVsPtPProj->SetMarkerColor(4);
+    //   hDeltaPiVsPtPProj->Draw("SAME P");
+    //   hProtonRatioMc->SetBinContent(bin, hDeltaPiVsPtPProj->Integral()/all);
+    //   hProtonYieldMc->SetBinContent(bin, hDeltaPiVsPtPProj->Integral());
+
+    //   pion->DrawCopy("same");
+    //   kaon->DrawCopy("same");
+    //   proton->DrawCopy("same");
+    //   cSingleFit->SaveAs(Form("debugfitsmc/ptspectrum_bin%d.gif", bin));
+    // }
+  }
+}
+
+//___________________________________________________________________________________________
+void MakeRatios(const Char_t* file1Name, const Char_t* file2Name, 
+               Bool_t drawFractionRatios,
+               Bool_t drawYieldRatios)
+{
+  /*
+    For yields we assume that file 1 is negative charge and file
+    2 is positive charge.
+   */
+  
+  TFile* file1 = FindFileFresh(file1Name);
+  if(!file1)
+    return;
+  
+  TH1D* hPionRatio1   = (TH1D*)file1->Get("hPionRatio");
+  TH1D* hKaonRatio1   = (TH1D*)file1->Get("hKaonRatio");
+  TH1D* hProtonRatio1 = (TH1D*)file1->Get("hProtonRatio");
+
+  TH1D* hPionYield1   = (TH1D*)file1->Get("hPionYield");
+  TH1D* hKaonYield1   = (TH1D*)file1->Get("hKaonYield");
+  TH1D* hProtonYield1 = (TH1D*)file1->Get("hProtonYield");
+
+  TH1D* hPionRatioMc1   = (TH1D*)file1->Get("hPionRatioMc");
+  TH1D* hKaonRatioMc1   = (TH1D*)file1->Get("hKaonRatioMc");
+  TH1D* hProtonRatioMc1 = (TH1D*)file1->Get("hProtonRatioMc");
+
+  TH1D* hPionYieldMc1   = (TH1D*)file1->Get("hPionYieldMc");
+  TH1D* hKaonYieldMc1   = (TH1D*)file1->Get("hKaonYieldMc");
+  TH1D* hProtonYieldMc1 = (TH1D*)file1->Get("hProtonYieldMc");
+
+  TFile* file2 = FindFileFresh(file2Name);
+  if(!file2)
+    return;
+  
+  TH1D* hPionRatio2   = (TH1D*)file2->Get("hPionRatio");
+  TH1D* hKaonRatio2   = (TH1D*)file2->Get("hKaonRatio");
+  TH1D* hProtonRatio2 = (TH1D*)file2->Get("hProtonRatio");
+
+  TH1D* hPionYield2   = (TH1D*)file2->Get("hPionYield");
+  TH1D* hKaonYield2   = (TH1D*)file2->Get("hKaonYield");
+  TH1D* hProtonYield2 = (TH1D*)file2->Get("hProtonYield");
+
+  TH1D* hPionRatioMc2   = (TH1D*)file2->Get("hPionRatioMc");
+  TH1D* hKaonRatioMc2   = (TH1D*)file2->Get("hKaonRatioMc");
+  TH1D* hProtonRatioMc2 = (TH1D*)file2->Get("hProtonRatioMc");
+
+  TH1D* hPionYieldMc2   = (TH1D*)file2->Get("hPionYieldMc");
+  TH1D* hKaonYieldMc2   = (TH1D*)file2->Get("hKaonYieldMc");
+  TH1D* hProtonYieldMc2 = (TH1D*)file2->Get("hProtonYieldMc");
+  
+  hPionRatio1->Divide(hPionRatio2);
+  hPionRatio1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hPionRatio1->SetTitle("Xcheck: pion fraction ratios; p_{T} [GeV/c]; pion fraction ratio");
+
+  hKaonRatio1->Divide(hKaonRatio2);
+  hKaonRatio1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hKaonRatio1->SetTitle("Xcheck: kaon fraction ratios; p_{T} [GeV/c]; kaon fraction ratio");
+
+  hProtonRatio1->Divide(hProtonRatio2);
+  hProtonRatio1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hProtonRatio1->SetTitle("Xcheck: proton fraction ratios; p_{T} [GeV/c]; proton fraction ratio");
+
+  hPionYield1->Divide(hPionYield2);
+  hPionYield1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hPionYield1->SetTitle("#pi^{-}/#pi^{+} vs p_{T}; p_{T} [GeV/c]; #pi^{-}/#pi^{+}");
+
+  hKaonYield1->Divide(hKaonYield2);
+  hKaonYield1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hKaonYield1->SetTitle("K^{-}/K^{+} vs p_{T}; p_{T} [GeV/c]; K^{-}/K^{+}");
+
+  hProtonYield1->Divide(hProtonYield2);
+  hProtonYield1->GetYaxis()->SetRangeUser(0.8, 1.2);
+  hProtonYield1->SetTitle("#bar{p}/p vs p_{T}; p_{T} [GeV/c]; #bar{p}/p");
+
+  if(hPionRatioMc1) {
+    hPionRatioMc1->Divide(hPionRatioMc2);
+    hPionRatioMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hPionRatioMc1->SetTitle("Xcheck: pion fraction ratios (MC TRUTH); p_{T} [GeV/c]; pion fraction ratio");
+    
+    hKaonRatioMc1->Divide(hKaonRatioMc2);
+    hKaonRatioMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hKaonRatioMc1->SetTitle("Xcheck: kaon fraction ratios (MC TRUTH); p_{T} [GeV/c]; kaon fraction ratio");
+    
+    hProtonRatioMc1->Divide(hProtonRatioMc2);
+    hProtonRatioMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hProtonRatioMc1->SetTitle("Xcheck: proton fraction ratios (MC TRUTH); p_{T} [GeV/c]; proton fraction ratio");
+    
+    hPionYieldMc1->Divide(hPionYieldMc2);
+    hPionYieldMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hPionYieldMc1->SetTitle("#pi^{-}/#pi^{+} vs p_{T} (MC TRUTH); p_{T} [GeV/c]; #pi^{-}/#pi^{+}");
+    
+    hKaonYieldMc1->Divide(hKaonYieldMc2);
+    hKaonYieldMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hKaonYieldMc1->SetTitle("K^{-}/K^{+} vs p_{T} (MC TRUTH); p_{T} [GeV/c]; K^{-}/K^{+}");
+    
+    hProtonYieldMc1->Divide(hProtonYieldMc2);
+    hProtonYieldMc1->GetYaxis()->SetRangeUser(0.8, 1.2);
+    hProtonYieldMc1->SetTitle("#bar{p}/p vs p_{T} (MC TRUTH); p_{T} [GeV/c]; #bar{p}/p");
+  }
+
+  if(drawFractionRatios) {
+    TCanvas* cPionFractionRatio = new TCanvas("cPionFractionRatio", "pion fraction ratio", 400, 300);
+    cPionFractionRatio->Clear();
+    cPionFractionRatio->SetGridy();
+    cPionFractionRatio->cd();
+    hPionRatio1->Draw();
+    cPionFractionRatio->SaveAs("pion_frac_ratio.gif");
+
+    TCanvas* cKaonFractionRatio = new TCanvas("cKaonFractionRatio", "kaon fraction ratio", 400, 300);
+    cKaonFractionRatio->Clear();
+    cKaonFractionRatio->SetGridy();
+    cKaonFractionRatio->cd();
+    hKaonRatio1->Draw();
+    cKaonFractionRatio->SaveAs("kaon_frac_ratio.gif");
+
+    TCanvas* cProtonFractionRatio = new TCanvas("cProtonFractionRatio", "proton fraction ratio", 400, 300);
+    cProtonFractionRatio->Clear();
+    cProtonFractionRatio->SetGridy();
+    cProtonFractionRatio->cd();
+    hProtonRatio1->Draw();
+    cProtonFractionRatio->SaveAs("proton_frac_ratio.gif");
+
+    if(hPionRatioMc1) {
+      TCanvas* cPionFractionRatioMc = new TCanvas("cPionFractionRatioMc", "pion fraction ratio", 400, 300);
+      cPionFractionRatioMc->Clear();
+      cPionFractionRatioMc->SetGridy();
+      cPionFractionRatioMc->cd();
+      hPionRatioMc1->Draw();
+      cPionFractionRatioMc->SaveAs("pion_frac_ratio_mc.gif");
+      
+      TCanvas* cKaonFractionRatioMc = new TCanvas("cKaonFractionRatioMc", "kaon fraction ratio", 400, 300);
+      cKaonFractionRatioMc->Clear();
+      cKaonFractionRatioMc->SetGridy();
+      cKaonFractionRatioMc->cd();
+      hKaonRatioMc1->Draw();
+      cKaonFractionRatioMc->SaveAs("kaon_frac_ratio_mc.gif");
+      
+      TCanvas* cProtonFractionRatioMc = new TCanvas("cProtonFractionRatioMc", "proton fraction ratio", 400, 300);
+      cProtonFractionRatioMc->Clear();
+      cProtonFractionRatioMc->SetGridy();
+      cProtonFractionRatioMc->cd();
+      hProtonRatioMc1->Draw();
+      cProtonFractionRatioMc->SaveAs("proton_frac_ratio_mc.gif");
+    }
+  }
+  
+  if(drawYieldRatios) {
+    TCanvas* cPionRatio = new TCanvas("cPionRatio", "pion yields ratio", 400, 300);
+    cPionRatio->Clear();
+    cPionRatio->cd();
+    cPionRatio->SetGridy();
+    hPionYield1->Draw();
+    cPionRatio->SaveAs("pion_ratio.gif");
+
+    TCanvas* cKaonRatio = new TCanvas("cKaonRatio", "kaon yields ratio", 400, 300);
+    cKaonRatio->Clear();
+    cKaonRatio->cd();
+    cKaonRatio->SetGridy();
+    hKaonYield1->Draw();
+    cKaonRatio->SaveAs("kaon_ratio.gif");
+
+    TCanvas* cProtonRatio = new TCanvas("cProtonRatio", "proton yields ratio", 400, 300);
+    cProtonRatio->Clear();
+    cProtonRatio->cd();
+    cProtonRatio->SetGridy();
+    hProtonYield1->Draw();
+    cProtonRatio->SaveAs("proton_ratio.gif");
+
+    if(hPionRatioMc1) {
+      
+      TCanvas* cPionRatioMc = new TCanvas("cPionRatioMc", "pion yields ratio", 400, 300);
+      cPionRatioMc->Clear();
+      cPionRatioMc->cd();
+      cPionRatioMc->SetGridy();
+      hPionYieldMc1->Draw();
+      cPionRatioMc->SaveAs("pion_ratio_mc.gif");
+      
+      TCanvas* cKaonRatioMc = new TCanvas("cKaonRatioMc", "kaon yields ratio", 400, 300);
+      cKaonRatioMc->Clear();
+      cKaonRatioMc->cd();
+      cKaonRatioMc->SetGridy();
+      hKaonYieldMc1->Draw();
+      cKaonRatioMc->SaveAs("kaon_ratio_mc.gif");
+      
+      TCanvas* cProtonRatioMc = new TCanvas("cProtonRatioMc", "proton yields ratio", 400, 300);
+      cProtonRatioMc->Clear();
+      cProtonRatioMc->cd();
+      cProtonRatioMc->SetGridy();
+      hProtonYieldMc1->Draw();
+      cProtonRatioMc->SaveAs("proton_ratio_mc.gif");
+    }
+  }
+}
+
+//___________________________________________________________________________________________
+void Compare(const Char_t* file1Name, const Char_t* file2Name, const Char_t* file3Name, 
+            const Char_t* legend2, const Char_t* legend3, const Char_t* outfilename)
+{
+  /*
+    filename1 is the default
+   */
+  
+  TLegend* legend = new TLegend(0.11, 0.68, 0.35, 0.88);    
+  legend->SetBorderSize(0);
+  legend->SetFillColor(0);
+
+  TFile* file1 = FindFileFresh(file1Name);
+  if(!file1)
+    return;
+  
+  TH1D* hPionRatio1   = (TH1D*)file1->Get("hPionRatio");
+  hPionRatio1->SetMarkerStyle(29);
+  TH1D* hPionRatio1Clone = (TH1D*)hPionRatio1->Clone("hPionsRatio1Clone");
+  hPionRatio1Clone->SetMarkerColor(1);
+  legend->AddEntry(hPionRatio1Clone, "default", "P");
+  TH1D* hKaonRatio1   = (TH1D*)file1->Get("hKaonRatio");
+  hKaonRatio1->SetMarkerStyle(29);
+  TH1D* hProtonRatio1 = (TH1D*)file1->Get("hProtonRatio");
+  hProtonRatio1->SetMarkerStyle(29);
+
+  TFile* file2 = FindFileFresh(file2Name);
+  if(!file2)
+    return;
+  
+  TH1D* hPionRatio2   = (TH1D*)file2->Get("hPionRatio");
+  hPionRatio2->SetMarkerStyle(20);
+  TH1D* hPionRatio2Clone = (TH1D*)hPionRatio2->Clone("hPionsRatio2Clone");
+  hPionRatio2Clone->SetMarkerColor(1);
+  legend->AddEntry(hPionRatio2Clone, legend2, "P");
+  TH1D* hKaonRatio2   = (TH1D*)file2->Get("hKaonRatio");
+  hKaonRatio2->SetMarkerStyle(20);
+  TH1D* hProtonRatio2 = (TH1D*)file2->Get("hProtonRatio");
+  hProtonRatio2->SetMarkerStyle(20);
+
+  TFile* file3 = FindFileFresh(file3Name);
+  if(!file3)
+    return;
+  
+  TH1D* hPionRatio3   = (TH1D*)file3->Get("hPionRatio");
+  hPionRatio3->SetMarkerStyle(24);
+  TH1D* hPionRatio3Clone = (TH1D*)hPionRatio3->Clone("hPionsRatio3Clone");
+  hPionRatio3Clone->SetMarkerColor(1);
+  legend->AddEntry(hPionRatio3Clone, legend3, "P");
+  TH1D* hKaonRatio3   = (TH1D*)file3->Get("hKaonRatio");
+  hKaonRatio3->SetMarkerStyle(24);
+  TH1D* hProtonRatio3 = (TH1D*)file3->Get("hProtonRatio");
+  hProtonRatio3->SetMarkerStyle(24);
+
+  TCanvas* cRatios = new TCanvas("cRatios", "pion fraction ratio", 400, 300);
+  cRatios->Clear();
+  cRatios->SetGridy();
+  cRatios->cd();
+  hPionRatio1->Draw("EP");
+  hKaonRatio1->Draw("SAME EP");
+  hProtonRatio1->Draw("SAME EP");
+  hPionRatio2->Draw("HIST SAME P");
+  hKaonRatio2->Draw("HIST SAME P");
+  hProtonRatio2->Draw("HIST SAME P");
+  hPionRatio3->Draw("HIST SAME P");
+  hKaonRatio3->Draw("HIST SAME P");
+  hProtonRatio3->Draw("HIST SAME P");
+  legend->Draw();
+  gROOT->ProcessLine(".x drawText.C");
+  cRatios->SaveAs(Form("%s.gif", outfilename));
+  cRatios->SaveAs(Form("%s.pdf", outfilename));
+  
+}
+
+//___________________________________________________________________________________________
+void Compare(Double_t x)
+{
+  /*
+    filename1 is the default
+   */
+  gStyle->SetOptStat(0);
+
+  TCanvas* cRatios = new TCanvas("cRatios", "pion fraction ratio", 400, 300);
+
+  const Int_t nEtaBins = 8;
+  Double_t etaLimits[nEtaBins+1] = {-0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8};
+
+  TGraphErrors* graphPionFractions = new TGraphErrors(nEtaBins);
+  graphPionFractions->SetMarkerStyle(29);
+  graphPionFractions->SetMarkerColor(2);
+
+  TGraphErrors* graphKaonFractions = new TGraphErrors(nEtaBins);
+  graphKaonFractions->SetMarkerStyle(29);
+  graphKaonFractions->SetMarkerColor(3);
+
+  TGraphErrors* graphProtonFractions = new TGraphErrors(nEtaBins);
+  graphProtonFractions->SetMarkerStyle(29);
+  graphProtonFractions->SetMarkerColor(4);
+
+  TH1F* hHelp = new TH1F("hHelp", "particle fractions vs #eta; #eta; particle fraction",
+                        nEtaBins, etaLimits[0], etaLimits[nEtaBins]);
+  hHelp->SetMinimum(0.0);
+  hHelp->SetMaximum(1.0);
+  hHelp->SetDirectory(0);
+
+  for(Int_t i = 0; i < nEtaBins; i++) {
+
+    Double_t etaCenter = (etaLimits[i] + etaLimits[i+1])/2.0;
+    Double_t etaWidth  = TMath::Abs(etaCenter - etaLimits[i]);
+
+    Int_t etaLow  = Int_t(TMath::Abs(etaLimits[i]*10.0));
+    Int_t etaHigh = Int_t(TMath::Abs(etaLimits[i+1]*10.0));
+
+    cout << etaCenter << ", " << etaWidth << ", " << etaLow << ", " << etaHigh << endl;
+
+    TFile* file = FindFileFresh(Form("fit_yields_results/lhc10h_aod_all_eta_%d%d.root", 
+                                    etaLow, etaHigh));
+    if(!file)
+      return;
+    
+    TH1D* hPionRatio   = (TH1D*)file->Get("hPionRatio");
+
+    Int_t bin = hPionRatio->FindBin(x);
+    if(i==0)
+      hHelp->SetTitle(Form("%s (%.1f<p_{T}<%.1f GeV/c)", 
+                          hHelp->GetTitle(),
+                          hPionRatio->GetXaxis()->GetBinLowEdge(bin),
+                          hPionRatio->GetXaxis()->GetBinUpEdge(bin)));
+
+    
+    graphPionFractions->SetPoint(i, etaCenter, hPionRatio->GetBinContent(bin)); 
+    graphPionFractions->SetPointError(i, etaWidth, hPionRatio->GetBinError(bin)); 
+    
+    TH1D* hKaonRatio   = (TH1D*)file->Get("hKaonRatio");
+    graphKaonFractions->SetPoint(i, etaCenter, hKaonRatio->GetBinContent(bin)); 
+    graphKaonFractions->SetPointError(i, etaWidth, hKaonRatio->GetBinError(bin)); 
+
+    TH1D* hProtonRatio = (TH1D*)file->Get("hProtonRatio");
+    graphProtonFractions->SetPoint(i, etaCenter, hProtonRatio->GetBinContent(bin)); 
+    graphProtonFractions->SetPointError(i, etaWidth, hProtonRatio->GetBinError(bin));     
+  }
+  
+
+  cRatios->Clear();
+  cRatios->cd();
+  hHelp->DrawCopy();
+  graphPionFractions->Draw("P");
+  graphKaonFractions->Draw("P");
+  graphProtonFractions->Draw("P");
+  gROOT->ProcessLine(".x drawText.C");
+  cRatios->SaveAs(Form("results/comparison/ratios_vs_eta_%.1f.gif", x));
+  cRatios->SaveAs(Form("results/comparison/ratios_vs_eta_%.1f.pdf", x));
+  
+  delete hHelp;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/my_functions.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/my_functions.C
new file mode 100644 (file)
index 0000000..8f1eddc
--- /dev/null
@@ -0,0 +1,259 @@
+#include <TMath.h>
+#include <TH2.h>
+#include <TProfile.h>
+
+#include <iostream>
+
+using namespace std;
+
+const Double_t eMass  = 0.000511;               //electron mass
+const Double_t piMass = 0.13957;               //pion mass
+const Double_t kMass  = 0.493676999999999977;  //kaon mass
+const Double_t pMass  = 0.938271999999999995;  //proton mass
+
+
+Double_t fitf3G(Double_t* xx, Double_t* par);
+Double_t FitFunc(Double_t* x, Double_t *par);
+Double_t SigmaFunc(Double_t* x, Double_t *par);
+
+TH2D* hDeDxVsP = 0;
+TProfile* hMeanP = 0;
+Double_t fixMIP     = 50.0;
+Double_t fixPlateau = 75.0;
+
+//______________________________________________________________________________
+Double_t fitf3G(Double_t* xx, Double_t* par)
+{
+  //
+  // Could speed up fit by forcing it to use <p>. In that way the parameters
+  // could be amde statis cand only changed when going to a new p bin
+  //
+  Double_t p = xx[0];
+  Double_t dedx = xx[1];
+
+  const Int_t bin = hDeDxVsP->GetXaxis()->FindBin(p);
+  
+  if(hMeanP) {
+    //    cout << "p before: " << p;
+    p = hMeanP->GetBinContent(bin);
+    //    cout << ", p after: " << p << endl;
+  }
+  const Int_t binStart = Int_t(par[0]);
+  const Int_t binStop  = Int_t(par[1]);
+
+  if(bin<binStart || bin>binStop) {
+    
+    cout << "Error: bin " << bin << " not inside inteval [" << binStart 
+        << "; " << binStop << "]" << endl;
+    return 0;
+  }
+
+  const Int_t nParDeDx = Int_t(par[2]);
+  
+  Double_t* parDeDx = &par[3];
+
+  Int_t offset = 4 + nParDeDx; // binStart + binStop + nParDeDx + optionDedx + nParDeDx parameters
+
+  const Int_t nParSigma = Int_t(par[offset]);
+  offset += 1; // nParSigma
+
+  Double_t* parSigma = &par[offset];
+  offset += 1 + nParSigma; // optionSigma + nParSigma parameters
+  
+  Double_t piMean = FitFunc(&p, parDeDx);
+  Double_t pKeff = p*piMass/kMass; // corresponding p of a pion with same dE/dx
+  Double_t kMean  = FitFunc(&pKeff, parDeDx);
+  Double_t pPeff = p*piMass/pMass; // corresponding p of a pion with same dE/dx
+  Double_t pMean  = FitFunc(&pPeff, parDeDx);
+
+  const Double_t piSigma = SigmaFunc(&piMean, parSigma);
+  const Double_t kSigma  = SigmaFunc(&kMean,  parSigma);
+  const Double_t pSigma  = SigmaFunc(&pMean,  parSigma);
+
+
+  const Int_t j = bin - binStart;
+  const Double_t piYield   = par[j * 3 + offset + 0];
+  const Double_t kYield    = par[j * 3 + offset + 1];
+  const Double_t pYield    = par[j * 3 + offset + 2];
+  
+  return piYield* TMath::Gaus(dedx, piMean, piSigma, kTRUE)
+    +    kYield * TMath::Gaus(dedx, kMean,  kSigma,  kTRUE)
+    +    pYield * TMath::Gaus(dedx, pMean,  pSigma,  kTRUE);
+}
+
+
+//______________________________________________________________________________
+Double_t FitFunc(Double_t* x, Double_t *par)
+{
+  static const Double_t bgMIP    = 0.5/piMass;
+  static const Double_t beta2MIP = bgMIP*bgMIP / (1.0+bgMIP*bgMIP);
+  //  static const Double_t betapowMIP = TMath;
+  static const Double_t logMIP   = TMath::Log(1+bgMIP);
+  
+  Int_t option = Int_t(par[0]);
+  Int_t specie = option;
+  option = option%10;
+  specie -= option;
+  specie /= 10;
+
+
+  Double_t bg = 0;
+  switch (specie) {
+    
+  case 0: // pion
+    bg = x[0]/piMass;
+    break;
+  case 1: // kaon
+    bg = x[0]/kMass;
+    break;
+  case 2: // proton
+    bg = x[0]/pMass;
+    break;
+  case 3: // electron
+    bg = x[0]/eMass;
+    break;
+  default:
+    cout << "Error in FitFunc: specie " << specie << " not supported!!!!!" << endl;
+    return 0;
+    break;
+  }
+    
+  if(bg > 10000.0)
+    bg = 10000.0;
+
+  const Double_t beta2 = bg*bg / (1.0+bg*bg);
+  
+  switch (option) {
+    
+  case 1: // standard parametrisation
+    {
+      /*
+       c0/beta^2 + c1 * log (1+x)
+       */
+      const Double_t c0 = par[1];
+      const Double_t c1 = par[2];
+      
+      const Double_t value = c0/beta2 + c1*TMath::Log(1+bg);          
+      return value;
+    }
+    break;
+  case 2: // fix the dE/dx to 50 at 0.5 GeV/c
+    {
+      const Double_t c1 = par[1];
+      const Double_t c0 = (fixMIP-par[1]*logMIP) * beta2MIP;
+      
+      const Double_t value = c0/beta2 + c1*TMath::Log(1+bg);          
+      return value;
+    }
+    break;
+  case 3: // fix the dE/dx to 50 at 0.5 GeV/c and the plateau to 75
+    {
+      /*
+       a/beta^2 + b/c*log( (1+x)^c / (1 + d*(1+x)^c) )
+
+       Assymptotic behavior:
+
+       1) Small bg (and d small so that d*(1+x)^c << 1)
+
+       a/beta^2 + b * log (1+x)
+       
+       So this is the same beavior as the standard expression. 
+
+       2) Large bg where d*(1+x)^c >> 1
+       a - b/c*log(d) = plateau
+       -> d = exp(c*(a-plateau)/b)
+
+       */
+      const Double_t b = par[1];
+      const Double_t a = (fixMIP-par[1]*logMIP) * beta2MIP;
+      const Double_t c = par[2];
+      const Double_t d = TMath::Exp(c*(a-fixPlateau)/b);
+
+      //      cout << bg << ": " << a << ", " << b << ", " << c << ", " << d << endl;
+
+      const Double_t powbg = TMath::Power(1.0+bg, c);
+
+      const Double_t value = a/beta2 + b/c*TMath::Log(powbg/(1.0 + d*powbg));          
+      return value;
+    }
+    break;
+  case 4: // fix the dE/dx to 50 at 0.5 GeV/c and the plateau to 75
+    {
+      /*
+       a/beta^2 + b/c*log( (1+x)^c / (1 + d*(1+x)^c) )
+
+       Assymptotic behavior:
+
+       1) Small bg (and d small so that d*(1+x)^c << 1)
+
+       a/beta^2 + b * log (1+x)
+       
+       So this is the same beavior as the standard expression. 
+
+       2) Large bg where d*(1+x)^c >> 1
+       a - b/c*log(d) = plateau
+       -> d = exp(c*(a-plateau)/b)
+
+       */
+      const Double_t a = par[1];
+      const Double_t b = par[2];
+      const Double_t c = par[3];
+      const Double_t d = TMath::Exp(c*(a-fixPlateau)/b);
+
+      //      cout << bg << ": " << a << ", " << b << ", " << c << ", " << d << endl;
+
+      const Double_t powbg = TMath::Power(1.0+bg, c);
+
+      const Double_t value = a/beta2 + b/c*TMath::Log(powbg/(1.0 + d*powbg));          
+      return value;
+    }
+    break;
+    // case 3: // fix the dE/dx to 50 at 0.5 GeV/c + powerlaw
+    
+    //   static const bgMIP    = 0.5/piMass;
+    //   static const beta2MIP = bgMIP*bgMIP / (1.0+bgMIP*bgMIP);
+    //   static const logMIP   = TMath::Log(1+bgMIP);
+    
+    //   const Double_t c1 = par[1];
+    //   const Double_t c2 = par[2]; // expect it to be 0.75 from Bichsel (beta**-1.5 instead of -2)
+    //   const Double_t c0 = (50.0-par[1]*logMIP) * beta2MIP;
+    
+    //   const Double_t value = TMathh::Power(c0/beta2, c2) + c1*TMath::Log(1+bg);          
+    //   return value;
+    
+  default:
+    break;
+  }
+  
+  cout << "Error in FitFunc: option " << option << " not supported!!!!!" << endl;
+  return 0;
+}
+
+//______________________________________________________________________________
+Double_t SigmaFunc(Double_t* x, Double_t *par)
+{
+  Int_t option = Int_t(par[0]);
+  
+  switch (option) {
+  case 1: // fixed sigma
+    return par[1];
+    break;
+  case 2: // relative sigma
+    return par[1]*x[0];
+    break;
+  case 3: // relative sigma + extrapolation
+    return (par[1] + (x[0]-fixMIP)*par[2])*x[0];
+    break;
+  case 4: // relative sigma with dE/dx to some power close to 1
+    return par[1]*TMath::Power(x[0], par[2]);
+    break;
+  case 5: // relative sigma with dE/dx to some power close to 1
+    return TMath::Sqrt(par[1]*par[1]*x[0]*x[0] + par[2]*par[2]);
+    break;
+  default:
+    break;
+  }
+  
+  cout << "Error in SigmaFunc: option " << option << " not supported!!!!!" << endl;
+  return 0;
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/my_tools.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/my_tools.C
new file mode 100644 (file)
index 0000000..11f1fae
--- /dev/null
@@ -0,0 +1,198 @@
+#include <TFile.h>
+#include <TH1.h>
+#include <TROOT.h>
+#include <TString.h>
+#include <TSystem.h>
+
+#include <iostream>
+
+#include "AliHighPtDeDxBase.h"
+
+using namespace std;
+
+
+class DeDxFitInfo : public TObject
+{
+ public:
+  
+  DeDxFitInfo();
+  void Print(Option_t* option="") const;
+
+  Double_t MIP;
+  Double_t plateau;
+
+  Int_t optionDeDx;
+  Int_t nDeDxPar;
+  Double_t parDeDx[5];
+
+  Int_t optionSigma;
+  Int_t nSigmaPar;
+  Double_t parSigma[5];
+
+  TString calibFileName;
+
+  ClassDef(DeDxFitInfo, 1);    // Help class
+};
+
+
+//_____________________________________________________________________________
+ClassImp(DeDxFitInfo)
+
+DeDxFitInfo::DeDxFitInfo():
+TObject(),
+  MIP(0),
+  plateau(0),
+  optionDeDx(-1),
+  nDeDxPar(-1),
+  optionSigma(-1),
+  nSigmaPar(-1),
+  calibFileName("")
+{
+  // default constructor
+  for(Int_t i = 0; i < 5; i++) {
+    parDeDx[i]  = 0;
+    parSigma[i] = 0;
+  }
+}
+
+//_________________________________________________________
+void DeDxFitInfo::Print(Option_t* option) const
+{
+  if(option) 
+    cout << "Option: " << option << endl;
+
+  cout << ClassName() << " : " << GetName() << endl  
+       << "MIP: " << MIP << endl
+       << "Plateau: " << plateau << endl
+       << "OptionDeDx: " << optionDeDx << endl
+       << "nDeDxPar: " << nDeDxPar << endl;
+  for(Int_t i = 0; i < nDeDxPar; i++) {
+    
+    cout << "parDeDx[" << i << "] = " << parDeDx[i] << endl;
+  }
+  cout << "OptionSigma: " << optionSigma << endl
+       << "nSigmaPar: " << nSigmaPar << endl;
+  for(Int_t i = 0; i < nSigmaPar; i++) {
+    
+    cout << "parSigma[" << i << "] = " << parSigma[i] << endl;
+  }
+  
+  if(calibFileName.IsNull()) {
+    cout << "No eta calibration file." << endl; 
+  } else {
+    cout << "Eta calibration file: " << calibFileName.Data() << endl; 
+  }
+}
+
+//_____________________________________________________________________________
+
+
+AliHighPtDeDxBase* GetObject(TFile* file, Int_t filter, Bool_t phiCut, 
+                            Int_t run, const Char_t* baseName="filter",
+                            const Char_t* endName=0);
+
+TFile* FindFileFresh(const Char_t* fileName);
+TFile* FindFile(const Char_t* fileName);
+void CutHistogram(TH1* hist, Double_t xMin, Double_t xMax);
+void SetHistError(TH1* hist, Double_t error);
+void CreateDir(const Char_t* dirName);
+
+//___________________________________________________________________________
+AliHighPtDeDxBase* GetObject(TFile* file, Int_t filter, Bool_t phiCut, Int_t run,
+                            const Char_t* baseName, const Char_t* endName)
+{
+  TString objectName(baseName);
+  if(filter>0)
+  objectName += filter;
+  if(phiCut)
+    objectName += "phicut";
+  if(run) {
+    objectName += "_";
+    objectName += run;
+  }
+  if(endName)
+    objectName += endName;
+
+  cout << "Getting object: " << objectName.Data() << endl;
+
+  return (AliHighPtDeDxBase*)(file->Get(objectName.Data()));
+}
+
+//______________________________________________________________________
+TFile* FindFileFresh(const Char_t* fileName)
+{
+  // Find file
+  TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(fileName);
+  if(file) {
+    file->Close();
+    delete file;
+  }
+
+  file = TFile::Open(fileName, "READ");
+
+  if(!file)
+    cout << "File : " << fileName << " was not found" << endl;
+
+  return file;
+}
+
+//______________________________________________________________________
+TFile* FindFile(const Char_t* fileName)
+{
+  // Find file
+  TFile *file = (TFile*)gROOT->GetListOfFiles()->FindObject(fileName);
+  if(file) {
+    return file;
+  }
+
+  file = TFile::Open(fileName, "READ");
+
+  if(!file)
+    cout << "File : " << fileName << " was not found" << endl;
+
+  return file;
+}
+
+//______________________________________________________________________
+void CutHistogram(TH1* hist, Double_t xMin, Double_t xMax)
+{
+  const Int_t n = hist->GetNbinsX();
+  
+  for(Int_t bin = 1; bin <= n; bin++) {
+    
+    Float_t x = hist->GetXaxis()->GetBinCenter(bin);
+    if(x < xMin) {
+      hist->SetBinContent(bin, 0);
+      hist->SetBinError(bin, 0);
+    } else if(x > xMax) {
+      hist->SetBinContent(bin, 0);
+      hist->SetBinError(bin, 0);
+    }
+
+  }
+}
+
+//______________________________________________________________________
+void SetHistError(TH1* hist, Double_t error)
+{
+  const Int_t n = hist->GetNbinsX();
+  
+  for(Int_t bin = 1; bin <= n; bin++) {
+    
+    //    Float_t x = hist->GetXaxis()->GetBinCenter(bin);
+    hist->SetBinError(bin, error);
+  }
+}
+
+//______________________________________________________________________
+void CreateDir(const Char_t* dirName)
+{
+  TString pwd(gSystem->pwd());
+  gSystem->cd(pwd.Data());
+  
+  if(gSystem->cd(dirName)) {
+    gSystem->cd(pwd.Data());
+  } else {
+    gSystem->mkdir(dirName, kTRUE); // kTRUE means recursive
+  }
+}
diff --git a/PWGLF/SPECTRA/IdentifiedHighPt/macros/run_code.C b/PWGLF/SPECTRA/IdentifiedHighPt/macros/run_code.C
new file mode 100644 (file)
index 0000000..daeb262
--- /dev/null
@@ -0,0 +1,1501 @@
+#include <TFile.h>
+#include <TList.h>
+#include <TTree.h>
+#include <TChain.h>
+#include <TClonesArray.h>
+#include <TObjString.h>
+#include <TString.h>
+#include <TROOT.h>
+
+#include "AliHighPtDeDxData.h"
+#include "AliHighPtDeDxMc.h"
+#include "AliHighPtDeDxCalib.h"
+
+#include <AliXRDPROOFtoolkit.h>
+
+#include "DebugClasses.C"
+#include "my_tools.C"
+#include "my_functions.C"
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+using namespace std;
+
+/*
+
+  In this version the start step for calibrations is 2. We do not correct for
+  the Ncl dependence as this is still uncertain of this should be done or not.
+
+  It is good to make a small test first because the MIP peak might have to be
+  adjusted. With pass0 the default 40-60 window should be good, but
+
+  To run calibrations:
+  ====================
+
+  Use AliRoot because of AliXRDPROOFtoolkit:
+   gSystem->AddIncludePath("-I$ALICE_ROOT/TPC")
+   gSystem->AddIncludePath("-I../lib")
+   gSystem->AddIncludePath("-I../grid")
+   gSystem->AddIncludePath("-I../macros")
+   gROOT->SetMacroPath(".:../macros:../grid:../lib/")
+  .L libMyDeDxAnalysis.so 
+  .L my_functions.C+
+  .L my_tools.C+
+  .L DebugClasses.C+
+  .L run_code.C+
+
+  // Step 1: create calibrations
+
+  CreateCalib("7tev_b.dat", kFALSE, "7tev_b.root", 0, 2)  
+
+  // This function is not used anymore
+  // CreateCalibV0("7tev_b_v0.dat", kFALSE, "7tev_b_v0_loose.root", 0)
+
+
+  // Step 2 and 3 are found in calibrate_de_dx.C
+
+
+  // Step 5: create data
+  CreateOutput("7tev_b.dat", kFALSE, "7tev_b.root", 0, "fitparameters/7tev_b.root")
+  CreateOutputV0("7tev_b_v0.dat", kFALSE, "7tev_b_v0_loose.root", 0, "fitparameters/7tev_b.root")
+
+
+
+
+  // Test examples
+  // Step 1
+  CreateCalib("7tev_b_test.dat", kFALSE, "7tev_b_test.root", 0, 2)  
+  // Step 5
+  CreateOutput("7tev_b_test.dat", kFALSE, "7tev_b_test.root", 0, "fitparameters/7tev_b_test.root")
+  CreateOutputV0("7tev_b_test_v0.dat", kFALSE, "7tev_b_test_v0_loose.root", 0, "fitparameters/7tev_b_test.root")
+
+ */
+
+
+const Int_t nPtBins = 68;
+//Double_t xBins[nPtBins+1] = {0., 0.2, 0.25, 0.3, 0.35, 0.4, 0.45, 0.5, 0.55, 0.6, 0.65, 0.7, 0.75, 0.8, 0.85, 0.9, 0.95, 1.0, 1.1 , 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 8.0, 9.0, 10.0};
+Double_t xBins[nPtBins+1] = {0. ,  0.05, 0.1,  0.15, 0.2,  0.25, 0.3,  0.35, 0.4,  0.45,
+                            0.5,  0.55, 0.6,  0.65, 0.7,  0.75, 0.8,  0.85, 0.9,  0.95,
+                            1.0,  1.1 , 1.2,  1.3 , 1.4,  1.5 , 1.6,  1.7 , 1.8,  1.9 ,
+                            2.0,  2.2 , 2.4,  2.6 , 2.8,  3.0 , 3.2,  3.4 , 3.6,  3.8 ,
+                            4.0,  4.5 , 5.0,  5.5 , 6.0,  6.5 , 7.0,  8.0 , 9.0,  10.0,
+                            11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 18.0, 20.0, 22.0, 24.0,
+                            26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 40.0, 45.0, 50.0 };
+
+TFile* dataOutFile = 0;
+TFile* mcOutFile   = 0;
+
+TF1* piFunc = 0;
+TF1* kFunc  = 0;
+TF1* pFunc = 0;
+TF1* eFunc = 0;
+TF1* sigmaFunc = 0;
+
+void CreateOutput(const Char_t* dataFileName, Bool_t isMc, 
+                 const Char_t* outfilename, Int_t maxEvents,
+                 const Char_t* fitFileName=0);
+void AddObject(TList* list, Int_t filter, Bool_t phiCut, Int_t run, 
+              Bool_t analyzeMc, Bool_t etaCut = kFALSE, Bool_t etaAbs = kFALSE, 
+              Int_t etaLow=-8, Int_t etaHigh=8);
+void CreateOutputV0(const Char_t* dataFileName, Bool_t isMc, 
+                   const Char_t* outFileName, Int_t maxEvents,
+                   const Char_t* fitFileName=0);
+void AddObjectV0(TList* list, const Char_t* baseName, Bool_t phiCut, Int_t run, 
+                Bool_t analyzeMc, Bool_t etaCut = kFALSE, Bool_t etaAbs = kFALSE, 
+              Int_t etaLow=-8, Int_t etaHigh=8);
+
+void CreateCalib(const Char_t* dataFileName, Bool_t isMc, 
+                const Char_t* outfilename, Int_t maxEvents, Int_t startStep);
+void AddCalibObject(TList* list, Int_t filter, Bool_t phiCut, Int_t run, 
+                   Bool_t analyzeMc, Bool_t etaCut = kFALSE, Bool_t etaAbs = kFALSE, 
+                   Int_t etaLow=-8, Int_t etaHigh=8);
+void CreateCalibV0(const Char_t* dataFileName, Bool_t isMc, 
+                  const Char_t* outFileName, Int_t maxEvents);
+void AddCalibObjectV0(TList* list, const Char_t* baseName, Bool_t phiCut, 
+                     Int_t run, Bool_t analyzeMc);
+Int_t CalculateFilter(DeDxTrack* track);
+
+//____________________________________________________________________________
+void CreateOutput(const Char_t* dataFileName, Bool_t isMc, 
+                 const Char_t* outFileName, Int_t maxEvents,
+                 const Char_t* fitFileName)
+{
+
+  TF1* fDeDxVsEtaNeg = 0;
+  TF1* fDeDxVsEtaPos = 0;
+  TF1* fDeDxVsNcl    = 0;
+
+  if(fitFileName) {
+
+    TFile* fitFile = FindFileFresh(fitFileName);
+    if(!fitFile)
+      return;
+    DeDxFitInfo* fitPar = (DeDxFitInfo*)fitFile->Get("fitInfo");
+    fitPar->Print();
+  
+
+    if(!fitPar->calibFileName.IsNull()) {
+
+      cout << "Setting calibFile: " << fitPar->calibFileName << endl;
+      TFile* calibFile = FindFileFresh(fitPar->calibFileName);
+      if(!calibFile)
+       return;
+      AliHighPtDeDxCalib* calib = (AliHighPtDeDxCalib*)GetObject(calibFile, 1, kTRUE, 0);
+      calib->Print();
+      fDeDxVsEtaNeg = calib->GetDeDxVsEtaNeg();
+      fDeDxVsEtaPos = calib->GetDeDxVsEtaPos();
+      fDeDxVsNcl    = calib->GetDeDxVsNcl();
+    }
+  
+    fixMIP      = fitPar->MIP;
+    fixPlateau  = fitPar->plateau;
+
+    Double_t dedxPar[6]  = {0, 0, 0, 0, 0, 0};
+    Double_t sigmaPar[6] = {0, 0, 0, 0, 0, 0};
+    
+    dedxPar[0] = fitPar->optionDeDx;
+    for(Int_t i = 0; i < fitPar->nDeDxPar; i++) {
+      dedxPar[i+1] = fitPar->parDeDx[i];
+    }
+
+    sigmaPar[0] = fitPar->optionSigma;
+    for(Int_t i = 0; i < fitPar->nSigmaPar; i++) {
+      sigmaPar[i+1] = fitPar->parSigma[i];
+    }
+
+    piFunc = new TF1("piFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    piFunc->SetParameters(dedxPar);
+
+    kFunc = new TF1("kFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    kFunc->SetParameters(dedxPar);
+    kFunc->SetParameter(0, kFunc->GetParameter(0)+10);
+
+    pFunc = new TF1("pFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    pFunc->SetParameters(dedxPar);
+    pFunc->SetParameter(0, pFunc->GetParameter(0)+20);
+
+    eFunc = new TF1("eFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    eFunc->SetParameters(dedxPar);
+    eFunc->SetParameter(0, eFunc->GetParameter(0)+30);
+
+    sigmaFunc = new TF1("sigmaFunc", SigmaFunc, 0, 100, fitPar->nSigmaPar+1); 
+    sigmaFunc->SetParameters(sigmaPar);
+  }
+
+  CreateDir("data");
+  dataOutFile = new TFile(Form("data/%s", outFileName), "RECREATE");
+  if(isMc) {
+    
+    CreateDir("mc");
+    mcOutFile = new TFile(Form("mc/%s", outFileName), "RECREATE");
+  }
+
+  // Create output objects
+  dataOutFile->cd();
+  TList* runList = new TList();
+  runList->SetOwner(kTRUE);
+  runList->SetBit(TObject::kSingleKey);
+  
+  TList* analysisList = new TList();
+  analysisList->SetOwner(kFALSE);
+  
+  //        TList    filter, phi cut, run, isMc
+  AddObject(analysisList, 1, kTRUE,  0, isMc); 
+  if(kTRUE) {
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, -8, -6); 
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, -6, -4); 
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, -4, -2); 
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, -2,  0); 
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, 0, 2); 
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, 2, 4); 
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, 4, 6); 
+    AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, 6, 8); 
+  }
+  AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, -8, 0); 
+  AddObject(analysisList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, 0, 8); 
+  AddObject(analysisList, 1, kTRUE,  0, isMc, kFALSE, kTRUE, 0, 4); 
+  AddObject(analysisList, 1, kTRUE,  0, isMc, kFALSE, kTRUE, 4, 8); 
+  AddObject(analysisList, 1, kFALSE, 0, isMc); 
+  AddObject(analysisList, 2, kTRUE,  0, isMc); 
+  AddObject(analysisList, 2, kFALSE, 0, isMc); 
+  
+  TTree* Tree = 0;
+  
+  if(strstr(dataFileName, ".dat")) {
+    
+    AliXRDPROOFtoolkit tool;
+    TChain* chain = tool.MakeChain(dataFileName,"tree", 0, 1000);
+    //    chain->Lookup();
+    Tree = chain;
+  } else {
+    TFile* dataFile = FindFileFresh(dataFileName);
+    if(!dataFile)
+      return;
+    
+    Tree = (TTree*)dataFile->Get("tree");
+  }
+
+  TClonesArray* trackArray = 0;
+  TClonesArray* mcTrackArray = 0;
+  DeDxEvent* event = 0;
+  Tree->SetBranchAddress("event", &event);
+  Tree->SetBranchAddress("trackGlobalPar"  , &trackArray);
+  if(isMc)
+    Tree->SetBranchAddress("trackMC"  , &mcTrackArray);
+
+  Int_t nEvents = Tree->GetEntries();
+  cout << "Number of events: " << nEvents << endl;
+  
+  if(maxEvents>0 && maxEvents < nEvents) {
+    
+    nEvents = maxEvents;
+    cout << "N events was reduced to: " << maxEvents << endl;
+  }
+
+  Int_t currentRun = 0;
+  Int_t nBad = 0;
+  TIter* iter = new TIter(analysisList);
+  
+  for(Int_t n = 0; n < nEvents; n++) {
+    
+    Tree->GetEntry(n);
+    
+    if((n+1)%1000000==0)
+      cout << "Event: " << n+1 << "/" << nEvents << endl;
+
+    // A few bad entries
+    if(event->run == -1) {
+      nBad++;
+      continue;
+    }
+
+    if(event->run != currentRun) {
+      
+      cout << "New run: " << event->run << endl;
+      currentRun = event->run;
+      
+      // Check if run objects exist
+      TObjString* runString = new TObjString(Form("%d", currentRun));
+      if(!runList->FindObject(runString->GetString().Data())) {
+       
+       runList->Add(runString);
+       
+       //        TList    filter, phi cut, run, isMc
+       AddObject(analysisList, 1, kTRUE,  currentRun, isMc); 
+       AddObject(analysisList, 1, kFALSE, currentRun, isMc); 
+       // AddObject(analysisList, 2, kTRUE,  currentRun, isMc); 
+       // AddObject(analysisList, 2, kFALSE, currentRun, isMc); 
+       
+       // Is this really necessary?
+       delete iter;
+       iter = new TIter(analysisList);
+
+      } else {
+
+       delete runString;
+      }
+    }
+
+    // iterate over analysis list
+    iter->Reset();
+    AliHighPtDeDxBase* analysis = 0;
+    while ((analysis = dynamic_cast<AliHighPtDeDxBase*> (iter->Next()))) {
+      
+      // First we set the global properties
+      // If I want to use a narrower vtx I have here to redefine my 
+      // vtxstatus according to the new vtx range
+      analysis->SetEventRun(event->run);
+      analysis->SetEventMag(event->mag);
+      analysis->SetEventVtxStatus(event->vtxstatus);
+      analysis->SetEventTrigger(event->trig);
+
+      Int_t vtxstatusmc = 0;
+      if(TMath::Abs(event->zvtxMC) < 10.0)
+       vtxstatusmc = 1;
+      analysis->SetEventVtxStatusMc(vtxstatusmc);
+
+      if(!analysis->EventAccepted()) // only checks for runs currently
+       continue;
+
+      // There is a small prolem in making this really nice, because we need
+      // also event info from events that are rejected by the vtx cut to
+      // correct our data. That is why we for bnow only have the run cut there
+      
+      analysis->FillEventInfo();
+      
+      // First we do the special MC part
+      if(isMc) {
+       
+       AliHighPtDeDxMc* mcAnalysis = dynamic_cast<AliHighPtDeDxMc*> (analysis);
+       if(mcAnalysis) {
+         if(vtxstatusmc) {
+           
+           // loop over mc tracks
+           const Int_t nMcTracks = mcTrackArray->GetEntries();
+           
+           for(Int_t i = 0; i < nMcTracks; i++) {
+             
+             DeDxTrackMC* trackMC = (DeDxTrackMC*)mcTrackArray->At(i);
+             
+             mcAnalysis->SetTrackPtMc(trackMC->ptMC);
+             mcAnalysis->SetTrackEtaMc(trackMC->etaMC);
+             mcAnalysis->SetTrackChargeMc(trackMC->qMC);
+             mcAnalysis->SetTrackPidMc(trackMC->pidMC);
+             if(mcAnalysis->TrackAcceptedMc()) {
+               // if(trackMC->ptMC<2.0)
+               //   mcAnalysis->FillTrackInfoMc(100.0);
+               // else
+                 mcAnalysis->FillTrackInfoMc(1.0);
+             }
+           }
+         }
+       }
+      }
+      
+      // The trig==1 is always true for real data, but not for MC data
+      if(!event->trig)
+       continue;
+       
+      if(event->vtxstatus<1) // only fill tracks for events with vtx inside cuts
+       continue;
+      
+      const Int_t nTracks = trackArray->GetEntries();
+      
+      for(Int_t i = 0; i < nTracks; i++) {
+       
+       DeDxTrack* track = (DeDxTrack*)trackArray->At(i);
+       
+       Double_t eta  = track->eta;
+       Double_t dedx = track->dedx;
+       Int_t ncl     = track->ncl;
+       if(fDeDxVsEtaNeg) {
+
+         dedx *= 50.0 / fDeDxVsNcl->Eval(ncl);
+
+         if(eta < 0) 
+           dedx *= 50.0 / fDeDxVsEtaNeg->Eval(eta);
+         else
+           dedx *= 50.0 / fDeDxVsEtaPos->Eval(eta);
+       }
+       
+       analysis->SetTrackCharge(track->q);
+       analysis->SetTrackP(track->p);
+       analysis->SetTrackPt(track->pt);
+       //
+       Int_t filter = CalculateFilter(track);
+       analysis->SetTrackFilter(filter);
+       analysis->SetTrackPhi(track->phi);
+       analysis->SetTrackDeDx(dedx);
+       analysis->SetTrackNcl(ncl);
+       analysis->SetTrackEta(eta);
+       analysis->SetTrackPidMc(track->pid);
+
+       if(analysis->TrackAccepted()) {
+         // if(track->pt<2.0)
+         //   analysis->FillTrackInfo(100.0);
+         // else
+           analysis->FillTrackInfo(1.0);
+       }
+      }
+    }
+  }
+  
+  if(isMc) {
+
+    TList* runListMc = (TList*)runList->Clone();
+    mcOutFile->cd();
+    runListMc->Write();
+
+    // I need to somehow specify autowrite, but I am not sure how, so for now
+    // this a bit stupid workaround...
+    iter->Reset();
+    AliHighPtDeDxBase* analysis = 0;
+    while ((analysis = dynamic_cast<AliHighPtDeDxBase*> (iter->Next()))) {
+      
+      AliHighPtDeDxMc* mcAnalysis = dynamic_cast<AliHighPtDeDxMc*> (analysis);
+      if(mcAnalysis) {
+       mcAnalysis->Write();
+      }
+    }
+    mcOutFile->Close();
+    delete mcOutFile;
+    mcOutFile = 0;
+  }
+
+  dataOutFile->cd();
+  runList->Write("runList");
+  iter->Reset();
+  AliHighPtDeDxBase* analysis = 0;
+  while ((analysis = dynamic_cast<AliHighPtDeDxBase*> (iter->Next()))) {
+    
+    AliHighPtDeDxData* dataAnalysis = dynamic_cast<AliHighPtDeDxData*> (analysis);
+    if(dataAnalysis) {
+      dataAnalysis->Write();
+    }
+  }
+  dataOutFile->Close();
+  delete dataOutFile;
+  dataOutFile = 0;
+
+  cout << "Nbad (runno == -1) : " << nBad << endl;
+}
+
+//___________________________________________________________________________
+void AddObject(TList* list, Int_t filter, Bool_t phiCut, Int_t run, 
+              Bool_t analyzeMc, Bool_t etaCut, Bool_t etaAbs, 
+              Int_t etaLow, Int_t etaHigh)
+{
+  if(etaCut && etaAbs) {
+
+    Fatal("AddObject", "You cannot have a cut on both abs and signed eta");
+    return;
+  }
+  TString objectName("filter");
+  objectName += filter;
+  if(phiCut)
+    objectName += "phicut";
+  if(run) {
+    objectName += "_";
+    objectName += run;
+  }
+  if(etaCut) {
+    objectName += "eta";
+    objectName += etaLow;
+    objectName += etaHigh;
+  }
+  if(etaAbs) {
+    objectName += "etaabs";
+    objectName += etaLow;
+    objectName += etaHigh;
+  }
+
+  dataOutFile->cd();
+  AliHighPtDeDxData* data = new AliHighPtDeDxData(objectName.Data(), "Analysis data");
+  if(run) {
+    data->SetUseRunCut(kTRUE);
+    data->SetRun(run);
+  }
+
+  list->Add(data);
+  data->SetIsMc(analyzeMc);
+  data->SetUseFilterCut(kTRUE);
+  data->SetFilter(filter);
+  data->SetUsePhiCut(phiCut);
+  if(phiCut) {
+    data->SetPhiCutLow(data->GetStandardPhiCutLow());
+    data->SetPhiCutHigh(data->GetStandardPhiCutHigh());
+  }
+  if(etaCut)
+    data->SetUseEtaCut(kTRUE);
+  if(etaAbs)
+    data->SetUseEtaCutAbs(kTRUE);
+  if(etaCut || etaAbs) {
+    data->SetEtaLow(Double_t(etaLow)/10.0);
+    data->SetEtaHigh(Double_t(etaHigh)/10.0);
+  }
+
+  data->Init(nPtBins, xBins);
+  data->Print();
+
+  if(piFunc && kFunc && pFunc && eFunc && sigmaFunc) {
+
+    data->SetPionDeDxFunction(piFunc);
+    data->SetKaonDeDxFunction(kFunc);
+    data->SetProtonDeDxFunction(pFunc);
+    data->SetElectronDeDxFunction(eFunc);
+    data->SetSigmaDeDxFunction(sigmaFunc);
+  }
+
+  if(analyzeMc) {
+    // create the correction class also
+    
+    mcOutFile->cd();
+    AliHighPtDeDxMc* mc = new AliHighPtDeDxMc(objectName.Data(), "Analysis mc");
+    if(run) {
+      mc->SetUseRunCut(kTRUE);
+      mc->SetRun(run);
+    }
+    
+    list->Add(mc);
+    mc->SetUseFilterCut(kTRUE);
+    mc->SetFilter(filter);
+    mc->SetUsePhiCut(phiCut);
+    if(phiCut) {
+      mc->SetPhiCutLow(mc->GetStandardPhiCutLow());
+      mc->SetPhiCutHigh(mc->GetStandardPhiCutHigh());
+    }
+    mc->Init(nPtBins, xBins);
+    mc->Print();
+  }
+}
+
+//____________________________________________________________________________
+void CreateOutputV0(const Char_t* dataFileName, Bool_t isMc, 
+                   const Char_t* outFileName, Int_t maxEvents,
+                   const Char_t* fitFileName)
+{
+
+  TF1* fDeDxVsEtaNeg = 0;
+  TF1* fDeDxVsEtaPos = 0;
+  TF1* fDeDxVsNcl    = 0;
+
+  if(fitFileName) {
+
+    TFile* fitFile = FindFileFresh(fitFileName);
+    if(!fitFile)
+      return;
+    DeDxFitInfo* fitPar = (DeDxFitInfo*)fitFile->Get("fitInfo");
+    fitPar->Print();
+  
+
+    if(!fitPar->calibFileName.IsNull()) {
+
+      cout << "Setting calibFile: " << fitPar->calibFileName << endl;
+      TFile* calibFile = FindFileFresh(fitPar->calibFileName);
+      if(!calibFile)
+       return;
+      AliHighPtDeDxCalib* calib = (AliHighPtDeDxCalib*)GetObject(calibFile, 1, kTRUE, 0);
+      calib->Print();
+      fDeDxVsEtaNeg = calib->GetDeDxVsEtaNeg();
+      fDeDxVsEtaPos = calib->GetDeDxVsEtaPos();
+      fDeDxVsNcl    = calib->GetDeDxVsNcl();
+    }
+  
+    fixMIP      = fitPar->MIP;
+    fixPlateau  = fitPar->plateau;
+
+    Double_t dedxPar[6]  = {0, 0, 0, 0, 0, 0};
+    Double_t sigmaPar[6] = {0, 0, 0, 0, 0, 0};
+    
+    dedxPar[0] = fitPar->optionDeDx;
+    for(Int_t i = 0; i < fitPar->nDeDxPar; i++) {
+      dedxPar[i+1] = fitPar->parDeDx[i];
+    }
+
+    sigmaPar[0] = fitPar->optionSigma;
+    for(Int_t i = 0; i < fitPar->nSigmaPar; i++) {
+      sigmaPar[i+1] = fitPar->parSigma[i];
+    }
+
+    piFunc = new TF1("piFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    piFunc->SetParameters(dedxPar);
+
+    kFunc = new TF1("kFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    kFunc->SetParameters(dedxPar);
+    kFunc->SetParameter(0, kFunc->GetParameter(0)+10);
+
+    pFunc = new TF1("pFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    pFunc->SetParameters(dedxPar);
+    pFunc->SetParameter(0, pFunc->GetParameter(0)+20);
+
+    eFunc = new TF1("eFunc", FitFunc, 0, 100, fitPar->nDeDxPar+1);
+    eFunc->SetParameters(dedxPar);
+    eFunc->SetParameter(0, eFunc->GetParameter(0)+30);
+
+    sigmaFunc = new TF1("sigmaFunc", SigmaFunc, 0, 100, fitPar->nSigmaPar+1); 
+    sigmaFunc->SetParameters(sigmaPar);
+  }
+
+  CreateDir("data");
+  dataOutFile = new TFile(Form("data/%s", outFileName), "RECREATE");
+
+  // Create output objects
+  dataOutFile->cd();
+  TList* runList = new TList();
+  runList->SetOwner(kTRUE);
+  runList->SetBit(TObject::kSingleKey);
+  
+  TList* analysisList = new TList();
+  analysisList->SetOwner(kFALSE);
+  
+  //               TList      v0type, phi cut, run, isMc
+  AddObjectV0(analysisList, "lambda", kTRUE,  0, isMc); 
+  AddObjectV0(analysisList, "lambda", kTRUE,  0, isMc, kTRUE, kFALSE, -8, 0); 
+  AddObjectV0(analysisList, "lambda", kTRUE,  0, isMc, kTRUE, kFALSE, 0, 8); 
+  AddObjectV0(analysisList, "lambda", kTRUE,  0, isMc, kFALSE, kTRUE, 0, 4); 
+  AddObjectV0(analysisList, "lambda", kTRUE,  0, isMc, kFALSE, kTRUE, 4, 8); 
+  AddObjectV0(analysisList, "kaon", kTRUE,  0, isMc); 
+  AddObjectV0(analysisList, "kaon", kTRUE,  0, isMc, kTRUE, kFALSE, -8, 0); 
+  AddObjectV0(analysisList, "kaon", kTRUE,  0, isMc, kTRUE, kFALSE, 0, 8); 
+  AddObjectV0(analysisList, "kaon", kTRUE,  0, isMc, kFALSE, kTRUE, 0, 4); 
+  AddObjectV0(analysisList, "kaon", kTRUE,  0, isMc, kFALSE, kTRUE, 4, 8); 
+  
+  TTree* Tree = 0;
+  
+  if(strstr(dataFileName, ".dat")) {
+    
+    AliXRDPROOFtoolkit tool;
+    TChain* chain = tool.MakeChain(dataFileName,"tree", 0, 1000);
+    //    chain->Lookup();
+    Tree = chain;
+  } else {
+    TFile* dataFile = FindFileFresh(dataFileName);
+    if(!dataFile)
+      return;
+    
+    Tree = (TTree*)dataFile->Get("tree");
+  }
+
+  TClonesArray* v0Array = 0;
+  DeDxEvent* event = 0;
+  Tree->SetBranchAddress("event", &event);
+  Tree->SetBranchAddress("v0GlobalPar"  , &v0Array);
+
+  Int_t nEvents = Tree->GetEntries();
+  cout << "Number of events: " << nEvents << endl;
+  
+  if(maxEvents>0 && maxEvents < nEvents) {
+    
+    nEvents = maxEvents;
+    cout << "N events was reduced to: " << maxEvents << endl;
+  }
+
+  Int_t currentRun = 0;
+  Int_t nBad = 0;
+  TIter* iter = new TIter(analysisList);
+  
+  for(Int_t n = 0; n < nEvents; n++) {
+    
+    Tree->GetEntry(n);
+    
+    if((n+1)%1000000==0)
+      cout << "Event: " << n+1 << "/" << nEvents << endl;
+
+    if(event->run == -1) {
+      nBad++;
+      continue;
+    }
+    // if(event->run == 126437)
+    //   continue;
+    
+    if(event->run != currentRun) {
+      
+      cout << "New run: " << event->run << endl;
+      currentRun = event->run;
+      
+      // Check if run objects exist
+      TObjString* runString = new TObjString(Form("%d", currentRun));
+      if(!runList->FindObject(runString->GetString().Data())) {
+       
+       runList->Add(runString);
+       
+       //               TList      v0type, phi cut, run, isMc
+       AddObjectV0(analysisList, "lambda", kTRUE,  currentRun, isMc); 
+       AddObjectV0(analysisList, "kaon", kTRUE,  currentRun, isMc); 
+       
+       // Is this really necessary?
+       delete iter;
+       iter = new TIter(analysisList);
+
+      } else {
+
+       delete runString;
+      }
+    }
+
+    // iterate over analysis list
+    iter->Reset();
+    AliHighPtDeDxBase* analysis = 0;
+    while ((analysis = dynamic_cast<AliHighPtDeDxBase*> (iter->Next()))) {
+      
+      // First we set the global properties
+      // If I want to use a narrower vtx I have here to redefine my 
+      // vtxstatus according to the new vtx range
+      analysis->SetEventRun(event->run);
+      analysis->SetEventMag(event->mag);
+      analysis->SetEventVtxStatus(event->vtxstatus);
+      analysis->SetEventTrigger(event->trig);
+
+      Int_t vtxstatusmc = 0;
+      if(TMath::Abs(event->zvtxMC) < 10.0)
+       vtxstatusmc = 1;
+      analysis->SetEventVtxStatusMc(vtxstatusmc);
+
+      if(!analysis->EventAccepted()) // only checks for runs currently
+       continue;
+      // There is a small prolem in making this really nice, because we need
+      // also event info from events that are rejected by the vtx cut to
+      // correct our data. That is why we for bnow only have the run cut there
+      
+      analysis->FillEventInfo();
+      
+      
+      // The trig==1 is always true for real data, but not for MC data
+      if(!event->trig)
+       continue;
+       
+      if(event->vtxstatus<1) // only fill tracks for events with vtx inside cuts
+       continue;
+      
+      const Int_t nV0s = v0Array->GetEntries();
+      
+      for(Int_t i = 0; i < nV0s; i++) {
+       
+       DeDxV0* v0 = (DeDxV0*)v0Array->At(i);
+       
+       // if(v0->ptrack.filter != 2)
+       //   continue;
+
+       if(v0->status != 0)
+         continue;
+
+       if(v0->dmassG < 0.1)
+         continue;
+
+       // if(v0->decayr < 5.0)
+       //   continue;
+
+       // if(v0->decayr > 40.0)
+       //   continue;
+       
+       const Double_t dmassK  = TMath::Abs(v0->dmassK0);
+       const Double_t dmassL  = TMath::Abs(v0->dmassL);
+       const Double_t dmassAL = TMath::Abs(v0->dmassAL);
+       
+       Bool_t fillPos = kFALSE;
+       Bool_t fillNeg = kFALSE;
+                                          
+       
+       if(strstr(analysis->GetName(), "lambda")) {
+         
+         if(dmassK<0.01)
+           continue;
+
+         if(dmassL<0.01&&dmassL>0.01)
+           fillPos = kTRUE;
+
+         if(dmassAL<0.01&&dmassL)
+           fillNeg = kTRUE;
+       } else { // kaons
+
+         if(dmassL<0.01 || dmassAL<0.01)
+           continue;
+
+         if(dmassK<0.01) {
+           fillPos = kTRUE;
+           fillNeg = kTRUE;
+         }
+       }
+
+       for(Int_t j = 0; j < 2; j++) {
+
+         DeDxTrack* track = 0;
+         
+         if(j==0) {
+
+           if(fillNeg)
+             track = &(v0->ntrack);
+           else
+             continue;
+         } else {
+
+           if(fillPos)
+             track = &(v0->ptrack);
+           else
+             continue;
+         }
+
+         Double_t eta  = track->eta;
+         Double_t dedx = track->dedx;
+         Int_t ncl     = track->ncl;
+         if(fDeDxVsEtaNeg) {
+           
+           dedx *= 50.0 / fDeDxVsNcl->Eval(ncl);
+           
+           if(eta < 0) 
+             dedx *= 50.0 / fDeDxVsEtaNeg->Eval(eta);
+           else
+             dedx *= 50.0 / fDeDxVsEtaPos->Eval(eta);
+         }
+         
+         analysis->SetTrackCharge(track->q);
+         analysis->SetTrackP(track->p);
+         analysis->SetTrackPt(track->pt);
+         // NB! Not used
+         analysis->SetTrackFilter(track->filter);
+         analysis->SetTrackPhi(track->phi);
+         analysis->SetTrackDeDx(dedx);
+         analysis->SetTrackNcl(ncl);
+         analysis->SetTrackBeta(track->beta);
+         analysis->SetTrackPidMc(track->pid);
+         analysis->SetTrackEta(eta);
+         
+         if(analysis->TrackAccepted()) {
+           analysis->FillTrackInfo(1.0);
+         }
+       }
+      }
+    }
+  }
+  
+  dataOutFile->cd();
+  runList->Write("runList");
+  iter->Reset();
+  AliHighPtDeDxBase* analysis = 0;
+  while ((analysis = dynamic_cast<AliHighPtDeDxBase*> (iter->Next()))) {
+    
+    AliHighPtDeDxData* dataAnalysis = dynamic_cast<AliHighPtDeDxData*> (analysis);
+    if(dataAnalysis) {
+      dataAnalysis->Write();
+    }
+  }
+  dataOutFile->Close();
+  delete dataOutFile;
+  dataOutFile = 0;
+
+  cout << "Nbad (runno == -1) : " << nBad << endl;
+}
+
+
+//___________________________________________________________________________
+void AddObjectV0(TList* list, const Char_t* baseName, Bool_t phiCut, Int_t run, 
+                Bool_t analyzeMc, Bool_t etaCut, Bool_t etaAbs, 
+                Int_t etaLow, Int_t etaHigh)
+{
+  if(etaCut && etaAbs) {
+
+    Fatal("AddObject", "You cannot have a cut on both abs and signed eta");
+    return;
+  }
+
+  TString objectName(baseName);
+  if(phiCut)
+    objectName += "phicut";
+  if(run) {
+    objectName += "_";
+    objectName += run;
+  }
+  if(etaCut) {
+    objectName += "eta";
+    objectName += etaLow;
+    objectName += etaHigh;
+  }
+  if(etaAbs) {
+    objectName += "etaabs";
+    objectName += etaLow;
+    objectName += etaHigh;
+  }
+  dataOutFile->cd();
+  AliHighPtDeDxData* data = new AliHighPtDeDxData(objectName.Data(), "Analysis data");
+  if(run) {
+    data->SetUseRunCut(kTRUE);
+    data->SetRun(run);
+  }
+  
+  list->Add(data);
+  data->SetIsMc(analyzeMc);
+  data->SetUseFilterCut(kFALSE);
+
+  data->SetUsePhiCut(phiCut);
+  if(phiCut) {
+    data->SetPhiCutLow(data->GetStandardPhiCutLow());
+    data->SetPhiCutHigh(data->GetStandardPhiCutHigh());
+  }
+  if(etaCut)
+    data->SetUseEtaCut(kTRUE);
+  if(etaAbs)
+    data->SetUseEtaCutAbs(kTRUE);
+  if(etaCut || etaAbs) {
+    data->SetEtaLow(Double_t(etaLow)/10.0);
+    data->SetEtaHigh(Double_t(etaHigh)/10.0);
+  }
+
+  data->Init(nPtBins, xBins);
+  data->Print();
+
+  if(piFunc && kFunc && pFunc && eFunc && sigmaFunc) {
+
+    data->SetPionDeDxFunction(piFunc);
+    data->SetKaonDeDxFunction(kFunc);
+    data->SetProtonDeDxFunction(pFunc);
+    data->SetElectronDeDxFunction(eFunc);
+    data->SetSigmaDeDxFunction(sigmaFunc);
+  }
+}
+
+//____________________________________________________________________________
+void CreateCalib(const Char_t* dataFileName, Bool_t isMc, 
+                const Char_t* outFileName, Int_t maxEvents, Int_t startStep)
+{
+  if(startStep < 1 || startStep > 3) {
+
+    cout << "Start step should be 1,2, or 3 - 2 is recommended" << endl;
+  }
+
+  if(startStep == 1) {
+
+    for(Int_t i = 0; i < 10; i++)
+      cout << "Step 1 calibration is depreceated! - 2 is recommended" << endl;
+  }
+  
+  if(startStep<3) {
+
+    CreateDir("calib_eta");
+    dataOutFile = new TFile(Form("calib_eta/%s", outFileName), "RECREATE");
+  } else {
+
+    CreateDir("no_calib_eta");
+    dataOutFile = new TFile(Form("no_calib_eta/%s", outFileName), "RECREATE");
+  }
+
+  // Create output objects
+  dataOutFile->cd();
+  TList* runList = new TList();
+  runList->SetOwner(kTRUE);
+  runList->SetBit(TObject::kSingleKey);
+  
+  TList* calibList = new TList();
+  calibList->SetOwner(kFALSE);
+  
+  //        TList    filter, phi cut, run, isMc
+  AddCalibObject(calibList, 1, kTRUE,  0, isMc); 
+  AddCalibObject(calibList, 2, kTRUE,  0, isMc); 
+  AddCalibObject(calibList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, -8, 0); 
+  AddCalibObject(calibList, 1, kTRUE,  0, isMc, kTRUE, kFALSE, 0, 8); 
+  AddCalibObject(calibList, 1, kTRUE,  0, isMc, kFALSE, kTRUE, 0, 4); 
+  AddCalibObject(calibList, 1, kTRUE,  0, isMc, kFALSE, kTRUE, 4, 8); 
+  //  AddCalibObject(calibList, 1, kFALSE, 0, isMc); 
+  //  AddCalibObject(calibList, 2, kTRUE,  0, isMc); 
+  //  AddCalibObject(calibList, 2, kFALSE, 0, isMc); 
+  
+  TTree* Tree = 0;
+  
+  if(strstr(dataFileName, ".dat")) {
+    
+    AliXRDPROOFtoolkit tool;
+    TChain* chain = tool.MakeChain(dataFileName,"tree", 0, 1000);
+    //    chain->Lookup();
+    Tree = chain;
+  } else {
+    TFile* dataFile = FindFileFresh(dataFileName);
+    if(!dataFile)
+      return;
+    
+    Tree = (TTree*)dataFile->Get("tree");
+  }
+
+  TClonesArray* trackArray = 0;
+  TClonesArray* mcTrackArray = 0;
+  DeDxEvent* event = 0;
+  Tree->SetBranchAddress("event", &event);
+  Tree->SetBranchAddress("trackGlobalPar"  , &trackArray);
+  if(isMc)
+    Tree->SetBranchAddress("trackMC"  , &mcTrackArray);
+
+  Int_t nEvents = Tree->GetEntries();
+  cout << "Number of events: " << nEvents << endl;
+  
+  if(maxEvents>0 && maxEvents < nEvents) {
+    
+    nEvents = maxEvents;
+    cout << "N events was reduced to: " << maxEvents << endl;
+  }
+
+  Int_t currentRun = 0;
+  Int_t nBad = 0;
+  TIter* iter = new TIter(calibList);
+  AliHighPtDeDxCalib* calib = 0;
+
+  for(Int_t step = startStep; step <= 3; step++) {
+    
+    iter->Reset();
+    while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+      
+      calib->SetStep(step);
+      // Here you can set the MIP interval
+      // default is 40-60
+      if(step==startStep) {
+       calib->SetDeDxMIPMin(25);
+       calib->SetDeDxMIPMax(55);
+      } else {
+       calib->SetDeDxMIPMin(40);
+       calib->SetDeDxMIPMax(60);
+      }
+      calib->Init(step, nPtBins, xBins);
+    }
+    
+    for(Int_t n = 0; n < nEvents; n++) {
+      
+      Tree->GetEntry(n);
+      
+      if((n+1)%1000000==0)
+       cout << "Event: " << n+1 << "/" << nEvents << endl;
+      
+      if(event->run == -1) {
+       nBad++;
+       continue;
+      }
+      // if(event->run == 126437)
+      //   continue;
+      
+      if(event->run != currentRun) {
+       
+       cout << "New run: " << event->run << endl;
+       currentRun = event->run;
+       
+       // Check if run objects exist
+       TObjString* runString = new TObjString(Form("%d", currentRun));
+       if(!runList->FindObject(runString->GetString().Data())) {
+         
+         runList->Add(runString);
+         
+         //        TList    filter, phi cut, run, isMc
+         AddCalibObject(calibList, 1, kTRUE,  currentRun, isMc); 
+         // AddCalibObject(calibList, 1, kFALSE, currentRun, isMc); 
+         // AddCalibObject(calibList, 2, kTRUE,  currentRun, isMc); 
+         // AddCalibObject(calibList, 2, kFALSE, currentRun, isMc); 
+         
+         // Is this really necessary?
+         delete iter;
+         iter = new TIter(calibList);
+
+         iter->Reset();
+         while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+           
+           calib->SetStep(step);
+           if(step==startStep) {
+             calib->SetDeDxMIPMin(25);
+             calib->SetDeDxMIPMax(55);
+           } else {
+             calib->SetDeDxMIPMin(40);
+             calib->SetDeDxMIPMax(60);
+           }
+           calib->Init(step, nPtBins, xBins);
+         }
+         
+       } else {
+
+         delete runString;
+       }
+      }
+      
+      // iterate over calib list
+      iter->Reset();
+      while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+       
+       // First we set the global properties
+       // If I want to use a narrower vtx I have here to redefine my 
+       // vtxstatus according to the new vtx range
+       calib->SetEventRun(event->run);
+       calib->SetEventMag(event->mag);
+       calib->SetEventVtxStatus(event->vtxstatus);
+       calib->SetEventTrigger(event->trig);
+       
+       if(!calib->EventAccepted()) // only checks for runs currently
+         continue;
+
+       calib->FillEventInfo();
+       
+       // The trig==1 is always true for real data, but not for MC data
+       if(!event->trig)
+         continue;
+       
+       if(event->vtxstatus<1) // only fill tracks for events with vtx inside cuts
+         continue;
+       
+       const Int_t nTracks = trackArray->GetEntries();
+       
+       for(Int_t i = 0; i < nTracks; i++) {
+         
+         DeDxTrack* track = (DeDxTrack*)trackArray->At(i);
+         
+         calib->SetTrackCharge(track->q);
+         calib->SetTrackP(track->p);
+         calib->SetTrackPt(track->pt);
+         Int_t filter = CalculateFilter(track);
+         calib->SetTrackFilter(filter);
+         calib->SetTrackPhi(track->phi);
+         calib->SetTrackDeDx(track->dedx);
+         calib->SetTrackNcl(track->ncl);
+         calib->SetTrackBeta(track->beta);
+         calib->SetTrackPidMc(track->pid);
+         calib->SetTrackEta(track->eta);
+         
+         if(calib->TrackAccepted()) {
+           // if(track->pt<2.0)
+           //   calib->FillTrackInfo(100.0);
+           // else
+             calib->FillTrackInfo(1.0);
+         }
+       }
+      }
+    }
+
+    if(step == 2) { // perform eta calibration
+
+      cout << "Starting Eta cal" << endl;
+      iter->Reset();
+      while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+       
+       calib->PerformEtaCal();
+      }
+      cout << "Finishing Eta cal" << endl;
+    } else if(step == 1) { // perform ncl calibration
+      
+
+      cout << "Starting Ncl cal" << endl;
+      iter->Reset();
+      while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+       
+       calib->PerformNclCal();
+      }
+      cout << "Finished Ncl cal" << endl;
+    }
+  }
+
+  cout << "Nbad (runno == -1) : " << nBad << endl;
+
+  dataOutFile->cd();
+  runList->Write("runList");
+  iter->Reset();
+  cout << "Writing calibration data" << endl;
+  while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+    
+    cout << "Writing calibration object " << calib->GetName() << endl;
+    calib->Write();
+  }
+  cout << "Finsihed writing calibration data" << endl;
+  dataOutFile->Close();
+  delete dataOutFile;
+  dataOutFile = 0;
+}
+
+//___________________________________________________________________________
+void AddCalibObject(TList* list, Int_t filter, Bool_t phiCut, Int_t run, 
+                   Bool_t analyzeMc, Bool_t etaCut, Bool_t etaAbs, 
+                   Int_t etaLow, Int_t etaHigh)
+{
+  if(etaCut && etaAbs) {
+
+    Fatal("AddCalibObject", "You cannot have a cut on both abs and signed eta");
+    return;
+  }
+  TString objectName("filter");
+  objectName += filter;
+  if(phiCut)
+    objectName += "phicut";
+  if(run) {
+    objectName += "_";
+    objectName += run;
+  }
+  if(etaCut) {
+    objectName += "eta";
+    objectName += etaLow;
+    objectName += etaHigh;
+  }
+  if(etaAbs) {
+    objectName += "etaabs";
+    objectName += etaLow;
+    objectName += etaHigh;
+  }
+
+  //  dataOutFile->cd();
+  AliHighPtDeDxCalib* data = new AliHighPtDeDxCalib(objectName.Data(), "Calib data");
+  if(run) {
+    data->SetUseRunCut(kTRUE);
+    data->SetRun(run);
+  }
+
+  list->Add(data);
+  data->SetIsMc(analyzeMc);
+  data->SetUseFilterCut(kTRUE);
+  data->SetFilter(filter);
+  data->SetUsePhiCut(phiCut);
+  if(phiCut) {
+    data->SetPhiCutLow(data->GetStandardPhiCutLow());
+    data->SetPhiCutHigh(data->GetStandardPhiCutHigh());
+  }
+  if(etaCut)
+    data->SetUseEtaCut(kTRUE);
+  if(etaAbs)
+    data->SetUseEtaCutAbs(kTRUE);
+  if(etaCut || etaAbs) {
+    data->SetEtaLow(Double_t(etaLow)/10.0);
+    data->SetEtaHigh(Double_t(etaHigh)/10.0);
+  }
+  if(run) {
+    data->SetUseRunCut(kTRUE);
+    data->SetRun(run);
+  }
+
+  data->Init(nPtBins, xBins);
+  data->Print();
+}
+
+//____________________________________________________________________________
+void CreateCalibV0(const Char_t* dataFileName, Bool_t isMc, 
+                  const Char_t* outFileName, Int_t maxEvents)
+{
+  CreateDir("no_calib_eta");
+  dataOutFile = new TFile(Form("no_calib_eta/%s", outFileName), "RECREATE");
+  
+  // Create output objects
+  dataOutFile->cd();
+  TList* runList = new TList();
+  runList->SetOwner(kTRUE);
+  runList->SetBit(TObject::kSingleKey);
+  
+  TList* calibList = new TList();
+  calibList->SetOwner(kFALSE);
+  
+  //        TList    filter, phi cut, run, isMc
+  AddCalibObjectV0(calibList, "lambda", kTRUE,  0, isMc); 
+  //  AddCalibObject(calibList, 1, kFALSE, 0, isMc); 
+  AddCalibObjectV0(calibList, "kaon", kTRUE,  0, isMc); 
+  //  AddCalibObject(calibList, 2, kFALSE, 0, isMc); 
+  
+  TTree* Tree = 0;
+  
+  if(strstr(dataFileName, ".dat")) {
+    
+    AliXRDPROOFtoolkit tool;
+    TChain* chain = tool.MakeChain(dataFileName,"tree", 0, 1000);
+    //    chain->Lookup();
+    Tree = chain;
+  } else {
+    TFile* dataFile = FindFileFresh(dataFileName);
+    if(!dataFile)
+      return;
+    
+    Tree = (TTree*)dataFile->Get("tree");
+  }
+  
+  TClonesArray* v0Array = 0;
+  DeDxEvent* event = 0;
+  Tree->SetBranchAddress("event", &event);
+  Tree->SetBranchAddress("v0"  , &v0Array);
+  
+  Int_t nEvents = Tree->GetEntries();
+  cout << "Number of events: " << nEvents << endl;
+  
+  if(maxEvents>0 && maxEvents < nEvents) {
+    
+    nEvents = maxEvents;
+    cout << "N events was reduced to: " << maxEvents << endl;
+  }
+  
+  Int_t currentRun = 0;
+  Int_t nBad = 0;
+  TIter* iter = new TIter(calibList);
+  AliHighPtDeDxCalib* calib = 0;
+  
+  iter->Reset();
+  while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+    
+    calib->SetStep(3);
+  }
+  
+  for(Int_t n = 0; n < nEvents; n++) {
+    
+    Tree->GetEntry(n);
+    
+    if((n+1)%1000000==0)
+      cout << "Event: " << n+1 << "/" << nEvents << endl;
+    
+    if(event->run == -1) {
+      nBad++;
+      continue;
+    }
+    // if(event->run == 126437)
+    //   continue;
+    
+    if(event->run != currentRun) {
+      
+      cout << "New run: " << event->run << endl;
+      currentRun = event->run;
+      
+      // Check if run objects exist
+      TObjString* runString = new TObjString(Form("%d", currentRun));
+      if(!runList->FindObject(runString->GetString().Data())) {
+       
+       runList->Add(runString);
+       
+       //        TList    filter, phi cut, run, isMc
+       AddCalibObjectV0(calibList, "lambda", kTRUE,  currentRun, isMc); 
+       AddCalibObjectV0(calibList, "kaon", kTRUE,  currentRun, isMc); 
+       
+       // Is this really necessary?
+       delete iter;
+       iter = new TIter(calibList);
+       
+       iter->Reset();
+       while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+         
+         calib->SetStep(3);
+       }
+       
+       } else {
+       
+       delete runString;
+      }
+    }
+    
+    // iterate over calib list
+    iter->Reset();
+    while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+      
+      // First we set the global properties
+      // If I want to use a narrower vtx I have here to redefine my 
+      // vtxstatus according to the new vtx range
+      calib->SetEventRun(event->run);
+      calib->SetEventMag(event->mag);
+      calib->SetEventVtxStatus(event->vtxstatus);
+      calib->SetEventTrigger(event->trig);
+      
+      if(!calib->EventAccepted()) // only checks for runs currently
+       continue;
+
+      calib->FillEventInfo();
+       
+      // The trig==1 is always true for real data, but not for MC data
+      if(!event->trig)
+       continue;
+      
+      if(event->vtxstatus<1) // only fill tracks for events with vtx inside cuts
+       continue;
+      
+      const Int_t nV0s = v0Array->GetEntries();
+      
+      for(Int_t i = 0; i < nV0s; i++) {
+       
+       DeDxV0* v0 = (DeDxV0*)v0Array->At(i);
+       
+       // if(v0->ptrack.filter != 2)
+       //   continue;
+
+       if(v0->status != 0)
+         continue;
+
+       if(v0->dmassG < 0.1)
+         continue;
+
+       // if(v0->decayr < 5.0)
+       //   continue;
+
+       // if(v0->decayr > 40.0)
+       //   continue;
+       
+       const Double_t dmassK  = TMath::Abs(v0->dmassK0);
+       const Double_t dmassL  = TMath::Abs(v0->dmassL);
+       const Double_t dmassAL = TMath::Abs(v0->dmassAL);
+       
+       Bool_t fillPos = kFALSE;
+       Bool_t fillNeg = kFALSE;
+                                          
+
+       if(strstr(calib->GetName(), "lambda")) {
+         
+         if(dmassK<0.01)
+           continue;
+
+         if(dmassL<0.01)
+           fillPos = kTRUE;
+
+         if(dmassAL<0.01)
+           fillNeg = kTRUE;
+       } else { // kaons
+
+         if(dmassL<0.01 || dmassAL<0.01)
+           continue;
+
+         if(dmassK<0.01) {
+           fillPos = kTRUE;
+           fillNeg = kTRUE;
+         }
+       }
+
+       for(Int_t j = 0; j < 2; j++) {
+
+         DeDxTrack* track = 0;
+         
+         if(j==0) {
+
+           if(fillNeg)
+             track = &(v0->ntrack);
+           else
+             continue;
+         } else {
+
+           if(fillPos)
+             track = &(v0->ptrack);
+           else
+             continue;
+         }
+         
+         calib->SetTrackCharge(track->q);
+         calib->SetTrackP(track->p);
+         calib->SetTrackPt(track->pt);
+         // NB! Filter is not used for these tracks!
+         calib->SetTrackFilter(track->filter);
+         calib->SetTrackPhi(track->phi);
+         calib->SetTrackDeDx(track->dedx);
+         calib->SetTrackNcl(track->ncl);
+         calib->SetTrackBeta(track->beta);
+         calib->SetTrackPidMc(track->pid);
+         calib->SetTrackEta(track->eta);
+         
+         if(calib->TrackAccepted()) {
+           calib->FillTrackInfo(1.0);
+         }
+       }
+      }
+    }
+  }
+  dataOutFile->cd();
+  runList->Write("runList");
+  iter->Reset();
+  while ((calib = dynamic_cast<AliHighPtDeDxCalib*> (iter->Next()))) {
+    
+    calib->Write();
+  }
+  dataOutFile->Close();
+  delete dataOutFile;
+  dataOutFile = 0;
+
+  cout << "Nbad (runno == -1) : " << nBad << endl;
+}
+
+//___________________________________________________________________________
+void AddCalibObjectV0(TList* list, const Char_t* baseName, Bool_t phiCut, 
+                     Int_t run, Bool_t analyzeMc)
+{
+  TString objectName(baseName);
+  if(phiCut)
+    objectName += "phicut";
+  if(run) {
+    objectName += "_";
+    objectName += run;
+  }
+  dataOutFile->cd();
+  AliHighPtDeDxCalib* data = new AliHighPtDeDxCalib(objectName.Data(), "Calib data");
+  if(run) {
+    data->SetUseRunCut(kTRUE);
+    data->SetRun(run);
+  }
+  
+  list->Add(data);
+  data->SetIsMc(analyzeMc);
+  data->SetUseFilterCut(kFALSE);
+  data->SetUsePhiCut(phiCut);
+  if(phiCut) {
+    data->SetPhiCutLow(data->GetStandardPhiCutLow());
+    data->SetPhiCutHigh(data->GetStandardPhiCutHigh());
+  }
+  data->Init(nPtBins, xBins);
+  data->Print();
+}
+
+//___________________________________________________________________________
+Int_t CalculateFilter(DeDxTrack* track)
+{
+  Int_t filter = 0;
+  if(track->filterset3)
+    filter += 1;
+  if(track->filterset2 && !track->filterset3)
+    filter += 2;
+  if(track->filterset1)
+    filter += 4;
+  return filter;
+}