TOF pi/K/p spectra code - Pb-Pb 2010 analysis
authorrpreghen <rpreghen@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Jan 2012 10:54:08 +0000 (10:54 +0000)
committerrpreghen <rpreghen@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 31 Jan 2012 10:54:08 +0000 (10:54 +0000)
53 files changed:
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.extended.root [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.root [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.137366.root [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.139507.root [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AddAnalysisTaskTOFSpectraPbPb.C [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisEvent.cxx [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisEvent.h [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisParticle.cxx [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisParticle.h [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTaskTOFSpectraPbPb.cxx [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTaskTOFSpectraPbPb.h [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTrack.cxx [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTrack.h [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/Makefile [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/SteerAnalysisTaskTOFSpectraPbPb.C [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/TOFSpectraPbPb.jdl [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/TOFSpectraPbPb.sh [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisEvent.cxx [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisEvent.h [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisParticle.cxx [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisParticle.h [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisTrack.cxx [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisTrack.h [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooFermiCutoff.cxx [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooFermiCutoff.h [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooGaussianTail.cxx [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooGaussianTail.h [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/DCA.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/FinalSpectra.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/HistoUtils.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MakeLibs.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MakeRooShapes.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MultCent.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/SystematicChecks.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFcalib.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFcalibMC.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFmatchEff.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFmatchMC.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFpid.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFsignal.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TPCTOFpid.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TPCcalib.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TrackingEff.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AddAnalysisTaskTOFSpectraPbPb.C [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisEvent.cxx [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisEvent.h [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisParticle.cxx [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisParticle.h [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisTaskTOFSpectraPbPb.cxx [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisTaskTOFSpectraPbPb.h [new file with mode: 0644]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisTrack.cxx [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/AliAnalysisTrack.h [new symlink]
PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/task/SteerAnalysisTaskTOFSpectraPbPb.C [new file with mode: 0644]

diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.extended.root b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.extended.root
new file mode 100644 (file)
index 0000000..4a131cd
Binary files /dev/null and b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.extended.root differ
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.root b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.root
new file mode 100644 (file)
index 0000000..ad0d569
Binary files /dev/null and b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/T0FillOnline.139465.root differ
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.137366.root b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.137366.root
new file mode 100644 (file)
index 0000000..36a120f
Binary files /dev/null and b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.137366.root differ
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.139507.root b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.139507.root
new file mode 100644 (file)
index 0000000..2fb6426
Binary files /dev/null and b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/data/enabledChannels.139507.root differ
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AddAnalysisTaskTOFSpectraPbPb.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AddAnalysisTaskTOFSpectraPbPb.C
new file mode 120000 (symlink)
index 0000000..6430e4b
--- /dev/null
@@ -0,0 +1 @@
+../task/AddAnalysisTaskTOFSpectraPbPb.C
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisEvent.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisEvent.cxx
new file mode 120000 (symlink)
index 0000000..416d46b
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisEvent.cxx
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisEvent.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisEvent.h
new file mode 120000 (symlink)
index 0000000..b07a687
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisEvent.h
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisParticle.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisParticle.cxx
new file mode 120000 (symlink)
index 0000000..0056cf0
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisParticle.cxx
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisParticle.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisParticle.h
new file mode 120000 (symlink)
index 0000000..5472649
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisParticle.h
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTaskTOFSpectraPbPb.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTaskTOFSpectraPbPb.cxx
new file mode 120000 (symlink)
index 0000000..6c70168
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisTaskTOFSpectraPbPb.cxx
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTaskTOFSpectraPbPb.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTaskTOFSpectraPbPb.h
new file mode 120000 (symlink)
index 0000000..610b44c
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisTaskTOFSpectraPbPb.h
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTrack.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTrack.cxx
new file mode 120000 (symlink)
index 0000000..1a32d19
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisTrack.cxx
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTrack.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/AliAnalysisTrack.h
new file mode 120000 (symlink)
index 0000000..e9a4560
--- /dev/null
@@ -0,0 +1 @@
+../task/AliAnalysisTrack.h
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/Makefile b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/Makefile
new file mode 100644 (file)
index 0000000..ebb5ec3
--- /dev/null
@@ -0,0 +1,37 @@
+TASK = TOFSpectraPbPb
+JDL = $(TASK).jdl
+EXE = $(TASK).sh
+TGZ = $(TASK).tgz
+DIR = /alice/cern.ch/user/r/rpreghen/$(TASK)
+SE = ALICE::CNAF::SE
+
+FILES = AliAnalysisTask$(TASK).h \
+       AliAnalysisTask$(TASK).cxx \
+       AliAnalysisEvent.h \
+       AliAnalysisEvent.cxx \
+       AliAnalysisTrack.h \
+       AliAnalysisTrack.cxx \
+       AliAnalysisParticle.h \
+       AliAnalysisParticle.cxx \
+       AddAnalysisTask$(TASK).C \
+       SteerAnalysisTask$(TASK).C
+
+all: $(TGZ)
+
+$(TGZ): $(FILES)
+       @echo "creating archive: "$(TGZ)
+       @tar zcvfh $(TGZ) $(FILES)
+
+install: $(TGZ)
+       @echo "installing archive: "$(TGZ)
+       @alien_cp -n $(TGZ) alien://$(DIR)/$(TGZ)@$(SE)
+       @echo "installing JDL: "$(JDL)
+       @alien_cp -n $(JDL) alien://$(DIR)/$(JDL)@$(SE)
+       @echo "installing executable: "$(EXE)
+       @alien_cp -n $(EXE) alien://$(DIR)/$(EXE)@$(SE)
+
+uninstall:
+       @alien_erase $(DIR)/$(TGZ)
+
+clean:
+       @rm -rf *~ $(TGZ)
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/SteerAnalysisTaskTOFSpectraPbPb.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/SteerAnalysisTaskTOFSpectraPbPb.C
new file mode 120000 (symlink)
index 0000000..8a04a82
--- /dev/null
@@ -0,0 +1 @@
+../task/SteerAnalysisTaskTOFSpectraPbPb.C
\ No newline at end of file
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/TOFSpectraPbPb.jdl b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/TOFSpectraPbPb.jdl
new file mode 100644 (file)
index 0000000..32dc128
--- /dev/null
@@ -0,0 +1,43 @@
+Executable = "/alice/cern.ch/user/r/rpreghen/bin/starter.sh";
+Validationcommand = "/alice/cern.ch/user/r/rpreghen/bin/validation.sh";
+Arguments = "bash TOFSpectraPbPb.sh $2";
+
+Requirements = ( other.Type == "machine" );
+
+Packages = {
+        "VO_ALICE@AliRoot::v5-02-16-AN",
+        "VO_ALICE@ROOT::v5-30-03-1",
+        "APISCONFIG::V1.1x"
+};
+
+JDLVariables = {
+        "Packages",
+        "OutputDir"
+};
+
+Type = "Job";
+User = "rpreghen";
+Jobtag = { "comment: TOFSpectraPbPb jdl" };
+TTL = 72000;
+Price = 1;
+Workdirectorysize = { "4000MB" };
+
+SplitMaxInputFileNumber = "250";
+Split = "se";
+
+InputDataListFormat = "xml-single";
+InputDataList = "wn.xml";
+InputDataCollection = {
+       "LF:$HOME/xml/$1.xml,nodownload"
+};
+
+InputFile = {
+       "LF:/alice/cern.ch/user/r/rpreghen/TOFSpectraPbPb/TOFSpectraPbPb.sh",
+       "LF:/alice/cern.ch/user/r/rpreghen/TOFSpectraPbPb/TOFSpectraPbPb.tgz"
+};
+
+OutputArchive = {
+       "log_archive.zip:wn.xml,stdout,stderr,*.log@disk=1",
+       "root_archive.zip:*.root@disk=1"
+};
+OutputDir = "$HOME/TOFSpectraPbPb/out/$1/#alien_counter_03i#";
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/TOFSpectraPbPb.sh b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/grid/TOFSpectraPbPb.sh
new file mode 100644 (file)
index 0000000..0e75c24
--- /dev/null
@@ -0,0 +1,17 @@
+#! /bin/bash
+
+tar zxvf TOFSpectraPbPb.tgz
+
+if [ "$1" == "data" ]; then
+    echo "*** Running analysis - Data ***"
+    aliroot -b -q "SteerAnalysisTaskTOFSpectraPbPb.C(\"wn.xml\", kFALSE, kFALSE, kTRUE)" 2>&1 | tee TOFSpectraPbPb.log
+elif [ "$1" == "mc" ]; then
+    echo "*** Running analysis - MC ***"
+    aliroot -b -q "SteerAnalysisTaskTOFSpectraPbPb.C(\"wn.xml\", kTRUE, kFALSE, kTRUE)" 2>&1 | tee TOFSpectraPbPb.log
+elif [ "$1" == "mctune" ]; then
+    echo "*** Running analysis - MCTune ***"
+    aliroot -b -q "SteerAnalysisTaskTOFSpectraPbPb.C(\"wn.xml\", kTRUE, kTRUE, kTRUE)" 2>&1 | tee TOFSpectraPbPb.log
+else
+    echo "*** Unkwnown analysis ***"
+    aliroot -b -q "SteerAnalysisTaskTOFSpectraPbPb.C(\"wn.xml\", kFALSE, kFALSE, kTRUE)" 2>&1 | tee TOFSpectraPbPb.log
+fi
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisEvent.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisEvent.cxx
new file mode 100644 (file)
index 0000000..46eef9d
--- /dev/null
@@ -0,0 +1,470 @@
+#include "AliAnalysisEvent.h"
+
+ClassImp(AliAnalysisEvent)
+
+//___________________________________________________________
+
+Bool_t AliAnalysisEvent::fgInitCorrections = kFALSE;
+
+const Char_t *AliAnalysisEvent::fgTimeZeroTOFCentCorrFormula = "[0]+[1]*x+[2]*x*x";
+
+Double_t AliAnalysisEvent::fgTimeZeroTOFCentCorrParams[3] = {
+  -14.9262, 0.0212941, 0.000960528
+};
+
+TF1 *AliAnalysisEvent::fgTimeZeroTOFCentCorrFunc = NULL;
+
+//___________________________________________________________
+
+AliTOFPIDResponse AliAnalysisEvent::fgTOFResponse;
+
+Float_t AliAnalysisEvent::fgVertexZ_cuts[2] = {-10., 10.}; /* min,max */
+Float_t AliAnalysisEvent::fgTimeZeroT0_AND_params[2] = {-4.75490e+01, 2.00476e+02}; /* mean,sigma */
+Float_t AliAnalysisEvent::fgTimeZeroT0_A_params[2] = {-9.61781e+00, 2.13385e+02}; /* mean,sigma */
+Float_t AliAnalysisEvent::fgTimeZeroT0_C_params[2] = {-8.44041e+01, 2.19459e+02}; /* mean,sigma */
+Float_t AliAnalysisEvent::fgTimeZeroT0_ACdiff_params[2] = {6.97001e+01, 6.65456e+01}; /* mean,sigma */
+Float_t AliAnalysisEvent::fgTimeZero_TOFT0diff_params[2] = {-3.41048e+01, 3.61210e+01}; /* mean,sigma */
+
+const Char_t *AliAnalysisEvent::fgkCentralityEstimatorName[AliAnalysisEvent::kNCentralityEstimators] = {
+  "V0M",
+  //  "FMD",
+  "TRK",
+  "TKL",
+  //  "CL0",
+  //  "CL1",
+  //  "V0MvsFMD",
+  //  "TKLvsV0M",
+  "ZEMvsZDC"
+};
+
+Float_t AliAnalysisEvent::fgTimeZeroSpread = 196.7;
+Float_t AliAnalysisEvent::fgTimeZeroT0_AND_sigma = 3.87264325235363032e+01;
+Float_t AliAnalysisEvent::fgTimeZeroT0_A_sigma = 8.27180042372880706e+01;
+Float_t AliAnalysisEvent::fgTimeZeroT0_C_sigma = 9.73209262235003933e+01;
+
+//___________________________________________________________
+
+AliAnalysisEvent::AliAnalysisEvent() :
+  TObject(),
+  fIsCollisionCandidate(kFALSE),
+  fHasVertex(kFALSE),
+  fVertexZ(0.),
+  fCentralityQuality(0),
+  fCentralityPercentile(),
+  fTimeZeroTOF(),
+  fTimeZeroTOFSigma(),
+  fTimeZeroT0(),
+  fMCTimeZero(0.)
+{
+  /*
+   * default constructor
+   */
+
+  /* init corrections */
+  if (!fgInitCorrections) {
+    
+    /*** TIME-ZERO TOF CENTRALITY CORRECTION ***/
+    fgTimeZeroTOFCentCorrFunc = new TF1("fTimeZeroTOFCentCorrFunc", fgTimeZeroTOFCentCorrFormula, 0., 100.);
+    for (Int_t iparam = 0; iparam < 3; iparam++)
+      fgTimeZeroTOFCentCorrFunc->SetParameter(iparam, fgTimeZeroTOFCentCorrParams[iparam]);
+    
+    /* set init flag */
+    fgInitCorrections = kTRUE;
+  }
+
+  /* reset */
+  Reset();
+}
+
+//___________________________________________________________
+
+AliAnalysisEvent::AliAnalysisEvent(const AliAnalysisEvent &source) :
+  TObject(source),
+  fIsCollisionCandidate(source.fIsCollisionCandidate),
+  fHasVertex(source.fHasVertex),
+  fVertexZ(source.fVertexZ),
+  fCentralityQuality(source.fCentralityQuality),
+  fCentralityPercentile(),
+  fTimeZeroTOF(),
+  fTimeZeroTOFSigma(),
+  fTimeZeroT0(),
+  fMCTimeZero(source.fMCTimeZero)
+{
+  /*
+   * copy constructor
+   */
+
+  for (Int_t i = 0; i < kNCentralityEstimators; i++)
+    fCentralityPercentile[i] = source.fCentralityPercentile[i];
+  for (Int_t i = 0; i < 10; i++) {
+    fTimeZeroTOF[i] = source.fTimeZeroTOF[i];
+    fTimeZeroTOFSigma[i] = source.fTimeZeroTOFSigma[i];
+  }
+  for (Int_t i = 0; i < 3; i++) 
+    fTimeZeroT0[i] = source.fTimeZeroT0[i];
+  
+}
+
+//___________________________________________________________
+
+AliAnalysisEvent &
+AliAnalysisEvent::operator=(const AliAnalysisEvent &source)
+{
+  /*
+   * operator=
+   */
+
+  if (&source == this) return *this;
+  TObject::operator=(source);
+
+  fIsCollisionCandidate = source.fIsCollisionCandidate;
+  fHasVertex = source.fHasVertex;
+  fVertexZ = source.fVertexZ;
+  fCentralityQuality = source.fCentralityQuality;
+  for (Int_t i = 0; i < kNCentralityEstimators; i++)
+    fCentralityPercentile[i] = source.fCentralityPercentile[i];
+  for (Int_t i = 0; i < 10; i++) {
+    fTimeZeroTOF[i] = source.fTimeZeroTOF[i];
+    fTimeZeroTOFSigma[i] = source.fTimeZeroTOFSigma[i];
+  }
+  for (Int_t i = 0; i < 3; i++) 
+    fTimeZeroT0[i] = source.fTimeZeroT0[i];
+  fMCTimeZero = source.fMCTimeZero;
+
+  return *this;
+}
+
+//___________________________________________________________
+
+AliAnalysisEvent::~AliAnalysisEvent()
+{
+  /*
+   * default destructor
+   */
+
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisEvent::Reset()
+{
+  /*
+   * reset
+   */
+
+  fIsCollisionCandidate = 0.;
+  fHasVertex = 0.;
+  fVertexZ = 0.;
+  fCentralityQuality = 0;
+  for (Int_t i = 0; i < kNCentralityEstimators; i++)
+    fCentralityPercentile[i] = 0.;
+  for (Int_t i = 0; i < 10; i++) {
+    fTimeZeroTOF[i] = 0.;
+    fTimeZeroTOFSigma[i] = 0.;
+  }
+  for (Int_t i = 0; i < 3; i++) 
+    fTimeZeroT0[i] = 0.;  
+  fMCTimeZero = 0.;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::CheckLimits(Float_t value, Float_t *params, Float_t nSigma) const
+{
+  /*
+   * check limits
+   */
+
+  Float_t min = params[0] - nSigma * params[1];
+  Float_t max = params[0] + nSigma * params[1];
+  if (value < min || value > max) return kFALSE;
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::AcceptVertex() const
+{
+  /*
+   * accept vertex
+   */
+
+  if (!HasVertex()) return kFALSE;
+  if (fVertexZ < fgVertexZ_cuts[0] || fVertexZ > fgVertexZ_cuts[1]) return kFALSE;
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::HasTimeZeroT0_AND() const
+{
+  /*
+   * has time-zero T0-AND
+   */
+
+  /* check T0-AND */
+  if (!CheckLimits(fTimeZeroT0[0], fgTimeZeroT0_AND_params)) return kFALSE;
+  /* check T0-A */
+  if (!CheckLimits(fTimeZeroT0[1], fgTimeZeroT0_A_params)) return kFALSE;
+  /* check T0-C */
+  if (!CheckLimits(fTimeZeroT0[2], fgTimeZeroT0_C_params)) return kFALSE;
+  /* check A-C difference */
+  if (!CheckLimits(fTimeZeroT0[1] - fTimeZeroT0[2], fgTimeZeroT0_ACdiff_params)) return kFALSE;
+  /* ok */
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::HasTimeZeroT0_XOR() const
+{
+  /*
+   * has time-zero T0-XOR
+   */
+
+  /* check T0-A only */
+  if (CheckLimits(fTimeZeroT0[1], fgTimeZeroT0_A_params) &&
+      !CheckLimits(fTimeZeroT0[2], fgTimeZeroT0_C_params)) return kTRUE;
+  /* check T0-C only */
+  if (!CheckLimits(fTimeZeroT0[1], fgTimeZeroT0_A_params) &&
+      CheckLimits(fTimeZeroT0[2], fgTimeZeroT0_C_params)) return kTRUE;
+  return kFALSE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::HasTimeZeroT0_OR() const
+{
+  /*
+   * has time-zero T0-OR
+   */
+
+  if (HasTimeZeroT0_AND() || HasTimeZeroT0_XOR()) return kTRUE;
+  return kFALSE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::HasTimeZeroTOF(Float_t momentum) const
+{
+  /*
+   * has time-zero TOF
+   */
+
+  Int_t momBin = fgTOFResponse.GetMomBin(momentum);
+  if (fTimeZeroTOF[momBin] == 0.) return kFALSE;
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::HasTimeZeroBest(Float_t momentum) const
+{
+  /*
+   * has time-zero best
+   */
+
+  if (HasTimeZeroT0_OR() || HasTimeZeroTOF(momentum)) return kTRUE;
+  return kFALSE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisEvent::HasTimeZeroSafe(Float_t momentum) const
+{
+  /*
+   * has time-zero safe
+   */
+
+  if (!HasTimeZeroT0_AND() || !HasTimeZeroTOF(momentum)) return kFALSE;
+  Float_t tzeroTOF = GetTimeZeroTOF(momentum);
+  Float_t tzeroT0 = GetTimeZeroT0_AND();
+  Float_t diff = tzeroTOF - tzeroT0;
+  if (!CheckLimits(diff, fgTimeZero_TOFT0diff_params)) return kFALSE;
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroT0_AND() const
+{
+  /*
+   * get time-zero T0-AND
+   */
+
+  return fTimeZeroT0[0] - fgTimeZeroT0_AND_params[0];
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroT0Sigma_AND() const
+{
+  /*
+   * get time-zero T0-AND sigma
+   */
+
+  return fgTimeZeroT0_AND_sigma;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroT0_XOR() const
+{
+  /*
+   * get time-zero T0-XOR
+   */
+  
+  if (CheckLimits(fTimeZeroT0[1], fgTimeZeroT0_A_params) &&
+      !CheckLimits(fTimeZeroT0[2], fgTimeZeroT0_C_params)) return fTimeZeroT0[1] - fgTimeZeroT0_A_params[0];
+  if (!CheckLimits(fTimeZeroT0[1], fgTimeZeroT0_A_params) &&
+      CheckLimits(fTimeZeroT0[2], fgTimeZeroT0_C_params)) return fTimeZeroT0[2] - fgTimeZeroT0_C_params[0];
+  return 0.;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroT0Sigma_XOR() const
+{
+  /*
+   * get time-zero T0-XOR sigma
+   */
+
+  if (CheckLimits(fTimeZeroT0[1], fgTimeZeroT0_A_params) &&
+      !CheckLimits(fTimeZeroT0[2], fgTimeZeroT0_C_params)) return fgTimeZeroT0_A_sigma;
+  if (!CheckLimits(fTimeZeroT0[1], fgTimeZeroT0_A_params) &&
+      CheckLimits(fTimeZeroT0[2], fgTimeZeroT0_C_params)) return fgTimeZeroT0_C_sigma;
+  return 0.;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroT0_OR() const
+{
+  /*
+   * get time-zero T0-OR
+   */
+  
+  if (HasTimeZeroT0_AND()) return GetTimeZeroT0_AND();
+  if (HasTimeZeroT0_XOR()) return GetTimeZeroT0_XOR();
+  return 0.;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroT0Sigma_OR() const
+{
+  /*
+   * get time-zero T0-OR sigma
+   */
+  
+  if (HasTimeZeroT0_AND()) return GetTimeZeroT0Sigma_AND();
+  if (HasTimeZeroT0_XOR()) return GetTimeZeroT0Sigma_XOR();
+  return 0.;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroTOF(Float_t momentum) const
+{
+  /*
+   * get time-zero TOF
+   */
+
+  Int_t momBin = fgTOFResponse.GetMomBin(momentum);
+  return fTimeZeroTOF[momBin];
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroTOFSigma(Float_t momentum) const
+{
+  /*
+   * get time-zero TOF sigma
+   */
+
+  Int_t momBin = fgTOFResponse.GetMomBin(momentum);
+  return fTimeZeroTOFSigma[momBin];
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroBest(Float_t momentum) const
+{
+  /*
+   * get time-zero best
+   */
+
+  if (HasTimeZeroTOF(momentum)) return GetTimeZeroTOF(momentum);
+  if (HasTimeZeroT0_OR()) return GetTimeZeroT0_OR();
+  return 0.;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroBestSigma(Float_t momentum) const
+{
+  /*
+   * get time-zero best sigma
+   */
+
+  if (HasTimeZeroTOF(momentum)) return GetTimeZeroTOFSigma(momentum);
+  if (HasTimeZeroT0_OR()) return GetTimeZeroT0Sigma_OR();
+  return fgTimeZeroSpread;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroSafe(Float_t momentum) const
+{
+  /*
+   * get time-zero safe
+   */
+
+  return GetTimeZeroTOF(momentum);
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisEvent::GetTimeZeroSafeSigma(Float_t momentum) const
+{
+  /*
+   * get time-zero safe sigma
+   */
+
+  return GetTimeZeroTOFSigma(momentum);
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisEvent::ApplyTimeZeroTOFCorrection()
+{
+  /*
+   * apply timezero TOF correction
+   */
+
+  for (Int_t imom = 0; imom < 10; imom++)
+    fTimeZeroTOF[imom] += GetTimeZeroTOFCorrection();
+  
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisEvent.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisEvent.h
new file mode 100644 (file)
index 0000000..7342412
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef ALIANALYSISEVENT_H
+#define ALIANALYSISEVENT_H
+
+#include "TObject.h"
+#include "AliTOFPIDResponse.h"
+#include "TF1.h"
+
+class AliAnalysisEvent :
+public TObject
+{
+
+ public:
+
+  AliAnalysisEvent(); // default constructor
+  AliAnalysisEvent(const AliAnalysisEvent &source); // copy constructor
+  AliAnalysisEvent &operator=(const AliAnalysisEvent &source); // operator=
+  virtual ~AliAnalysisEvent(); // default destructor
+
+  Bool_t IsCollisionCandidate() const {return fIsCollisionCandidate;}; // getter
+  Bool_t HasVertex() const {return fHasVertex;}; // getter
+  Float_t GetVertexZ() const {return fVertexZ;}; // getter
+  UChar_t GetCentralityQuality() const {return fCentralityQuality;}; // getter
+  Float_t GetCentralityPercentile(Int_t i) const {return i < kNCentralityEstimators ? fCentralityPercentile[i] : -1;}; // getter
+  Float_t *GetTimeZeroTOF() {return fTimeZeroTOF;}; // getter
+  Float_t *GetTimeZeroTOFSigma() {return fTimeZeroTOFSigma;}; // getter
+  Float_t *GetTimeZeroT0() {return fTimeZeroT0;}; // getter
+  Float_t GetTimeZeroTOF(Int_t i) {return i < 10 ? fTimeZeroTOF[i] : 0.;}; // getter
+  Float_t GetTimeZeroTOFSigma(Int_t i) {return i < 10 ? fTimeZeroTOFSigma[i] : 0.;}; // getter
+  Float_t GetTimeZeroT0(Int_t i) {return i < 3 ? fTimeZeroT0[i] : 0.;}; // getter
+  Float_t GetMCTimeZero() const {return fMCTimeZero;}; // getter
+
+  void SetIsCollisionCandidate(Bool_t value) {fIsCollisionCandidate = value;}; // setter
+  void SetHasVertex(Bool_t value) {fHasVertex = value;}; // setter
+  void SetVertexZ(Float_t value) {fVertexZ = value;}; // setter
+  void SetCentralityQuality(UChar_t value) {fCentralityQuality = value;}; // setter
+  void SetCentralityPercentile(Int_t icent, Float_t value) {if (icent < kNCentralityEstimators) fCentralityPercentile[icent] = value;}; // setter
+  void SetTimeZeroTOF(Int_t i, Float_t value) {fTimeZeroTOF[i] = value;}; // setter
+  void SetTimeZeroTOFSigma(Int_t i, Float_t value) {fTimeZeroTOFSigma[i] = value;}; // setter
+  void SetTimeZeroT0(Int_t i, Float_t value) {fTimeZeroT0[i] = value;}; // setter
+  void SetMCTimeZero(Float_t value) {fMCTimeZero = value;}; // setter
+  
+  void Reset(); // reset
+  Bool_t CheckLimits(Float_t value, Float_t *params, Float_t nSigma = 3.) const; // check limits
+
+  Bool_t AcceptVertex() const; // accept vertex
+  Bool_t HasTimeZeroT0_AND() const; // has time-zero T0-AND
+  Bool_t HasTimeZeroT0_XOR() const; // has time-zero T0-XOR
+  Bool_t HasTimeZeroT0_OR() const; // has time-zero T0-OR
+  Bool_t HasTimeZeroTOF(Float_t momentum) const; // has time-zero TOF
+  Bool_t HasTimeZeroBest(Float_t momentum) const; // has time-zero TOF
+  Bool_t HasTimeZeroSafe(Float_t momentum) const; // has time-zero safe
+
+  Float_t GetTimeZeroT0_AND() const; // get time-zero T0-AND
+  Float_t GetTimeZeroT0_XOR() const; // get time-zero T0-XOR
+  Float_t GetTimeZeroT0_OR() const; // get time-zero T0-OR
+  Float_t GetTimeZeroTOF(Float_t momentum) const; // get time-zero TOF
+  Float_t GetTimeZeroBest(Float_t momentum) const; // get time-zero best
+  Float_t GetTimeZeroSafe(Float_t momentum) const; // get time-zero safe
+
+  Float_t GetTimeZeroT0Sigma_AND() const; // get time-zero T0-AND sigma
+  Float_t GetTimeZeroT0Sigma_XOR() const; // get time-zero T0-XOR sigma
+  Float_t GetTimeZeroT0Sigma_OR() const; // get time-zero T0-OR sigma
+  Float_t GetTimeZeroTOFSigma(Float_t momentum) const; // get time-zero TOF sigma
+  Float_t GetTimeZeroBestSigma(Float_t momentum) const; // get time-zero best sigma
+  Float_t GetTimeZeroSafeSigma(Float_t momentum) const; // get time-zero safe sigma
+
+  enum ECentralityEstimator_t {
+    kCentEst_V0M, /* V0 multiplicity */
+    //    kCentEst_FMD, /* FMD raw multiplicity */
+    kCentEst_TRK, /* N. of tracks */
+    kCentEst_TKL, /* N. of tracklets */
+    //    kCentEst_CL0, /* N. of clusters in layer 0 */
+    //    kCentEst_CL1, /*  N. of clusters in layer 1 */
+    //    kCentEst_V0MvsFMD, /* correlation between V0 and FMD */
+    //    kCentEst_TKLvsV0M, /* correlation between tracklets and V0 */
+    kCentEst_ZEMvsZDC, /* correlation between ZEM and ZDC */
+    kNCentralityEstimators
+  };
+  static const Char_t *fgkCentralityEstimatorName[kNCentralityEstimators]; // centrality estimator name
+
+  static void SetVertexZCuts(Float_t min, Float_t max) {fgVertexZ_cuts[0] = min; fgVertexZ_cuts[1] = max;}; // setter
+
+  void ApplyTimeZeroTOFCorrection();
+  Double_t GetTimeZeroTOFCorrection() {return fgTimeZeroTOFCentCorrFunc->Eval(fCentralityPercentile[kCentEst_V0M]);};
+
+ private:
+
+  /*** global event info ***/
+  Bool_t fIsCollisionCandidate; // is collision candidate
+  Bool_t fHasVertex; // has vertex
+  Float_t fVertexZ; // vertex z
+  UChar_t fCentralityQuality; // centrality quality
+  Float_t fCentralityPercentile[kNCentralityEstimators]; // centrality percentile
+  /*** TPC event info ***/
+  /*** TOF event info ***/
+  Float_t fTimeZeroTOF[10]; // time-zero TOF
+  Float_t fTimeZeroTOFSigma[10]; // time-zero TOF sigma
+  /*** T0 event info ***/
+  Float_t fTimeZeroT0[3]; // time-zero T0
+  /*** MC info ***/
+  Float_t fMCTimeZero; // MC time-zero
+
+  /*** tools ***/
+  static AliTOFPIDResponse fgTOFResponse; // TOF PID response
+
+  /*** cuts ***/
+  static Float_t fgVertexZ_cuts[2]; // min,max
+  static Float_t fgTimeZeroT0_AND_params[2]; // mean,sigma
+  static Float_t fgTimeZeroT0_A_params[2];
+  static Float_t fgTimeZeroT0_C_params[2];
+  static Float_t fgTimeZeroT0_ACdiff_params[2];
+  static Float_t fgTimeZero_TOFT0diff_params[2];
+
+  /*** other ***/
+  static Float_t fgTimeZeroSpread;
+  static Float_t fgTimeZeroT0_AND_sigma;
+  static Float_t fgTimeZeroT0_A_sigma;
+  static Float_t fgTimeZeroT0_C_sigma;
+
+  /*** corrections ***/
+  static Bool_t fgInitCorrections;
+  static const Char_t *fgTimeZeroTOFCentCorrFormula;
+  static Double_t fgTimeZeroTOFCentCorrParams[3];
+  static TF1 *fgTimeZeroTOFCentCorrFunc;
+
+  ClassDef(AliAnalysisEvent, 3);
+};
+
+#endif /* ALIANALYSISEVENT_H */
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisParticle.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisParticle.cxx
new file mode 100644 (file)
index 0000000..ce7e99b
--- /dev/null
@@ -0,0 +1,160 @@
+#include "AliAnalysisParticle.h"
+#include "TParticle.h"
+#include "AliPID.h"
+#include "TDatabasePDG.h"
+#include "TParticlePDG.h"
+#include "TMath.h"
+
+ClassImp(AliAnalysisParticle)
+
+//___________________________________________________________
+
+TLorentzVector AliAnalysisParticle::fgLorentzVector;
+
+//___________________________________________________________
+
+Double_t
+AliAnalysisParticle::GetY() const
+{
+  
+  fgLorentzVector.SetPtEtaPhiM(fPt, fEta, fPhi, GetMass());
+  return fgLorentzVector.Rapidity();
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisParticle::GetSign() const
+{
+  
+  TDatabasePDG *dbpdg = TDatabasePDG::Instance();
+  TParticlePDG *ppdg = dbpdg->GetParticle(fPdgCode);
+  if (!ppdg)
+    return 0.;
+  return TMath::Sign(1., ppdg->Charge());
+}
+
+//___________________________________________________________
+
+Int_t
+AliAnalysisParticle::GetPID() const
+{
+  /*
+   * get PID
+   */
+
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+    if (TMath::Abs(fPdgCode) == AliPID::ParticleCode(ipart))
+      return ipart;
+  return -1;
+
+}
+
+//___________________________________________________________
+
+Double_t
+AliAnalysisParticle::GetMass() const
+{
+  /*
+   * get mass
+   */
+  
+  if (GetPID() == -1)
+    return 0.;
+  return AliPID::ParticleMass(GetPID());
+}
+
+//___________________________________________________________
+
+AliAnalysisParticle::AliAnalysisParticle() :
+  TObject(),
+  fLabel(0),
+  fPt(0.),
+  fEta(0.),
+  fPhi(0.),
+  fPdgCode(0)
+{
+  /*
+   * default constructor
+   */
+}
+
+//___________________________________________________________
+
+AliAnalysisParticle::AliAnalysisParticle(const AliAnalysisParticle &source) :
+  TObject(source),
+  fLabel(source.fLabel),
+  fPt(source.fPt),
+  fEta(source.fEta),
+  fPhi(source.fPhi),
+  fPdgCode(source.fPdgCode)
+{
+  /*
+   * copy constructor
+   */
+}
+
+//___________________________________________________________
+
+AliAnalysisParticle &
+AliAnalysisParticle::operator=(const AliAnalysisParticle &source)
+{
+  /*
+   * operator=
+   */
+
+  if (&source == this) return *this;
+  TObject::operator=(source);
+
+  fLabel = source.fLabel;
+  fPt = source.fPt;
+  fEta = source.fEta;
+  fPhi = source.fPhi;
+  fPdgCode = source.fPdgCode;
+
+  return *this;
+}
+
+//___________________________________________________________
+
+AliAnalysisParticle::~AliAnalysisParticle()
+{
+  /*
+   * default destructor
+   */
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisParticle::Reset()
+{
+  /*
+   * reset
+   */
+
+  fLabel = 0;
+  fPt = 0.;
+  fEta = 0.;
+  fPhi = 0.;
+  fPdgCode = 0;
+  
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisParticle::Update(TParticle *particle, Int_t label)
+{
+  /*
+   * update
+   */
+
+  fLabel = label;
+  fPt = particle->Pt();
+  fEta = particle->Eta();
+  fPhi = particle->Phi();
+  fPdgCode = particle->GetPdgCode();
+  
+}
+
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisParticle.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisParticle.h
new file mode 100644 (file)
index 0000000..5b02587
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef ALIANALYSISPARTICLE_H
+#define ALIANALYSISPARTICLE_H
+
+#include "TObject.h"
+#include "TLorentzVector.h"
+
+class TParticle;
+
+class AliAnalysisParticle :
+public TObject
+{
+
+ public:
+
+  AliAnalysisParticle(); // default constructor
+  AliAnalysisParticle(const AliAnalysisParticle &source); // copy constructor
+  AliAnalysisParticle &operator=(const AliAnalysisParticle &source); // operator=
+  virtual ~AliAnalysisParticle(); // default destructor
+
+  Int_t GetLabel() const {return fLabel;} // get label
+  Float_t GetPt() const {return fPt;}; // get pt
+  Float_t GetEta() const {return fEta;}; // get eta
+  Float_t GetPhi() const {return fPhi;}; // get phi
+  Int_t GetPdgCode() const {return fPdgCode;}; // get PDG code
+
+  Double_t GetY() const; // get Y
+  Float_t GetSign() const; // get sign
+  Int_t GetPID() const; // get MC PID
+  Double_t GetMass() const; // get mass
+
+  void Reset(); // reset
+  void Update(TParticle *particle, Int_t label); // update
+  
+ private:
+
+  Int_t fLabel; // label
+  Float_t fPt; // pt
+  Float_t fEta; // eta
+  Float_t fPhi; // phi
+  Int_t fPdgCode; // PDG code
+
+  /*** tools ***/
+  static TLorentzVector fgLorentzVector;
+
+  ClassDef(AliAnalysisParticle, 1);
+};
+
+#endif /* ALIANALYSISPARTICLE_H */
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisTrack.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisTrack.cxx
new file mode 100644 (file)
index 0000000..5a94d4a
--- /dev/null
@@ -0,0 +1,965 @@
+#include "AliAnalysisTrack.h"
+#include "AliAnalysisEvent.h"
+#include "AliStack.h"
+#include "AliTrackReference.h"
+#include "AliMCEvent.h"
+#include "TParticle.h"
+#include "TDatabasePDG.h"
+#include "TParticlePDG.h"
+#include "TFile.h"
+#include "TH2F.h"
+#include "TF1.h"
+#include "TMath.h"
+
+ClassImp(AliAnalysisTrack)
+
+//___________________________________________________________
+
+Float_t AliAnalysisTrack::fgEtaCut = 0.8;
+Float_t AliAnalysisTrack::fgEtaReject = 0.;
+TFormula *AliAnalysisTrack::fgMaxDCAToVertexXYPtDepFormula = new TFormula("f1MaxDCAToVertexXYPtDepFormula", "0.0182+0.0350/x^1.01");
+UShort_t AliAnalysisTrack::fgMinNClustersTPC = 70;
+UShort_t AliAnalysisTrack::fgMinNCrossedRowsTPC = 70;
+Float_t AliAnalysisTrack::fgMinRatioCrossedRowsOverFindableClustersTPC = 0.8;
+Int_t AliAnalysisTrack::fgAcceptTrackClusterCut = 0;
+ULong_t AliAnalysisTrack::fgAcceptTrackStatusCut = 0;
+ULong_t AliAnalysisTrack::fgRejectTrackStatusCut = 0;
+Float_t AliAnalysisTrack::fgMaxDCAToVertexZCut = 2.;
+Float_t AliAnalysisTrack::fgMaxChi2PerClusterTPC = 4.;
+Bool_t AliAnalysisTrack::fgRejectITSFakes = kFALSE;
+
+//___________________________________________________________
+
+TLorentzVector AliAnalysisTrack::fgLorentzVector;
+AliTOFGeometry AliAnalysisTrack::fgTOFGeometry;
+AliTOFcalibHisto AliAnalysisTrack::fgTOFcalibHisto;
+Bool_t AliAnalysisTrack::fgTOFcalibHistoFlag = kFALSE;
+AliTPCPIDResponse *AliAnalysisTrack::fgTPCResponse = NULL;
+AliTOFPIDResponse *AliAnalysisTrack::fgTOFResponse = NULL;
+TH2F *AliAnalysisTrack::hTOFtuned_th[AliPID::kSPECIES] = {
+  NULL, NULL, NULL, NULL, NULL
+};
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisTrack::GetY(Float_t mass) const
+{
+  
+  fgLorentzVector.SetPtEtaPhiM(fPt, fEta, fPhi, mass);
+  return fgLorentzVector.Rapidity();
+}
+
+//___________________________________________________________
+
+AliAnalysisTrack::AliAnalysisTrack() :
+  TObject(),
+  fP(),
+  fPt(),
+  fEta(),
+  fPhi(),
+  fSign(0.),
+  fStatus(0x0),
+  fLabel(0),
+  fImpactParameter(),
+  fImpactParameterCov(),
+  fTPCmomentum(0.),
+  fTPCdEdx(0.),
+  fTPCdEdxN(0),
+  fTPCNcls(0),
+  fTPCNclsF(0),
+  fTPCNcr(0.),
+  fTOFIndex(0),
+  fTOFTime(0.),
+  fTOFExpTime(),
+  fTOFLength(0.),
+  fTOFDeltaX(0.),
+  fTOFDeltaZ(0.),
+  fTOFLabel(),
+  fMCPrimary(kFALSE),
+  fMCPdgCode(0),
+  fMCMotherPrimary(kFALSE),
+  fMCMotherPdgCode(0),
+  fMCTOFMatchPrimary(kFALSE),
+  fMCTOFMatchPdgCode(0),
+  fMCTOFMatchLevel(-1),
+  fMCTOFTime(0.),
+  fMCTOFLength(0.),
+  fMCSecondaryWeak(kFALSE),
+  fMCSecondaryMaterial(kFALSE),
+  fHMPIDmomentum(0.),
+  fHMPIDsignal(0.),
+  fTPCchi2(0.),
+  fITSFakeFlag(kFALSE),
+  fTimeZeroSigma(0.)
+{
+  /*
+   * default constructor
+   */
+
+  /* load calib histo */
+  if (!fgTOFcalibHistoFlag) {
+    fgTOFcalibHisto.LoadCalibHisto();
+    fgTOFcalibHistoFlag = kTRUE;
+  }
+
+  Double_t bbParam[6] = { /* R+ fit on minimum-bias PbPb (run 138275, pass2) */
+    5.22879e+01,
+    2.80863e-02,
+    2.58364e+01,
+    5.15102e-07,
+    2.42169e+00,
+    5.38930e+00
+  };
+  
+  if (!fgTPCResponse) {
+    fgTPCResponse = new AliTPCPIDResponse();
+    fgTPCResponse->SetMip(bbParam[0]);
+    fgTPCResponse->SetBetheBlochParameters(bbParam[1], bbParam[2], bbParam[3], bbParam[4], bbParam[5]);
+  }
+
+  /* reset */
+  Reset();
+}
+
+//___________________________________________________________
+
+AliAnalysisTrack::AliAnalysisTrack(const AliAnalysisTrack &source) :
+  TObject(source),
+  fP(source.fP),
+  fPt(source.fPt),
+  fEta(source.fEta),
+  fPhi(source.fPhi),
+  fSign(source.fSign),
+  fStatus(source.fStatus),
+  fLabel(source.fLabel),
+  fImpactParameter(),
+  fImpactParameterCov(),
+  fTPCmomentum(source.fTPCmomentum),
+  fTPCdEdx(source.fTPCdEdx),
+  fTPCdEdxN(source.fTPCdEdxN),
+  fTPCNcls(source.fTPCNcls),
+  fTPCNclsF(source.fTPCNclsF),
+  fTPCNcr(source.fTPCNcr),  
+  fTOFIndex(source.fTOFIndex),
+  fTOFTime(source.fTOFTime),
+  fTOFExpTime(),
+  fTOFLength(source.fTOFLength),
+  fTOFDeltaX(source.fTOFDeltaX),
+  fTOFDeltaZ(source.fTOFDeltaZ),
+  fTOFLabel(),
+  fMCPrimary(source.fMCPrimary),
+  fMCPdgCode(source.fMCPdgCode),
+  fMCMotherPrimary(source.fMCMotherPrimary),
+  fMCMotherPdgCode(source.fMCMotherPdgCode),
+  fMCTOFMatchPrimary(source.fMCTOFMatchPrimary),
+  fMCTOFMatchPdgCode(source.fMCTOFMatchPdgCode),
+  fMCTOFMatchLevel(source.fMCTOFMatchLevel),
+  fMCTOFTime(source.fMCTOFTime),
+  fMCTOFLength(source.fMCTOFLength),
+  fMCSecondaryWeak(source.fMCSecondaryWeak),
+  fMCSecondaryMaterial(source.fMCSecondaryMaterial),
+  fHMPIDmomentum(source.fHMPIDmomentum),
+  fHMPIDsignal(source.fHMPIDsignal),
+  fTPCchi2(source.fTPCchi2),
+  fITSFakeFlag(source.fITSFakeFlag),
+  fTimeZeroSigma(source.fTimeZeroSigma)
+{
+  /*
+   * copy constructor
+   */
+
+  for (Int_t i = 0; i < 2; i++) fImpactParameter[i] = source.fImpactParameter[i];
+  for (Int_t i = 0; i < 3; i++) fImpactParameterCov[i] = source.fImpactParameterCov[i];
+  for (Int_t i = 0; i < 5; i++) fTOFExpTime[i] = source.fTOFExpTime[i];
+  for (Int_t i = 0; i < 3; i++) fTOFLabel[i] = source.fTOFLabel[i];
+
+}
+
+//___________________________________________________________
+
+AliAnalysisTrack &
+AliAnalysisTrack::operator=(const AliAnalysisTrack &source)
+{
+  /*
+   * operator=
+   */
+
+  if (&source == this) return *this;
+  TObject::operator=(source);
+
+  fP = source.fP;
+  fPt = source.fPt;
+  fEta = source.fEta;
+  fPhi = source.fPhi;
+  fSign = source.fSign;
+  fStatus = source.fStatus;
+  fLabel = source.fLabel;
+  for (Int_t i = 0; i < 2; i++) fImpactParameter[i] = source.fImpactParameter[i];
+  for (Int_t i = 0; i < 3; i++) fImpactParameterCov[i] = source.fImpactParameterCov[i];
+  fTPCmomentum = source.fTPCmomentum;
+  fTPCdEdx = source.fTPCdEdx;
+  fTPCdEdxN = source.fTPCdEdxN;
+  fTPCNcls = source.fTPCNcls;
+  fTPCNclsF = source.fTPCNclsF;
+  fTPCNcr = source.fTPCNcr;
+  fTOFIndex = source.fTOFIndex;
+  fTOFTime = source.fTOFTime;
+  for (Int_t i = 0; i < 5; i++) fTOFExpTime[i] = source.fTOFExpTime[i];
+  fTOFLength = source.fTOFLength;
+  fTOFDeltaX = source.fTOFDeltaX;
+  fTOFDeltaZ = source.fTOFDeltaZ;
+  for (Int_t i = 0; i < 3; i++) fTOFLabel[i] = source.fTOFLabel[i];
+  fMCPrimary = source.fMCPrimary;
+  fMCPdgCode = source.fMCPdgCode;
+  fMCMotherPrimary = source.fMCMotherPrimary;
+  fMCMotherPdgCode = source.fMCMotherPdgCode;
+  fMCTOFMatchPrimary = source.fMCTOFMatchPrimary;
+  fMCTOFMatchPdgCode = source.fMCTOFMatchPdgCode;
+  fMCTOFMatchLevel = source.fMCTOFMatchLevel;
+  fMCTOFTime = source.fMCTOFTime;
+  fMCTOFLength = source.fMCTOFLength;
+  fMCSecondaryWeak = source.fMCSecondaryWeak;
+  fMCSecondaryMaterial = source.fMCSecondaryMaterial;
+  fHMPIDmomentum = source.fHMPIDmomentum;
+  fHMPIDsignal = source.fHMPIDsignal;
+  fTPCchi2 = source.fTPCchi2;
+  fITSFakeFlag = source.fITSFakeFlag;
+  fTimeZeroSigma = source.fTimeZeroSigma;
+
+  return *this;
+}
+
+//___________________________________________________________
+
+AliAnalysisTrack::~AliAnalysisTrack()
+{
+  /*
+   * default destructor
+   */
+
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisTrack::Reset()
+{
+  /*
+   * reset
+   */
+
+  fP = 0.;
+  fPt = 0.;
+  fEta = 0.;
+  fPhi = 0.;
+  fSign = 0.;
+  fStatus = 0;
+  fLabel = 0;
+  for (Int_t i = 0; i < 2; i++) fImpactParameter[i] = 0.;
+  for (Int_t i = 0; i < 3; i++) fImpactParameterCov[i] = 0.;
+  fTPCmomentum = 0.;
+  fTPCdEdx = 0.;
+  fTPCdEdxN = 0;
+  fTPCNcls = 0;
+  fTPCNclsF = 0;
+  fTPCNcr = 0.;
+  fTOFIndex = 0;
+  fTOFTime = 0.;
+  for (Int_t i = 0; i < 5; i++) fTOFExpTime[i] = 0.;
+  fTOFLength = 0.;
+  fTOFDeltaX = 0.;
+  fTOFDeltaZ = 0.;
+  for (Int_t i = 0; i < 3; i++) fTOFLabel[i] = 0;
+  fMCPrimary = kFALSE;
+  fMCPdgCode = 0;
+  fMCMotherPrimary = kFALSE;
+  fMCMotherPdgCode = 0;
+  fMCTOFMatchPrimary = kFALSE;
+  fMCTOFMatchPdgCode = 0;
+  fMCTOFMatchLevel = -1;
+  fMCTOFTime = 0.;
+  fMCTOFLength = 0.;
+  fMCSecondaryWeak = 0.;
+  fMCSecondaryMaterial = 0.;
+  fHMPIDmomentum = 0.;
+  fHMPIDsignal = 0.;
+  fTPCchi2 = 0.;
+  fITSFakeFlag = kFALSE;
+  fTimeZeroSigma = 0.;
+  
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisTrack::Update(AliESDtrack *track, AliStack *stack, AliMCEvent *mcevent)
+{
+  /*
+   * update
+   */
+
+  fP = track->P();
+  fPt = track->Pt();
+  fEta = track->Eta();
+  fPhi = track->Phi();
+  fSign = track->GetSign();
+  fStatus = track->GetStatus();
+  fLabel = track->GetLabel();
+  track->GetImpactParameters(fImpactParameter, fImpactParameterCov);
+  fTPCmomentum = track->GetInnerParam() ? track->GetInnerParam()->P() : 0.;
+  fTPCdEdx = track->GetTPCsignal();
+  fTPCdEdxN = track->GetTPCsignalN();
+  fTPCNcls = track->GetTPCNcls();
+  fTPCNclsF = track->GetTPCNclsF();
+  fTPCNcr = track->GetTPCClusterInfo(2,1);
+  fTPCchi2 = track->GetTPCchi2();
+  fITSFakeFlag = track->GetITSFakeFlag();
+  fTOFIndex = track->GetTOFCalChannel();
+  fTOFTime = track->GetTOFsignal();
+  Double_t timei[5];
+  track->GetIntegratedTimes(timei);
+  for (Int_t i = 0; i < 5; i++) fTOFExpTime[i] = timei[i];
+  fTOFLength = track->GetIntegratedLength();
+  fTOFDeltaX = track->GetTOFsignalDx();
+  fTOFDeltaZ = track->GetTOFsignalDz();
+  track->GetTOFLabel(fTOFLabel);
+  fHMPIDmomentum = track->GetOuterHmpParam() ? track->GetOuterHmpParam()->P() : 0.;
+  /* HMPID signal with cuts */
+  Float_t xPc=0., yPc=0., xMip=0., yMip=0., thetaTrk=0., phiTrk=0.;
+  Int_t nPhot=0, qMip=0;
+  track->GetHMPIDtrk(xPc,yPc,thetaTrk,phiTrk);
+  track->GetHMPIDmip(xMip,yMip,qMip,nPhot);
+  Float_t dist = TMath::Sqrt((xPc-xMip)*(xPc-xMip) + (yPc-yMip)*(yPc-yMip));    
+  if (dist < 0.7 && nPhot < 30 && qMip > 100)
+    fHMPIDsignal = track->GetHMPIDsignal();
+  else
+    fHMPIDsignal = 0.;
+  /* info from track references */
+  fMCTOFTime = 0.;
+  fMCTOFLength = 0.;
+  if (mcevent && fTOFLabel[0] > 0) {
+    TParticle *particle;
+    TClonesArray *arrayTR;
+    AliTrackReference *trackRef;
+    mcevent->GetParticleAndTR(fTOFLabel[0], particle, arrayTR);
+    for (Int_t itr = 0; itr < arrayTR->GetEntries(); itr++) {
+      trackRef = (AliTrackReference *)arrayTR->At(itr);
+      if (!trackRef || trackRef->DetectorId() != AliTrackReference::kTOF) continue;
+      fMCTOFTime = trackRef->GetTime() * 1.e12; /* s -> ps */
+      fMCTOFLength = trackRef->GetLength();
+      /* break as soon as we get it */
+      break;
+    }
+  }
+  /* info from stack */
+  fMCPrimary = kFALSE;
+  fMCPdgCode = 0;
+  fMCMotherPrimary = kFALSE;
+  fMCMotherPdgCode = 0;
+  fMCSecondaryWeak = kFALSE;
+  fMCSecondaryMaterial = kFALSE;
+  if (stack) {
+    Int_t index = TMath::Abs(fLabel);
+    if (index < 0) {
+      printf("index = %d\n", index);
+      return;
+    }
+    TParticle *particle = stack->Particle(index);
+    fMCPrimary = stack->IsPhysicalPrimary(index);
+    fMCSecondaryWeak = stack->IsSecondaryFromWeakDecay(index);
+    fMCSecondaryMaterial = stack->IsSecondaryFromMaterial(index);
+    fMCPdgCode = particle->GetPdgCode();
+    Int_t indexm = particle->GetFirstMother();
+    if (indexm < 0) {
+      fMCMotherPrimary = kFALSE;
+      fMCMotherPdgCode = 0;
+    }
+    else {
+      TParticle *particlem = stack->Particle(indexm);
+      fMCMotherPrimary = stack->IsPhysicalPrimary(indexm);
+      fMCMotherPdgCode = particlem->GetPdgCode();
+    }
+
+    /* check TOF match */
+    fMCTOFMatchPrimary = kFALSE;
+    fMCTOFMatchPdgCode = 0;
+    fMCTOFMatchLevel = -1;
+    if (fTOFLabel[0] > 0) {
+      index = fTOFLabel[0];
+      particle = stack->Particle(index);
+      fMCTOFMatchPrimary = stack->IsPhysicalPrimary(index);
+      fMCTOFMatchPdgCode = particle->GetPdgCode();
+      /* check match level */
+      Int_t tracklabel = TMath::Abs(fLabel);
+      Int_t matchlevel = -1;
+      //      printf("entering match level loop\n");
+      //      printf("track is a:\n");
+      //      stack->Particle(tracklabel)->Print();
+      for (Int_t ilevel = 0; index > 0; ilevel++) {
+       //      printf("ilevel = %d, index = %d, tracklabel = %d\n", ilevel, index, tracklabel);
+       //      stack->Particle(index)->Print();
+       if (index == tracklabel) {
+         matchlevel = ilevel;
+         //      printf("break match loop at level %d\n", ilevel);
+         break;
+       }
+       index = stack->Particle(index)->GetFirstMother();
+      }
+      //      printf("out of match level loop: matchlevel = %d\n", matchlevel);
+      //      if (matchlevel != 0 && matchlevel != 1)
+      //       getchar();
+      fMCTOFMatchLevel = matchlevel;
+    }
+    
+  }
+  fTimeZeroSigma = 0.;
+  
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::HasTPCPID() const
+{
+  /*
+   * has TPC PID
+   */
+
+  /* check PID signal */
+  if (fTPCdEdx <= 0. || fTPCdEdxN == 0) return kFALSE;
+  return kTRUE;
+}
+  
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::HasTOFPID() const
+{
+  /*
+   * has TOF PID
+   */
+
+  /* check TOF matched track */
+  if (!(fStatus & AliESDtrack::kTOFout)||
+      !(fStatus & AliESDtrack::kTIME)) return kFALSE;
+  /* check integrated length */
+  if (fTOFLength < 350.) return kFALSE;
+  return kTRUE;
+}
+  
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsTPCPID(Int_t ipart, Float_t cutTPC) const
+{
+  /*
+   * is TPC PID
+   */
+
+  Float_t nSigma[AliPID::kSPECIES];
+  if (!MakeTPCPID(nSigma)) return kFALSE;
+  if (TMath::Abs(nSigma[ipart]) > cutTPC) return kFALSE;
+  return kTRUE;
+}
+  
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::MakeTPCPID(Float_t *nSigma) const
+{
+  /*
+   * make TPC PID
+   */
+  
+  /* check TPC PID */
+  if (!HasTPCPID()) return kFALSE;
+  /* loop over particles */
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    Double_t bethe = fgTPCResponse->GetExpectedSignal(fTPCmomentum, (AliPID::EParticleType)ipart);
+    Double_t diff = fTPCdEdx - bethe;
+    Double_t sigma = fgTPCResponse->GetExpectedSigma(fTPCmomentum, fTPCdEdxN, (AliPID::EParticleType)ipart);
+    nSigma[ipart] = diff / sigma;
+  }
+
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::MakeTOFPID(Float_t *nSigma) const
+{
+  /*
+   * make TOF PID
+   */
+  
+  /* check TOF PID */
+  if (!HasTOFPID()) return kFALSE;
+
+  /* loop over particles */
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    Double_t timez = fTOFTime - fTOFExpTime[ipart] - fgTOFResponse->GetStartTime(fP);
+    Double_t sigma = fgTOFResponse->GetExpectedSigma(fP, fTOFExpTime[ipart], AliPID::ParticleMass(ipart));
+    nSigma[ipart] = timez / sigma;
+  }
+
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsMismatch(const Float_t *nSigmaTPC, const Float_t *nSigmaTOF, Float_t cutTPC, Float_t cutTOF) const
+{
+  /*
+   * is mismatch
+   */
+
+  /* search for valid and compatible PID */
+  Bool_t valid = kFALSE;
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    if (TMath::Abs(nSigmaTPC[ipart]) < cutTPC) {
+      valid = kTRUE;
+      if (TMath::Abs(nSigmaTOF[ipart]) < cutTOF) return kFALSE;
+    }
+  }
+  /* check valid TPC PID */
+  if (!valid) return kFALSE;
+  /* check beta-gamma compatible */
+  if (IsBetaGammaCompatible(cutTPC, cutTOF)) return kFALSE;
+  /* mismatch */
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsMismatch(Float_t cutTPC, Float_t cutTOF) const
+{
+  /*
+   * is mismatch
+   */
+
+  Float_t nSigmaTPC[AliPID::kSPECIES];
+  Float_t nSigmaTOF[AliPID::kSPECIES];
+  Bool_t hasTPCPID = MakeTPCPID(nSigmaTPC);
+  Bool_t hasTOFPID = MakeTOFPID(nSigmaTOF);
+  /* check both TPC and TOF PID */
+  if (!hasTPCPID || !hasTOFPID) return kFALSE;
+  return IsMismatch(nSigmaTPC, nSigmaTOF, cutTPC, cutTOF);
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisTrack::RemoveTimeZero(const AliAnalysisEvent *analysisEvent)
+{
+  /*
+   * remove time-zero
+   */
+
+  if (!analysisEvent) return;
+  fTOFTime -= analysisEvent->GetTimeZeroSafe(fP);
+  fTimeZeroSigma = analysisEvent->GetTimeZeroSafeSigma(fP);
+  //  fTOFTime -= analysisEvent->GetTimeZeroBest(fP);
+  //  fTimeZeroSigma = analysisEvent->GetTimeZeroBestSigma(fP);
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsTPCDeuton() const
+{
+  /*
+   * is TPC deuton
+   */
+
+  /* check TPC PID */
+  if (!HasTPCPID()) return kFALSE;
+  Double_t mass = 1.8756; /* GeV */
+  Double_t bethe = fgTPCResponse->Bethe(fTPCmomentum / mass);
+  Double_t diff = fTPCdEdx - bethe;
+  Double_t sigma = bethe * 0.07;
+  if (TMath::Abs(diff / sigma) < 5.) return kTRUE;
+  return kFALSE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsTPCTriton() const
+{
+  /*
+   * is TPC triton
+   */
+
+  /* check TPC PID */
+  if (!HasTPCPID()) return kFALSE;
+  Double_t mass = 2. * 0.939565560 + AliPID::ParticleMass(4); /* GeV */
+  Double_t bethe = fgTPCResponse->Bethe(fTPCmomentum / mass);
+  Double_t diff = fTPCdEdx - bethe;
+  Double_t sigma = bethe * 0.07;
+  if (TMath::Abs(diff / sigma) < 5.) return kTRUE;
+  return kFALSE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsTPCHeavy() const
+{
+  /*
+   * is TPC heavy
+   */
+  
+  /* check TPC heavier than proton */
+  if (!HasTPCPID()) return kFALSE;
+  Double_t mass = 1.8756; /* GeV */
+  Double_t bethe = fgTPCResponse->Bethe(fTPCmomentum / mass);
+  Double_t diff = fTPCdEdx - bethe;
+  Double_t sigma = bethe * 0.07;
+  if (diff / sigma > -5.) return kTRUE;
+  return kFALSE;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisTrack::GetTOFBetaSigma() const
+{
+  /*
+   * get TOF beta sigma
+   */
+
+  Float_t tofReso = TMath::Sqrt(80. * 80. + fTimeZeroSigma * fTimeZeroSigma);
+  return GetTOFBeta() * tofReso / fTOFTime;
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisTrack::GetTPCdEdxTh(Float_t betagamma) const
+{
+  /*
+   * get TPD dEdx th
+   */
+
+  return fgTPCResponse->Bethe(betagamma);
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsBetaGammaCompatible(Float_t cutTPC, Float_t cutTOF) const
+{
+  /*
+   * is beta-gamma compatible
+   */
+
+  Double_t epsilon = 1.e-10;
+  /* check TPC PID */
+  if (!HasTPCPID()) return kTRUE;
+  /* get beta and sigma */
+  Double_t beta = GetTOFBeta();
+  Double_t betasigma = GetTOFBetaSigma();
+  /* get and check beta min/max */
+  Double_t betamin = beta - cutTOF * betasigma;
+  Double_t betamax = beta + cutTOF * betasigma;
+  if (betamin <= 0.) betamin = epsilon;
+  if (betamin >= 1.) betamin = 1. - epsilon;
+  if (betamax <= 0.) betamax = epsilon;
+  if (betamax >= 1.) betamax = 1. - epsilon;
+  /* check TOF beta-gamma min/max compatible with TPC dEdx */
+  Double_t betagammamin = betamin / TMath::Sqrt(1. - betamin * betamin);
+  Double_t betagammamax = betamax / TMath::Sqrt(1. - betamax * betamax);
+  Double_t bethemin = fgTPCResponse->Bethe(betagammamin);
+  Double_t bethemax = fgTPCResponse->Bethe(betagammamax);
+  Double_t diffmin = fTPCdEdx - bethemin;
+  Double_t diffmax = fTPCdEdx - bethemax;
+  Double_t sigmamin = bethemin * 0.07;
+  Double_t sigmamax = bethemax * 0.07;
+  Double_t nsigmamin = diffmin / sigmamin;
+  Double_t nsigmamax = diffmax / sigmamax;
+  if (TMath::Abs(nsigmamin) < cutTPC) return kTRUE;
+  if (TMath::Abs(nsigmamax) < cutTPC) return kTRUE;
+  return kFALSE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::IsHeavyAndCompatible(const Float_t *nSigmaTOF, Float_t cutTPC, Float_t cutTOF) const
+{
+  /*
+   * is heavy and compatible
+   */
+
+  /* check TOF time larger than proton expected time */
+  if (nSigmaTOF[AliPID::kProton] < cutTOF) return kFALSE;
+  return IsBetaGammaCompatible(cutTPC, cutTOF);
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::HasPrimaryDCA(Float_t nSigmaXY, Float_t nSigmaZ) const
+{
+  /*
+   * has primary DCA
+   */
+
+  // cut on transverse impact parameter
+  Float_t d0z0[2],covd0z0[3];
+  d0z0[0] = GetImpactParameter(0);
+  d0z0[1] = GetImpactParameter(1);
+  covd0z0[0] = GetImpactParameterCov(0);
+  covd0z0[1] = GetImpactParameterCov(1);
+  covd0z0[2] = GetImpactParameterCov(2);
+  Float_t sigma= 0.0050 + 0.0060 / TMath::Power(fPt, 0.9);
+  Float_t d0max = nSigmaXY * sigma;
+  //
+  Float_t sigmaZ = 0.0146 + 0.0070 / TMath::Power(fPt, 1.114758);
+  if (fPt > 1.) sigmaZ = 0.0216;
+  Float_t d0maxZ = nSigmaZ * sigmaZ;
+  //
+  if(TMath::Abs(d0z0[0]) > d0max || TMath::Abs(d0z0[1]) > d0maxZ)
+    return kFALSE;
+  
+  /* primary DCA ok */
+  return kTRUE;
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::LoadTuningExpTimeTh(const Char_t *filename)
+{
+  /*
+   * load tuning exp time th
+   */
+
+  TFile *file = TFile::Open(filename);
+  if (!file || !file->IsOpen()) return kFALSE;
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+    hTOFtuned_th[ipart] = (TH2F *)file->Get(Form("hTOFtuned_th_%s", AliPID::ParticleName(ipart)));
+  return kTRUE;
+  
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisTrack::GetTuningExpTimeTh(Int_t ipart) const
+{
+  /*
+   * get tuning exp time th
+   */
+
+  if (!hTOFtuned_th[ipart]) return 0.;
+  if (fP > 1.5) return 0.;
+  Int_t bin = hTOFtuned_th[ipart]->FindBin(fP, fEta);
+  Float_t value = hTOFtuned_th[ipart]->GetBinContent(bin);
+  return value;
+}
+
+//___________________________________________________________
+
+Int_t
+AliAnalysisTrack::GetTOFVolumeIndex(Int_t i)
+{
+  /*
+   * get TOF volume index
+   */
+
+  if (i < 0 || i > 4) return -1;
+  Int_t det[5];
+  fgTOFGeometry.GetVolumeIndices(fTOFIndex, det);
+  return det[i];
+
+}
+
+//___________________________________________________________
+
+Int_t
+AliAnalysisTrack::GetMCPID() const
+{
+  /*
+   * get MC PID
+   */
+
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+    if (TMath::Abs(fMCPdgCode) == AliPID::ParticleCode(ipart))
+      return ipart;
+  return -1;
+
+}
+
+//___________________________________________________________
+
+Int_t
+AliAnalysisTrack::GetMCCharge() const
+{
+  /*
+   * get MC charge
+   */
+  
+  TDatabasePDG *dbpdg = TDatabasePDG::Instance();
+  TParticlePDG *pdg = dbpdg->GetParticle(fMCPdgCode);
+  if (!pdg) return 0;
+  return (Int_t)TMath::Sign(1., pdg->Charge());
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisTrack::GetTOFExpTimeSigma(Int_t i) const
+{
+  /*
+   * get TOF integrated times sigma
+   */
+
+  Double_t par[5][3] = {
+    {1.84217e-04, 2.50350e-04, -2.06718e+00},
+    {1.84217e-04, 2.50350e-04, -2.06718e+00},
+    {1.84217e-04, 2.50350e-04, -2.06718e+00},
+    {1.30006e-04, 1.65197e-03, -1.21072e+00},
+    {1.89219e-03, 2.06852e-03, -1.85165e+00}
+  };
+  
+  return 1.5 * (par[i][0] + par[i][1] * TMath::Power(fP, par[i][2])) * fTOFExpTime[i];
+
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisTrack::GetTOFExpTimeCorrection(Int_t i, Int_t chargeCorr) const
+{
+  /*
+   * get TOF integrated times correction
+   */
+
+  /* for both charges */
+  Double_t par[AliPID::kSPECIES][5] = {
+    {-40., 0., 0., 0., 1.},
+    {-4.26411e+00, -8.17232e+01, 2.84390e+02, -1.10976e-02, -3.76187e+00},
+    {-4.26411e+00, -8.17232e+01, 2.84390e+02, -1.10976e-02, -3.76187e+00},
+    {3.74297e+00, -4.90544e+03, 0.00000e+00, 0.00000e+00, -8.79427e+00},
+    {3.36701e+00, 1.60189e+04, -3.43919e+04, 8.27698e-02, -6.49010e+00}
+  };
+  /* split charges */
+  Double_t parpos[AliPID::kSPECIES][2] = {
+    {0., 0.},
+    {1.97815e+00, -1.76842e-01},
+    {1.97815e+00, -1.76842e-01},
+    {1.66051e+01, -8.98377e-01},
+    {2.09552e+01, -3.18122e-01}
+  };
+  Double_t parneg[AliPID::kSPECIES][2] = {
+    {0., 0.},
+    {-5.91210e+00, -1.04768e+00},
+    {-5.91210e+00, -1.04768e+00},
+    {-1.58687e+01, -7.93304e-01},
+    {-2.90316e+01, -4.05392e-01}
+  };
+  
+  Double_t x = fP;
+  Double_t corr = par[i][0]+(par[i][1]*x+par[i][2]*x*x+par[i][3]*x*x*x)*TMath::Exp(par[i][4]*x);
+  Double_t chcorr;
+  if (fSign > 0.)
+    chcorr = parpos[i][0]*TMath::Exp(parpos[i][1]*x);
+  else if (fSign < 0.)
+    chcorr = parneg[i][0]*TMath::Exp(parneg[i][1]*x);
+  else
+    return 0.;
+  
+  return corr + chargeCorr * chcorr;
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisTrack::UpdateTOFResponse(AliAnalysisEvent *analysisEvent)
+{
+  /*
+   * update TOF response
+   */
+
+  fgTOFResponse->SetT0event(analysisEvent->GetTimeZeroTOF());
+  fgTOFResponse->SetT0resolution(analysisEvent->GetTimeZeroTOFSigma());
+}
+
+//___________________________________________________________
+
+Float_t
+AliAnalysisTrack::GetTOFExpectedSigma(Int_t i) const
+{
+  /*
+   * get TOF expected sigma
+   */
+
+  return fgTOFResponse->GetExpectedSigma(fP, fTOFExpTime[i], AliPID::ParticleMass(i));
+
+}
+
+//___________________________________________________________
+
+void
+AliAnalysisTrack::ApplyTOFExpectedTimeCorrection(Int_t chargeCorr)
+{
+  /*
+   * apply TOF expected time correction
+   */
+
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+    fTOFExpTime[ipart] += GetTOFExpTimeCorrection(ipart, chargeCorr);
+  
+}
+
+//___________________________________________________________
+
+Bool_t
+AliAnalysisTrack::AcceptTrack(Bool_t selPrimaries)
+{
+  /*
+   * accept track
+   */
+
+  /* check charge */
+  if (fSign == 0.) return kFALSE;
+  /* check eta */
+  if (TMath::Abs(fEta) > fgEtaCut) return kFALSE;
+  if (TMath::Abs(fEta) < fgEtaReject) return kFALSE;
+  /* check max DCA to vertex Z */
+  if (TMath::Abs(fImpactParameter[1]) > fgMaxDCAToVertexZCut) return kFALSE;
+  /* check max DCA to vertex XY */
+  if (selPrimaries) {
+    Float_t maxdca = fgMaxDCAToVertexXYPtDepFormula->Eval(fPt);
+    if (TMath::Abs(fImpactParameter[0]) > maxdca) return kFALSE;
+  }
+  /* check max chi2 per cluster TPC */
+  Float_t chi2 = fTPCchi2 / (Float_t)fTPCNcls;
+  if (chi2 > fgMaxChi2PerClusterTPC) return kFALSE;
+  /* check min N clusters TPC */
+  if (fgAcceptTrackClusterCut != 1) {
+    if (fTPCNcls < fgMinNClustersTPC) return kFALSE;
+  }
+  if (fgAcceptTrackClusterCut == 1) {
+    /* check min N crossed rows TPC */
+    if (fTPCNcr < fgMinNCrossedRowsTPC) return kFALSE;
+    /* check min crossed rows over findable clusters ratio */
+    Float_t crratio = 1.;
+    if (fTPCNclsF > 0) crratio = fTPCNcr / fTPCNclsF;
+    if (crratio < fgMinRatioCrossedRowsOverFindableClustersTPC) return kFALSE;
+  }
+  /* check accept track status cut */
+  if (fgAcceptTrackStatusCut && (fStatus & fgAcceptTrackStatusCut) == 0) return kFALSE;
+  /* check reject track status cut */
+  if (fgRejectTrackStatusCut && (fStatus & fgRejectTrackStatusCut) != 0) return kFALSE;
+  /* reject ITS fakes if requested */
+  if (fgRejectITSFakes && fITSFakeFlag) return kFALSE;
+
+  /* accept track */
+  return kTRUE;
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisTrack.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/AliAnalysisTrack.h
new file mode 100644 (file)
index 0000000..07fe76c
--- /dev/null
@@ -0,0 +1,212 @@
+#ifndef ALIANALYSISTRACK_H
+#define ALIANALYSISTRACK_H
+
+#include "TObject.h"
+#include "TMath.h"
+#include "TLorentzVector.h"
+#include "AliTOFGeometry.h"
+#include "AliTOFcalibHisto.h"
+#include "AliTPCPIDResponse.h"
+#include "AliTOFPIDResponse.h"
+#include "AliAnalysisEvent.h"
+#include "AliESDtrack.h"
+#include "AliPID.h"
+#include "TF1.h"
+
+class AliStack;
+class AliMCEvent;
+class TH2F;
+
+class AliAnalysisTrack :
+public TObject
+{
+
+ public:
+
+  AliAnalysisTrack(); // default constructor
+  AliAnalysisTrack(const AliAnalysisTrack &source); // copy constructor
+  AliAnalysisTrack &operator=(const AliAnalysisTrack &source); // operator=
+  virtual ~AliAnalysisTrack(); // default destructor
+
+  Float_t GetP() const {return fP;}; // get p
+  Float_t GetPt() const {return fPt;}; // get pt
+  Float_t GetEta() const {return fEta;}; // get eta
+  Float_t GetPhi() const {return fPhi;}; // get phi
+  Float_t GetY(Float_t mass) const; // get Y
+  Double_t GetSign() const {return fSign;}; // get sign
+  ULong_t GetStatus() const {return fStatus;}; // get status
+  Int_t GetLabel() const {return fLabel;}; // get label
+  Float_t GetImpactParameter(Int_t i) const {return fImpactParameter[i];}; // get impact parameter
+  Float_t GetImpactParameterCov(Int_t i) const {return fImpactParameterCov[i];}; // get impact parameter covariance
+  Float_t GetTPCmomentum() const {return fTPCmomentum;}; // get TPC inner wall momentum
+  Float_t GetTPCdEdx() const {return fTPCdEdx;}; // get TPC dEdx
+  UShort_t GetTPCdEdxN() const {return fTPCdEdxN;}; // get TPC dEdx clusters
+  UShort_t GetTPCNcls() const {return fTPCNcls;}; // get number of clusters TPC
+  UShort_t GetTPCNclsF() const {return fTPCNclsF;}; // get number of findable clusters TPC
+  Float_t GetTPCnc() const {return fTPCNcr;}; // get number of crossed rows TPC
+  Int_t GetTOFIndex() const {return fTOFIndex;}; // get TOF index
+  Float_t GetTOFTime() const {return fTOFTime;}; // get TOF time
+  Float_t GetTOFExpTime(Int_t i) const {return fTOFExpTime[i];}; // get TOF integrated times
+  Float_t GetTOFExpTimeCorrection(Int_t i, Int_t chargeCorr = 0) const; // get TOF integrated times correction
+  Float_t GetTOFExpTimeSigma(Int_t i) const; // get TOF integrated times sigma
+  Float_t GetTOFExpectedSigma(Int_t i) const; // get TOF expected sigma
+  Float_t GetTOFLength() const {return fTOFLength;}; // get TOF length
+  Int_t GetTOFLabel(Int_t i) const {return fTOFLabel[i];}; // get TOF label
+  Float_t GetTOFDeltaX() const {return fTOFDeltaX;}; // get TOF deltaX
+  Float_t GetTOFDeltaZ() const {return fTOFDeltaZ;}; // get TOF deltaZ
+  Bool_t IsMCPrimary() const {return fMCPrimary;}; // is MC primary
+  Bool_t IsMCSecondaryWeakDecay() const {return fMCSecondaryWeak;}; // is MC weak decay
+  Bool_t IsMCSecondaryMaterial() const {return fMCSecondaryMaterial;}; // is MC material
+  Bool_t IsMCPrimary(Int_t ipart) const {return (fMCPrimary && TMath::Abs(fMCPdgCode) == AliPID::ParticleCode(ipart));}; // is MC primary
+  Int_t GetMCPdgCode() const {return fMCPdgCode;}; // get MC PDG code
+  Int_t GetMCMotherPdgCode() const {return fMCMotherPdgCode;}; // get MC mother PDG code
+  Int_t GetMCMotherPrimary() const {return fMCMotherPrimary;}; // get MC mother primary
+
+  Bool_t IsMCTOFMatchPrimary() const {return fMCTOFMatchPrimary;};
+  Int_t GetMCTOFMatchPdgCode() const {return fMCTOFMatchPdgCode;};
+  Int_t GetMCTOFMatchLevel() const {return fMCTOFMatchLevel;};
+  Float_t GetMCTOFTime() const {return fMCTOFTime;};
+  Float_t GetMCTOFLength() const {return fMCTOFLength;};
+
+  Bool_t IsInTOFPad() const {return ((TMath::Abs(fTOFDeltaX) < 1.25) && (TMath::Abs(fTOFDeltaZ) < 1.75));}; // is in TOF pad
+
+  Int_t GetTOFVolumeIndex(Int_t i); // get TOF volume index
+  Float_t GetTOFBeta() const {return HasTOFPID() ? fTOFLength / (2.99792457999999984e-02 * (fTOFTime - fgTOFResponse->GetStartTime(fP))) : 0.;}; // get TOF beta
+  Float_t GetTOFBetaSigma() const; // get TOF beta sigma
+  Float_t GetTOFExpBeta(Int_t ipart) const {return HasTOFPID() ? fTOFLength / (2.99792457999999984e-02 * fTOFExpTime[ipart]) : 0.;}; // get TOF beta
+  Float_t GetTOFBetaTh(Int_t ipart) const {return GetTOFBetaTh(AliPID::ParticleMass(ipart));}; // get TOF beta th
+  Float_t GetTOFBetaTh(Float_t mass) const {return TMath::Sqrt(1. / (1. + mass * mass / (fP * fP)));}; // get TOF beta th
+  Float_t GetTOFMass2() const {return fP * fP * (1. / (GetTOFBeta() * GetTOFBeta()) - 1.);}; // get TOF mass^2
+  Float_t GetTOFMass() const {return GetTOFMass2() > 0. ? TMath::Sqrt(TMath::Abs(GetTOFMass2())) : -TMath::Sqrt(TMath::Abs(GetTOFMass2()));}; // get TOF mass
+  Float_t GetTPCdEdxTh(Float_t betagamma) const; // get TPC dEdx th
+  Float_t GetTOFExpTimeTh(Int_t ipart) const {return fTOFLength / 2.99792457999999984e-02 / GetTOFBetaTh(ipart);}; // get TOF exp time th
+  Float_t GetTuningExpTimeTh(Int_t ipart) const; // get tuning exp time th
+  Float_t GetTPCBetaGamma(Int_t ipart) const {return fTPCmomentum / AliPID::ParticleMass(ipart);}; // get TPC beta-gamma
+
+  void Reset(); // reset
+  void Update(AliESDtrack *track, AliStack *stack, AliMCEvent *mcevent); // update
+  Bool_t HasTOFMatch() const {return (fStatus & AliESDtrack::kTOFout);}; // has TOF match
+  Bool_t HasIntegratedTimes() const{ return (fStatus & AliESDtrack::kTIME);}; // has integrated times
+  Bool_t HasTPCPID() const; // has TPC PID
+  Bool_t HasTOFPID() const; // has TOF PID
+  Bool_t MakeTPCPID(Float_t *nSigma) const; // make TPC PID
+  Bool_t MakeTOFPID(Float_t *nSigma) const; // make TOF PID
+  Bool_t IsMismatchMC() const {return (fMCTOFMatchLevel != 0);}; // is mismatch MC
+  Int_t GetMCPID() const; // get MC PID
+  Int_t GetMCCharge() const; // get MC charge
+  Bool_t IsUncorrelatedMismatchMC() const {return (fMCTOFMatchLevel < 0);}; // is uncorreltaed mismatch MC
+  Bool_t IsMismatch(Float_t cutTPC = 5., Float_t cutTOF = 5.) const; // is mismatch
+  Bool_t IsMismatch(const Float_t *nSigmaTPC, const Float_t *nSigmaTOF, Float_t cutTPC = 5., Float_t cutTOF = 5.) const; // is mismatch
+  Bool_t IsBetaGammaCompatible(Float_t cutTPC = 5., Float_t cutTOF = 5.) const; // is beta-gamma compatible
+  Bool_t IsHeavyAndCompatible(const Float_t *nSigmaTOF, Float_t cutTPC = 5., Float_t cutTOF = 5.) const; // is heavy and compatible
+  void RemoveTimeZero(const AliAnalysisEvent *analysisEvent); // remove time-zero
+  Bool_t IsTPCPID(Int_t ipart, Float_t cutTPC = 5.) const; // is TPC PID
+  Bool_t IsTPCDeuton() const; // is TPC deuton
+  Bool_t IsTPCTriton() const; // is TPC deuton
+  Bool_t IsTPCHeavy() const; // is TPC heavy
+  Bool_t HasPrimaryDCA(Float_t nSigmaXY = 7., Float_t nSigmaZ = 5.) const; // has primary DCA
+  Bool_t IsTRDin() const {return fStatus & AliESDtrack::kTRDin;}; // is TRD in
+  Bool_t IsTRDout() const {return fStatus & AliESDtrack::kTRDout;}; // is TRD out
+  Bool_t IsTRDrefit() const {return fStatus & AliESDtrack::kTRDrefit;}; // is TRD refit
+  Bool_t IsTOFout() const {return fStatus & AliESDtrack::kTOFout;}; // is TOF out
+
+  static Bool_t LoadTuningExpTimeTh(const Char_t *filename); // load tuning exp time th
+
+  Int_t GetTOFCalibIndex(Int_t imap) {return (Int_t)fgTOFcalibHisto.GetCalibMap(imap, fTOFIndex);}; // get TOF calib index
+
+  static AliTOFPIDResponse *GetTOFResponse() {return fgTOFResponse;}; // getter
+  static AliTPCPIDResponse *GetTPCResponse() {return fgTPCResponse;}; // getter
+  static void SetTOFResponse(AliTOFPIDResponse *value) {fgTOFResponse = value;}; // setter
+  static void SetTPCResponse(AliTPCPIDResponse *value) {fgTPCResponse = value;}; // setter
+
+  static void UpdateTOFResponse(AliAnalysisEvent *analysisEvent); // update TOF response
+
+  void ApplyTOFExpectedTimeCorrection(Int_t chargeCorr = 0); // apply expected time correction
+
+  Bool_t AcceptTrack(Bool_t selPrimaries = kTRUE); // accept track
+  static void SetAcceptTrackMinNClustersTPC(UShort_t value) {fgMinNClustersTPC = value;}; // setter
+  static void SetAcceptTrackClusterCut(Int_t value) {fgAcceptTrackClusterCut = value;}; // setter
+  static void SetAcceptTrackMaxDCAToVertexXYPtDepFormula(TFormula *formula) {fgMaxDCAToVertexXYPtDepFormula = formula;}; // setter
+  static void SetAcceptTrackEtaCut(Float_t value) {fgEtaCut = value;}; // setter
+  static void SetAcceptTrackEtaReject(Float_t value) {fgEtaReject = value;}; // setter
+  static void SetAcceptTrackStatusCut(ULong_t value) {fgAcceptTrackStatusCut = value;}; // setter
+  static void SetRejectTrackStatusCut(ULong_t value) {fgRejectTrackStatusCut = value;}; // setter
+  static void SetAcceptTrackMaxDCAToVertexZCut(Float_t value) {fgMaxDCAToVertexZCut = value;}; // setter
+  static void SetAcceptTrackMaxChi2PerClusterTPC(Float_t value) {fgMaxChi2PerClusterTPC = value;}; // setter
+  static void SetRejectITSFakes(Bool_t value) {fgRejectITSFakes = value;}; // setter
+
+ private:
+
+  /*** global track info ***/
+  Float_t fP; // p
+  Float_t fPt; // pt
+  Float_t fEta; // eta
+  Float_t fPhi; // phi
+  Double_t fSign; // sign
+  ULong_t fStatus; // status
+  Int_t fLabel; // label
+  Float_t fImpactParameter[2]; // impact parameters 
+  Float_t fImpactParameterCov[3]; // impact parameters covariance
+  /*** TPC PID info ***/
+  Float_t fTPCmomentum; // TPC inner wall momentum
+  Float_t fTPCdEdx; // dEdx
+  UShort_t fTPCdEdxN; // dEdx clusters
+  UShort_t fTPCNcls; // number of clusters TPC
+  UShort_t fTPCNclsF; // number of findable clusters TPC
+  Float_t fTPCNcr; // number of crossed rows TPC
+  /*** TOF PID info ***/
+  Int_t fTOFIndex; // index
+  Float_t fTOFTime; // time
+  Float_t fTOFExpTime[AliPID::kSPECIES]; // integrated time array
+  Float_t fTOFLength; // track length
+  Float_t fTOFDeltaX; // TOF deltaX
+  Float_t fTOFDeltaZ; // TOF deltaZ
+  Int_t fTOFLabel[3]; // TOF label
+  /*** MC info ***/
+  Bool_t fMCPrimary; // MC primary flag
+  Int_t fMCPdgCode; // MC PDG code
+  Bool_t fMCMotherPrimary; // MC mother primary flag
+  Int_t fMCMotherPdgCode; // MC mother PDG code
+  Bool_t fMCTOFMatchPrimary; // MC TOF match primary flag
+  Int_t fMCTOFMatchPdgCode; // MC TOF match PDG code
+  Short_t fMCTOFMatchLevel; // MC TOF match level
+  Float_t fMCTOFTime; // MC TOF time
+  Float_t fMCTOFLength; // MC TOF length
+  Bool_t fMCSecondaryWeak; 
+  Bool_t fMCSecondaryMaterial; 
+  /*** HMPID PID info ***/
+  Float_t fHMPIDmomentum;
+  Float_t fHMPIDsignal;
+  /*** extras ***/
+  Float_t fTPCchi2; // TPC chi2
+  Bool_t fITSFakeFlag; // ITS fake flag
+
+  /*** cut paramters */
+  static Float_t fgEtaCut; // eta cut
+  static Float_t fgEtaReject; // eta reject
+  static TFormula *fgMaxDCAToVertexXYPtDepFormula; // DCA-xy cut formula
+  static UShort_t fgMinNClustersTPC; // cut
+  static UShort_t fgMinNCrossedRowsTPC; // cut
+  static Float_t fgMinRatioCrossedRowsOverFindableClustersTPC; // cut
+  static Int_t fgAcceptTrackClusterCut; // cluster cut
+  static ULong_t fgAcceptTrackStatusCut; // accept track status cut
+  static ULong_t fgRejectTrackStatusCut; // reject track status cut
+  static Float_t fgMaxDCAToVertexZCut; // DCA-z cut
+  static Float_t fgMaxChi2PerClusterTPC; // max chi2 per cluster TPC cut
+  static Bool_t fgRejectITSFakes; // reject ITS fakes cut
+
+  /*** tools ***/
+  static TLorentzVector fgLorentzVector;
+  static AliTOFGeometry fgTOFGeometry;
+  static AliTOFcalibHisto fgTOFcalibHisto;
+  static Bool_t fgTOFcalibHistoFlag;
+  static AliTPCPIDResponse *fgTPCResponse;
+  static AliTOFPIDResponse *fgTOFResponse;
+  static TH2F *hTOFtuned_th[AliPID::kSPECIES];
+
+  Float_t fTimeZeroSigma; //!
+
+  ClassDef(AliAnalysisTrack, 9);
+};
+
+#endif /* ALIANALYSISTRACK_H */
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooFermiCutoff.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooFermiCutoff.cxx
new file mode 100644 (file)
index 0000000..c3d08d7
--- /dev/null
@@ -0,0 +1,47 @@
+/***************************************************************************** 
+ * Project: RooFit                                                           * 
+ *                                                                           * 
+ * This code was autogenerated by RooClassFactory                            * 
+ *****************************************************************************/ 
+
+// Your description goes here... 
+
+#include "Riostream.h" 
+
+#include "RooFermiCutoff.h" 
+#include "RooAbsReal.h" 
+#include "RooAbsCategory.h" 
+#include <math.h> 
+#include "TMath.h" 
+
+ClassImp(RooFermiCutoff) 
+
+ RooFermiCutoff::RooFermiCutoff(const char *name, const char *title, 
+                        RooAbsReal& _x,
+                        RooAbsReal& _cutoff,
+                        RooAbsReal& _power) :
+   RooAbsPdf(name,title), 
+   x("x","x",this,_x),
+   cutoff("cutoff","cutoff",this,_cutoff),
+   power("power","power",this,_power)
+ { 
+ } 
+
+
+ RooFermiCutoff::RooFermiCutoff(const RooFermiCutoff& other, const char* name) :  
+   RooAbsPdf(other,name), 
+   x("x",this,other.x),
+   cutoff("cutoff",this,other.cutoff),
+   power("power",this,other.power)
+ { 
+ } 
+
+
+
+ Double_t RooFermiCutoff::evaluate() const 
+ { 
+   return (1. / (TMath::Exp((cutoff - x) / power) + 1.)); 
+ } 
+
+
+
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooFermiCutoff.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooFermiCutoff.h
new file mode 100644 (file)
index 0000000..0efa747
--- /dev/null
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Project: RooFit                                                           *
+ *                                                                           *
+  * This code was autogenerated by RooClassFactory                            * 
+ *****************************************************************************/
+
+#ifndef ROOFERMICUTOFF
+#define ROOFERMICUTOFF
+
+#include "RooAbsPdf.h"
+#include "RooRealProxy.h"
+#include "RooCategoryProxy.h"
+#include "RooAbsReal.h"
+#include "RooAbsCategory.h"
+class RooFermiCutoff : public RooAbsPdf {
+public:
+  RooFermiCutoff() {} ; 
+  RooFermiCutoff(const char *name, const char *title,
+             RooAbsReal& _x,
+             RooAbsReal& _cutoff,
+             RooAbsReal& _power);
+  RooFermiCutoff(const RooFermiCutoff& other, const char* name=0) ;
+  virtual TObject* clone(const char* newname) const { return new RooFermiCutoff(*this,newname); }
+  inline virtual ~RooFermiCutoff() { }
+
+protected:
+
+  RooRealProxy x ;
+  RooRealProxy cutoff ;
+  RooRealProxy power ;
+  
+  Double_t evaluate() const ;
+
+private:
+
+  ClassDef(RooFermiCutoff,1) // Your description goes here...
+};
+#endif
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooGaussianTail.cxx b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooGaussianTail.cxx
new file mode 100644 (file)
index 0000000..cd6f7ae
--- /dev/null
@@ -0,0 +1,54 @@
+/***************************************************************************** 
+ * Project: RooFit                                                           * 
+ *                                                                           * 
+ * This code was autogenerated by RooClassFactory                            * 
+ *****************************************************************************/ 
+
+// Your description goes here... 
+
+#include "Riostream.h" 
+
+#include "RooGaussianTail.h" 
+#include "RooAbsReal.h" 
+#include "RooAbsCategory.h" 
+#include <math.h> 
+#include "TMath.h" 
+
+ClassImp(RooGaussianTail) 
+
+ RooGaussianTail::RooGaussianTail(const char *name, const char *title, 
+                        RooAbsReal& _x,
+                        RooAbsReal& _mean,
+                        RooAbsReal& _sigma,
+                        RooAbsReal& _tail) :
+   RooAbsPdf(name,title), 
+   x("x","x",this,_x),
+   mean("mean","mean",this,_mean),
+   sigma("sigma","sigma",this,_sigma),
+   tail("tail","tail",this,_tail)
+ { 
+ } 
+
+
+ RooGaussianTail::RooGaussianTail(const RooGaussianTail& other, const char* name) :  
+   RooAbsPdf(other,name), 
+   x("x",this,other.x),
+   mean("mean",this,other.mean),
+   sigma("sigma",this,other.sigma),
+   tail("tail",this,other.tail)
+ { 
+ } 
+
+
+
+ Double_t RooGaussianTail::evaluate() const
+ { 
+   Double_t tail2 = tail * sigma;
+   if (x <= (tail2 + mean))
+     return TMath::Gaus(x, mean, sigma);
+   else
+     return TMath::Gaus(tail2 + mean, mean, sigma) * TMath::Exp(-tail2 * (x - tail2 - mean) / (sigma * sigma));
+ } 
+
+
+
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooGaussianTail.h b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/libs/RooGaussianTail.h
new file mode 100644 (file)
index 0000000..eb34087
--- /dev/null
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * Project: RooFit                                                           *
+ *                                                                           *
+  * This code was autogenerated by RooClassFactory                            * 
+ *****************************************************************************/
+
+#ifndef ROOGAUSSIANTAIL
+#define ROOGAUSSIANTAIL
+
+#include "RooAbsPdf.h"
+#include "RooRealProxy.h"
+#include "RooCategoryProxy.h"
+#include "RooAbsReal.h"
+#include "RooAbsCategory.h"
+class RooGaussianTail : public RooAbsPdf {
+public:
+  RooGaussianTail() {} ; 
+  RooGaussianTail(const char *name, const char *title,
+             RooAbsReal& _x,
+             RooAbsReal& _mean,
+             RooAbsReal& _sigma,
+             RooAbsReal& _tail);
+  RooGaussianTail(const RooGaussianTail& other, const char* name=0) ;
+  virtual TObject* clone(const char* newname) const { return new RooGaussianTail(*this,newname); }
+  inline virtual ~RooGaussianTail() { }
+
+protected:
+
+  RooRealProxy x ;
+  RooRealProxy mean ;
+  RooRealProxy sigma ;
+  RooRealProxy tail ;
+  
+  Double_t evaluate() const;
+
+private:
+
+  ClassDef(RooGaussianTail,1) // Your description goes here...
+};
+#endif
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/DCA.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/DCA.C
new file mode 100644 (file)
index 0000000..aec4885
--- /dev/null
@@ -0,0 +1,1258 @@
+Double_t tofReso = 85.;
+
+/**************************************************************/
+/*** HISTOS AND BINNING ***************************************/
+/**************************************************************/
+
+/**************************************************************/
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative",
+};
+/**************************************************************/
+enum EMCHisto_t {
+  kPrimary,
+  kWeakDecay,
+  kMaterial,
+  kNMCHistos
+};
+const Char_t *mchistoName[kNMCHistos] = {
+  "primary",
+  "weakdecay",
+  "material"
+};
+/**************************************************************/
+const Int_t NcentralityBins = 10;
+Double_t centralityBin[NcentralityBins + 1] = {0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.};
+/**************************************************************/
+const Int_t NdcaBins = 2000;
+Double_t dcaBin[NdcaBins + 1];
+Double_t dcaMin = -5., dcaMax = 5., dcaStep = (dcaMax - dcaMin) / NdcaBins;
+/**************************************************************/
+const Int_t NptBins = 46;
+Double_t ptBin[NptBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+/**************************************************************/
+const Int_t NmtBins = 46;
+Double_t mtBin[NmtBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+/**************************************************************/
+
+/**************************************************************/
+/**************************************************************/
+/**************************************************************/
+
+/**************************************************************/
+
+DCAdata(const Char_t *filename, Int_t evMax = kMaxInt, Int_t startEv = 0)
+{
+  
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* open enabled flag map */
+  //  TFile *enabledfile = TFile::Open(enabledChannelsFileName);
+  //  TH1F *hEnabledFlag = (TH1F *)enabledfile->Get("hEnabledFlag");
+
+  /**************************************************************/
+  /*** HISTOS ***************************************************/
+  /**************************************************************/
+
+  /* run-time binning */
+  for (Int_t ibin = 0; ibin < NdcaBins + 1; ibin++)
+    dcaBin[ibin] = dcaMin + ibin * dcaStep;
+  
+  /* histos */
+  TH3I *hDCAopen[AliPID::kSPECIES][kNCharges];
+  TH3I *hDCAcut[AliPID::kSPECIES][kNCharges];
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hDCAopen[ipart][icharge] = new TH3I(Form("hDCAopen_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "", NcentralityBins, centralityBin, NptBins, ptBin, NdcaBins, dcaBin);
+      hDCAcut[ipart][icharge] = new TH3I(Form("hDCAcut_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "", NcentralityBins, centralityBin, NptBins, ptBin, NdcaBins, dcaBin);
+    }
+  }
+  
+  /**************************************************************/
+  /**************************************************************/
+  /**************************************************************/
+
+  /* TOF PID response */
+  AliTOFPIDResponse tofResponse;
+  tofResponse.SetTimeResolution(tofReso);
+  /* TPC PID response */
+  AliTPCPIDResponse *tpcResponse = AliAnalysisTrack::GetTPCResponse();
+
+  /* start stopwatch */
+  TStopwatch timer;
+  timer.Start();
+
+  /* loop over events */
+  Int_t charge, index;
+  UShort_t dedxN;
+  Double_t cent, p, pt, mt, dca, tofsignal, tpcsignal, tpctofsignal;
+  Double_t dedx, bethe, deltadedx, dedx_sigma, ptpc;
+  Double_t time, time_sigma, timezero, timezero_sigma, tof, tof_sigma, texp, texp_sigma, deltat, deltat_sigma;
+
+  for (Int_t iev = startEv; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 100 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+
+    /*** ACCEPTED EVENT ***/
+
+    /* apply time-zero TOF correction */
+    analysisEvent->ApplyTimeZeroTOFCorrection();
+
+    /* get centrality */
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check accepted track (no DCA cut) */
+      if (!analysisTrack->AcceptTrack(kFALSE)) continue;
+      /* get charge */
+      charge = analysisTrack->GetSign() > 0. ? kPositive : kNegative;
+      /* check TPC pid */
+      if (!analysisTrack->HasTPCPID()) continue;
+      /* check TOF pid */
+      if (!analysisTrack->HasTOFPID()) continue;
+
+      /*** ACCEPTED TRACK WITH TPC+TOF PID ***/
+
+      /* get track info */
+      p = analysisTrack->GetP();
+      pt = analysisTrack->GetPt();
+      dca = analysisTrack->GetImpactParameter(0);
+
+      /* get TPC info */
+      dedx = analysisTrack->GetTPCdEdx();
+      dedxN = analysisTrack->GetTPCdEdxN();
+      ptpc = analysisTrack->GetTPCmomentum();
+      
+      /* apply expected time correction */
+      analysisTrack->ApplyTOFExpectedTimeCorrection();
+      
+      /* get TOF info */
+      time = analysisTrack->GetTOFTime();
+      time_sigma = tofReso;
+      timezero = analysisEvent->GetTimeZeroTOF(p);
+      timezero_sigma = analysisEvent->GetTimeZeroTOFSigma(p);
+      tof = time - timezero;
+      tof_sigma = TMath::Sqrt(time_sigma * time_sigma + timezero_sigma * timezero_sigma);
+      
+      /* loop over particle IDs */
+      for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+       
+       /* check rapidity */
+       if (TMath::Abs(analysisTrack->GetY(AliPID::ParticleMass(ipart))) > 0.5) continue;
+
+       /*** ACCEPTED TRACK WITHIN CORRECT RAPIDTY ***/
+       
+       /* TPC signal */
+       bethe = tpcResponse->GetExpectedSignal(ptpc, ipart);
+       deltadedx = dedx - bethe;
+       dedx_sigma = tpcResponse->GetExpectedSigma(ptpc, dedxN, ipart);
+       tpcsignal = deltadedx / dedx_sigma;
+       
+       /* TOF expected time */
+       texp = analysisTrack->GetTOFExpTime(ipart);
+       texp_sigma = analysisTrack->GetTOFExpTimeSigma(ipart);
+       
+       /* TOF signal */
+       deltat = tof - texp;
+       deltat_sigma = TMath::Sqrt(tof_sigma * tof_sigma + texp_sigma * texp_sigma);
+       tofsignal = deltat / deltat_sigma;
+       
+       /* TPC+TOF signal */
+       tpctofsignal = TMath::Sqrt(tpcsignal * tpcsignal + tofsignal * tofsignal);
+
+       /* check PID cuts */
+       if (tpctofsignal > 2.) continue;
+
+       /* fill histo */
+       hDCAopen[ipart][charge]->Fill(cent, pt, dca);
+
+       /* check accepted track (with DCA cut) */
+       if (!analysisTrack->AcceptTrack(kTRUE)) continue;
+
+       /* fill histo */
+       hDCAcut[ipart][charge]->Fill(cent, pt, dca);
+       
+      } /* end of loop over particle IDs */
+    } /* end of loop over tracks */
+  } /* end of loop over events */
+  
+  /* stop stopwatch */
+  timer.Stop();
+  timer.Print();
+  
+  /* output */
+  TFile *fileout = TFile::Open(Form("DCAdata.%s", filename), "RECREATE");
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hDCAopen[ipart][icharge]->Write();
+      hDCAcut[ipart][icharge]->Write();
+    }
+  }
+
+  fileout->Close();
+  
+}
+
+/**************************************************************/
+
+DCAmc(const Char_t *filename, Int_t evMax = kMaxInt, Int_t startEv = 0)
+{
+  
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* open enabled flag map */
+  //  TFile *enabledfile = TFile::Open(enabledChannelsFileName);
+  //  TH1F *hEnabledFlag = (TH1F *)enabledfile->Get("hEnabledFlag");
+
+  /**************************************************************/
+  /*** HISTOS ***************************************************/
+  /**************************************************************/
+
+  /* run-time binning */
+  for (Int_t ibin = 0; ibin < NdcaBins + 1; ibin++)
+    dcaBin[ibin] = dcaMin + ibin * dcaStep;
+  
+  /* histos */
+  TH3I *hDCAopen[kNMCHistos][AliPID::kSPECIES][kNCharges];
+  TH3I *hDCAcut[kNMCHistos][AliPID::kSPECIES][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNMCHistos; ihisto++ ) {
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       hDCAopen[ihisto][ipart][icharge] = new TH3I(Form("hDCAopen_%s_%s_%s", mchistoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]), "", NcentralityBins, centralityBin, NptBins, ptBin, NdcaBins, dcaBin);
+       hDCAcut[ihisto][ipart][icharge] = new TH3I(Form("hDCAcut_%s_%s_%s", mchistoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]), "", NcentralityBins, centralityBin, NptBins, ptBin, NdcaBins, dcaBin);
+      }
+    }
+  }
+  
+  /**************************************************************/
+  /**************************************************************/
+  /**************************************************************/
+
+  /* start stopwatch */
+  TStopwatch timer;
+  timer.Start();
+
+  /* loop over events */
+  Int_t part, charge, type;
+  Double_t cent, pt, mt, dca;
+
+  for (Int_t iev = startEv; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 100 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+
+    /*** ACCEPTED EVENT ***/
+
+    /* get centrality */
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check defined PID */
+      part = analysisTrack->GetMCPID();
+      if (part < 0 || analysisTrack->GetSign() == 0.) continue;
+      /* check accepted track (no DCA cut) */
+      if (!analysisTrack->AcceptTrack(kFALSE)) continue;
+      /* check rapidity */
+      if (TMath::Abs(analysisTrack->GetY(AliPID::ParticleMass(part))) > 0.5)
+       continue;
+
+      /*** ACCEPTED TRACK WITHIN CORRECT RAPIDTY ***/
+      
+      /* get track info */
+      pt = analysisTrack->GetPt();
+      dca = analysisTrack->GetImpactParameter(0);
+      charge = analysisTrack->GetMCCharge() > 0. ? kPositive : kNegative;
+      if (analysisTrack->IsMCPrimary())
+       type = kPrimary;
+      else if (analysisTrack->IsMCSecondaryWeakDecay())
+       type = kWeakDecay;
+      else if (analysisTrack->IsMCSecondaryMaterial())
+       type = kMaterial;
+      else
+       continue;
+
+      /* fill histo */
+      hDCAopen[type][part][charge]->Fill(cent, pt, dca);
+      
+      /* check accepted track (with DCA cut) */
+      if (!analysisTrack->AcceptTrack(kTRUE)) continue;
+      
+      /* fill histo */
+      hDCAcut[type][part][charge]->Fill(cent, pt, dca);
+      
+    } /* end of loop over tracks */
+  } /* end of loop over events */
+  
+  /* stop stopwatch */
+  timer.Stop();
+  timer.Print();
+  
+  /* output */
+  TFile *fileout = TFile::Open(Form("DCAmc.%s", filename), "RECREATE");
+  for (Int_t ihisto = 0; ihisto < kNMCHistos; ihisto++) {
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       hDCAopen[ihisto][ipart][icharge]->Write();
+       hDCAcut[ihisto][ipart][icharge]->Write();
+      }
+    }
+  }
+
+  fileout->Close();
+  
+}
+
+/**************************************************************/
+
+enum EFitParams_t {
+  kIntegralCounts,
+  kPrimaryCounts,
+  kWeakDecayCounts,
+  kMaterialCounts,
+  kPrimaryIntegral,
+  kWeakDecayIntegral,
+  kMaterialIntegral,
+  kDataCutIntegral,
+  kPrimaryCutIntegral,
+  kWeakDecayCutIntegral,
+  kMaterialCutIntegral,
+  kNFitParams
+};
+
+/* fit output params name */
+const Char_t *fitParamName[kNFitParams] = {
+  "IntegralCounts",
+  "PrimaryCounts",
+  "WeakDecayCounts",
+  "MaterialCounts",
+  "PrimaryIntegral",
+  "WeakDecayIntegral",
+  "MaterialIntegral",
+  "DataCutIntegral",
+  "PrimaryCutIntegral",
+  "WeakDecayCutIntegral",
+  "MaterialCutIntegral"
+};
+
+/* fit output params title */
+const Char_t *fitParamTitle[kNFitParams] = {
+  "Integral counts;p_{T} (GeV/c);",
+  "Primary counts;p_{T} (GeV/c);",
+  "Weak-decay counts;p_{T} (GeV/c);",
+  "Material counts;p_{T} (GeV/c);",
+  "Primary integral;p_{T} (GeV/c);",
+  "Weak-decay integral;p_{T} (GeV/c);",
+  "Material integral;p_{T} (GeV/c);",
+  "Data cut integral;p_{T} (GeV/c);",
+  "Primary cut integral;p_{T} (GeV/c);",
+  "Weak-decay cut integral;p_{T} (GeV/c);",
+  "Material cut integral;p_{T} (GeV/c);"
+};
+
+/* fit ranges */
+Double_t fitPtMin[AliPID::kSPECIES] = {0.5, 0.5, 0.3, 0.4, 0.5};
+Double_t fitPtMax[AliPID::kSPECIES] = {2.0, 2.0, 2.0, 2.0, 3.0};
+
+/* rebin DCA */
+Int_t rebindca = 10;
+
+DCAdeltafeed(const Char_t *datafilename, const Char_t *mcfilename)
+{
+  for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+    DCAdeltafeed(datafilename, mcfilename, 2, icharge, -1);
+    DCAdeltafeed(datafilename, mcfilename, 4, icharge, -1);
+    for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+      DCAdeltafeed(datafilename, mcfilename, 2, icharge, icent);
+      DCAdeltafeed(datafilename, mcfilename, 4, icharge, icent);
+    }
+  }
+}
+
+DCAdeltafeed(const Char_t *datafilename, const Char_t *mcfilename, Int_t ipart, Int_t icharge, Int_t icent, Float_t ptMin = -1., Float_t ptMax = -1., Bool_t checkHistoFlag = kFALSE)
+{
+
+  printf("****************************************\n");
+  printf("RUNNING DCA FIT:\n");
+  printf("RAPIDITY-CUT:   %s\n", AliPID::ParticleName(ipart));
+  printf("CHARGE:         %s\n", chargeName[icharge]);
+  printf("PARTICLE:       %s\n", AliPID::ParticleName(ipart));
+  printf("CENTRALITY BIN: %d\n", icent);
+  printf("****************************************\n");
+
+  /* open data */
+  TFile *datafilein = TFile::Open(datafilename);
+  TFile *mcfilein = TFile::Open(mcfilename);
+
+  /* get histos */
+  TH3I *hDCAopen = (TH3I *)datafilein->Get(Form("hDCAopen_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+  TH3I *hDCAopen_primary = (TH3I *)mcfilein->Get(Form("hDCAopen_primary_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+  TH3I *hDCAopen_weakdecay = (TH3I *)mcfilein->Get(Form("hDCAopen_weakdecay_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+  TH3I *hDCAopen_material = (TH3I *)mcfilein->Get(Form("hDCAopen_material_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+  TH3I *hDCAcut = (TH3I *)datafilein->Get(Form("hDCAcut_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+  TH3I *hDCAcut_primary = (TH3I *)mcfilein->Get(Form("hDCAcut_primary_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+  TH3I *hDCAcut_weakdecay = (TH3I *)mcfilein->Get(Form("hDCAcut_weakdecay_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+  TH3I *hDCAcut_material = (TH3I *)mcfilein->Get(Form("hDCAcut_material_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+
+  /* setup centrality range */
+  if (icent < 0 || icent >= NcentralityBins) {
+    printf("WARNING: undefined centrality -> using 00-90\% range\n");
+    hDCAopen->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAopen_primary->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAopen_weakdecay->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAopen_material->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAcut->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAcut_primary->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAcut_weakdecay->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAcut_material->GetXaxis()->SetRange(1, NcentralityBins);
+  }
+  else {
+    printf("***** FITTING CENTRALITY-BIN [%02d, %02d] %% *****\n", centralityBin[icent], centralityBin[icent + 1]);
+    hDCAopen->GetXaxis()->SetRange(icent + 1, icent + 1);
+#if 0
+    hDCAopen_primary->GetXaxis()->SetRange(icent + 1, icent + 1);
+    hDCAopen_weakdecay->GetXaxis()->SetRange(icent + 1, icent + 1);
+    hDCAopen_material->GetXaxis()->SetRange(icent + 1, icent + 1);
+#else
+    hDCAopen_primary->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAopen_weakdecay->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAopen_material->GetXaxis()->SetRange(1, NcentralityBins);
+#endif
+    hDCAcut->GetXaxis()->SetRange(icent + 1, icent + 1);
+#if 0
+    hDCAcut_primary->GetXaxis()->SetRange(icent + 1, icent + 1);
+    hDCAcut_weakdecay->GetXaxis()->SetRange(icent + 1, icent + 1);
+    hDCAcut_material->GetXaxis()->SetRange(icent + 1, icent + 1);
+#else
+    hDCAcut_primary->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAcut_weakdecay->GetXaxis()->SetRange(1, NcentralityBins);
+    hDCAcut_material->GetXaxis()->SetRange(1, NcentralityBins);
+#endif
+  }
+
+  /* setup pt range */
+  Bool_t requestedRange = kFALSE;
+  if (ptMin > -0.001 && ptMax > -0.001 && ptMax > ptMin) {
+    printf("***** FITTING PT-BIN [%f, %f] GeV/c *****\n", ptMin, ptMax);
+    requestedRange = kTRUE;
+    hDCAopen->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hDCAopen_primary->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hDCAopen_weakdecay->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hDCAopen_material->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hDCAcut->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hDCAcut_primary->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hDCAcut_weakdecay->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hDCAcut_material->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+  }
+
+  /* output */
+  Char_t outfilename[1024];
+  if (icent < 0 || icent >= NcentralityBins)
+    sprintf(outfilename, "DCAdeltafeed_cent0090_%s_%s.root", AliPID::ParticleName(ipart), chargeName[icharge]);
+  else {
+    sprintf(outfilename, "DCAdeltafeed_cent%02d%02d_%s_%s.root", centralityBin[icent], centralityBin[icent + 1], AliPID::ParticleName(ipart), chargeName[icharge]);
+  }
+  TFile *fileout = TFile::Open(outfilename, "RECREATE");
+  TDirectory *fitDir = fileout->mkdir("FitParams");
+  /* canvas */
+  TCanvas *canvas = new TCanvas("canvas");
+  canvas->SetLogy();
+  /* histo */
+  TH1D *hFitParamHisto[kNFitParams];
+  for (Int_t iparam = 0; iparam < kNFitParams; iparam++)
+    hFitParamHisto[iparam] = new TH1D(Form("h%s", fitParamName[iparam]), fitParamTitle[iparam], NptBins, ptBin);
+
+
+  /* loop over ptBins */
+  for (Int_t ipt = 0; ipt < NptBins; ipt++) {
+    
+    if (!requestedRange) {
+      if ((ptBin[ipt] + 0.001) < fitPtMin[ipart] || (ptBin[ipt + 1] - 0.001) > fitPtMax[ipart]) continue;
+      printf("***** FITTING PT-BIN [%f, %f] GeV/c *****\n", ptBin[ipt], ptBin[ipt + 1]);
+      hDCAopen->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hDCAopen_primary->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hDCAopen_weakdecay->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hDCAopen_material->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hDCAcut->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hDCAcut_primary->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hDCAcut_weakdecay->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hDCAcut_material->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+    }
+    
+    /* dca projections */
+    TH1 *hDCAopen_py = hDCAopen->Project3D("z");
+    TH1 *hDCAopen_primary_py = hDCAopen_primary->Project3D("z");
+    TH1 *hDCAopen_weakdecay_py = hDCAopen_weakdecay->Project3D("z");
+    TH1 *hDCAopen_material_py = hDCAopen_material->Project3D("z");
+    TH1 *hDCAcut_py = hDCAcut->Project3D("z");
+    TH1 *hDCAcut_primary_py = hDCAcut_primary->Project3D("z");
+    TH1 *hDCAcut_weakdecay_py = hDCAcut_weakdecay->Project3D("z");
+    TH1 *hDCAcut_material_py = hDCAcut_material->Project3D("z");
+
+    /* rebin */
+    hDCAopen_py->Rebin(rebindca);
+    hDCAopen_primary_py->Rebin(rebindca);
+    hDCAopen_weakdecay_py->Rebin(rebindca);
+    hDCAopen_material_py->Rebin(rebindca);
+    hDCAcut_py->Rebin(rebindca);
+    hDCAcut_primary_py->Rebin(rebindca);
+    hDCAcut_weakdecay_py->Rebin(rebindca);
+    hDCAcut_material_py->Rebin(rebindca);
+
+    /* check histos if requested */
+    if (checkHistoFlag) {
+      TCanvas *cCheckHisto = new TCanvas("cCheckHisto");
+      cCheckHisto->Divide(2, 4);
+      cCheckHisto->cd(1);
+      hDCAopen_py->Draw();
+      cCheckHisto->cd(2);
+      hDCAcut_py->Draw();
+      cCheckHisto->cd(3);
+      hDCAopen_primary_py->Draw();
+      cCheckHisto->cd(4);
+      hDCAcut_primary_py->Draw();
+      cCheckHisto->cd(5);
+      hDCAopen_weakdecay_py->Draw();
+      cCheckHisto->cd(6);
+      hDCAcut_weakdecay_py->Draw();
+      cCheckHisto->cd(7);
+      hDCAopen_material_py->Draw();
+      cCheckHisto->cd(8);
+      hDCAcut_material_py->Draw();
+      return;
+    }
+
+    Double_t param[kNFitParams];
+    Double_t param_err[kNFitParams];
+
+    param[kPrimaryIntegral] = hDCAopen_primary_py->Integral();
+    param_err[kPrimaryIntegral] = TMath::Sqrt(hDCAopen_primary_py->Integral());
+    param[kWeakDecayIntegral] = hDCAopen_weakdecay_py->Integral();
+    param_err[kWeakDecayIntegral] = TMath::Sqrt(hDCAopen_weakdecay_py->Integral());
+    param[kMaterialIntegral] = hDCAopen_material_py->Integral();
+    param_err[kMaterialIntegral] = TMath::Sqrt(hDCAopen_material_py->Integral());
+    
+    param[kDataCutIntegral] = hDCAcut_py->Integral();
+    param_err[kDataCutIntegral] = TMath::Sqrt(hDCAcut_py->Integral());
+    param[kPrimaryCutIntegral] = hDCAcut_primary_py->Integral();
+    param_err[kPrimaryCutIntegral] = TMath::Sqrt(hDCAcut_primary_py->Integral());
+    param[kWeakDecayCutIntegral] = hDCAcut_weakdecay_py->Integral();
+    param_err[kWeakDecayCutIntegral] = TMath::Sqrt(hDCAcut_weakdecay_py->Integral());
+    param[kMaterialCutIntegral] = hDCAcut_material_py->Integral();
+    param_err[kMaterialCutIntegral] = TMath::Sqrt(hDCAcut_material_py->Integral());
+
+    /* fit */
+    DCAfit(hDCAopen_py, hDCAopen_primary_py, hDCAopen_weakdecay_py, hDCAopen_material_py, param, param_err, canvas);
+
+    
+    /* check requested pt-range */
+    if (requestedRange)
+      return;
+
+    /* write canvas */
+    fitDir->cd();
+    canvas->Write(Form("fitDisplay_ptBin_%3.2f_%3.2f", ptBin[ipt], ptBin[ipt + 1]));
+    
+    /* set histo */
+    for (Int_t iparam = 0; iparam < kNFitParams; iparam++) {
+      hFitParamHisto[iparam]->SetBinContent(ipt + 1, param[iparam]);
+      hFitParamHisto[iparam]->SetBinError(ipt + 1, param_err[iparam]);
+    }
+
+    /* delete */
+    delete hDCAopen_py;
+    delete hDCAopen_primary_py;
+    delete hDCAopen_weakdecay_py;
+    delete hDCAopen_material_py;
+    delete hDCAcut_py;
+    delete hDCAcut_primary_py;
+    delete hDCAcut_weakdecay_py;
+    delete hDCAcut_material_py;
+
+  }
+
+  /* check requested pt-range */
+  if (requestedRange)
+    return;
+
+  /*** POST-ANALYSIS ***/
+
+  TDirectory *postDir = fileout->mkdir("PostAnalysis");
+  /* compute fractions */
+  TH1D *hPrimaryFraction = new TH1D(*hFitParamHisto[kPrimaryCounts]);
+  hPrimaryFraction->Divide(hFitParamHisto[kPrimaryCounts], hFitParamHisto[kIntegralCounts], 1., 1., "B");
+  TH1D *hWeakDecayFraction = new TH1D(*hFitParamHisto[kWeakDecayCounts]);
+  hWeakDecayFraction->Divide(hFitParamHisto[kWeakDecayCounts], hFitParamHisto[kIntegralCounts], 1., 1., "B");
+  TH1D *hMaterialFraction = new TH1D(*hFitParamHisto[kMaterialCounts]);
+  hMaterialFraction->Divide(hFitParamHisto[kMaterialCounts], hFitParamHisto[kIntegralCounts], 1., 1., "B");
+
+  /* compute scale factors */
+  TH1D *hPrimaryScale = new TH1D(*hFitParamHisto[kPrimaryCounts]);
+  hPrimaryScale->Divide(hFitParamHisto[kPrimaryCounts], hFitParamHisto[kPrimaryIntegral], 1., 1., "B");
+  TH1D *hWeakDecayScale = new TH1D(*hFitParamHisto[kWeakDecayCounts]);
+  hWeakDecayScale->Divide(hFitParamHisto[kWeakDecayCounts], hFitParamHisto[kWeakDecayIntegral], 1., 1., "B");
+  TH1D *hMaterialScale = new TH1D(*hFitParamHisto[kMaterialCounts]);
+  hMaterialScale->Divide(hFitParamHisto[kMaterialCounts], hFitParamHisto[kMaterialIntegral], 1., 1., "B");
+
+  /* compute cut integrals */
+  TH1D *hPrimaryCutIntegral = new TH1D(*hFitParamHisto[kPrimaryCutIntegral]);
+  hPrimaryCutIntegral->Multiply(hPrimaryScale);
+  TH1D *hWeakDecayCutIntegral = new TH1D(*hFitParamHisto[kWeakDecayCutIntegral]);
+  hWeakDecayCutIntegral->Multiply(hWeakDecayScale);
+  TH1D *hMaterialCutIntegral = new TH1D(*hFitParamHisto[kMaterialCutIntegral]);
+  hMaterialCutIntegral->Multiply(hMaterialScale);
+
+  /* compute cut fractions */
+  TH1D *hPrimaryCutFraction = new TH1D(*hPrimaryCutIntegral);
+  hPrimaryCutFraction->Divide(hPrimaryCutIntegral, hFitParamHisto[kDataCutIntegral], 1., 1., "B");
+  TH1D *hWeakDecayCutFraction = new TH1D(*hWeakDecayCutIntegral);
+  hWeakDecayCutFraction->Divide(hWeakDecayCutIntegral, hFitParamHisto[kDataCutIntegral], 1., 1., "B");
+  TH1D *hMaterialCutFraction = new TH1D(*hMaterialCutIntegral);
+  hMaterialCutFraction->Divide(hMaterialCutIntegral, hFitParamHisto[kDataCutIntegral], 1., 1., "B");
+
+
+  /*** OUTPUT ***/
+
+  /* write fir params histos */
+  fitDir->cd();
+  for (Int_t iparam = 0; iparam < kNFitParams; iparam++)
+    hFitParamHisto[iparam]->Write();
+  /* write post-analysis histos */
+  postDir->cd();
+  hPrimaryFraction->Write("hPrimaryFraction");
+  hWeakDecayFraction->Write("hWeakDecayFraction");
+  hMaterialFraction->Write("hMaterialFraction");
+  hPrimaryCutFraction->Write("hPrimaryCutFraction");
+  hWeakDecayCutFraction->Write("hWeakDecayCutFraction");
+  hMaterialCutFraction->Write("hMaterialCutFraction");
+
+  /* cleanup */
+  delete hPrimaryFraction;
+  delete hWeakDecayFraction;
+  delete hMaterialFraction;
+  delete hPrimaryScale;
+  delete hWeakDecayScale;
+  delete hMaterialScale;
+  delete hPrimaryCutIntegral;
+  delete hWeakDecayCutIntegral;
+  delete hMaterialCutIntegral;
+  delete hPrimaryCutFraction;
+  delete hWeakDecayCutFraction;
+  delete hMaterialCutFraction;
+  delete canvas;
+  for (Int_t iparam = 0; iparam < kNFitParams; iparam++)
+    delete hFitParamHisto[iparam];
+
+  /* close file */
+  fileout->Close();
+
+
+}
+
+/**************************************************************/
+
+//___________________________________________________________________________________
+
+Float_t 
+TOFpid_histomin(TH1 *h)
+{
+
+  for (Int_t ibin = 0; ibin < h->GetNbinsX(); ibin++)
+    if (h->GetBinContent(ibin + 1) > 0.)
+      return h->GetXaxis()->GetBinCenter(ibin + 1);
+  return kMaxInt;
+}
+
+//___________________________________________________________________________________
+
+Float_t 
+TOFpid_histomax(TH1 *h)
+{
+
+  for (Int_t ibin = h->GetNbinsX(); ibin > 0; ibin--)
+    if (h->GetBinContent(ibin) > 0.)
+      return h->GetXaxis()->GetBinCenter(ibin);
+  return -kMaxInt;
+}
+
+//___________________________________________________________________________________
+
+TOFpid_checkneg(TH1 *h)
+{
+
+  for (Int_t ibin = 0; ibin < h->GetNbinsX(); ibin++)
+    if (h->GetBinContent(ibin + 1) <= 0.) {
+      h->SetBinContent(ibin + 1, 1.e-300);
+      //      h->SetBinError(ibin + 1, 0.1);
+    }
+}
+
+
+Double_t
+DCAfit(TH1 *hData, TH1 *hPrimary, TH1 *hWeakDecay, TH1 *hMaterial, Double_t *param = NULL, Double_t *param_err = NULL, TCanvas *canvas = NULL)
+{
+
+  /** ROOFIT ***/
+  gSystem->Load("libRooFit");
+  using namespace RooFit;
+
+  /*** DEFINE FIT RANGE ***/
+
+  printf("***** FIT RANGE DEFINITION *****\n");
+
+  /* check material histogram to define min/max fit range */
+  Double_t rangeMin = TMath::Max(dcaMin, TOFpid_histomin(hMaterial));
+  Double_t rangeMax = TMath::Min(dcaMax, TOFpid_histomax(hMaterial));
+  /* fix zeroes */
+  TOFpid_checkneg(hMaterial);
+
+  /* define range */
+  RooRealVar x("x", "DCA_{xy}", 0., -5., 5., "");
+  printf("FIT RANGE DEFINED: %f -> %f\n", dcaMin, dcaMax);
+  printf("********************************\n");
+
+  /*** DEFINE HISTOGRAM DATA ***/
+  
+  /* define data to fit and background from input histogram */
+  RooDataHist hdata("hdata", "hdata", x, hData);
+  RooDataHist hprimary("hprimary", "hprimary", x, hPrimary);
+  RooDataHist hweakdecay("hweakdecay", "hweakdecay", x, hWeakDecay);
+  RooDataHist hmaterial("hmaterial", "hmaterial", x, hMaterial);
+
+  /*** DEFINE SHAPES ***/
+
+  RooHistPdf primary("primary", "primary", x, hprimary);
+  RooHistPdf weakdecay("weakdecay", "weakdecay", x, hweakdecay);
+  RooHistPdf material("material", "material", x, hmaterial);
+
+  /*** DEFINE MODEL ***/
+
+  Double_t integral = hdata.sumEntries();
+  RooRealVar nprimary("nprimary", "nprimary", 0.80 * integral, 0., integral);
+  RooRealVar nweakdecay("nweakdecay", "nweakdecay", 0.1 * integral, 0., integral);
+  RooRealVar nmaterial("nmaterial", "nmaterial", 0.1 * integral, 0., integral);
+
+  RooAddPdf model("model", "model p.d.f.", RooArgList(primary, weakdecay, material), RooArgList(nprimary, nweakdecay, nmaterial));
+
+  /*** FIT ***/
+
+  if (canvas) canvas->cd();
+  model.fitTo(hdata, Extended(kTRUE), SumW2Error(kFALSE));
+
+  /*** DRAW ***/
+
+  RooPlot *xframe = x.frame();
+  hdata.plotOn(xframe, XErrorSize(0), DrawOption("PZ"));
+  model.plotOn(xframe, LineWidth(2), Precision(1.e-4));
+  model.plotOn(xframe, Components(primary), LineWidth(2), LineColor(kRed), Precision(1.e-4));
+  model.plotOn(xframe, Components(weakdecay), LineWidth(2), LineStyle(kDashed), LineColor(kCyan+1));
+  model.plotOn(xframe, Components(material), LineWidth(2), LineStyle(kDashed), LineColor(kGreen+1));
+  xframe->SetMinimum(0.1);
+  xframe->Draw();
+  if (canvas) canvas->Update();
+
+  printf("*****************************\n");
+  printf("***** FRACTIONS *****\n");
+  printf("primary     = %f +- %f\n", nprimary.getVal(), nprimary.getError());
+  printf("weak-decay  = %f +- %f\n", nweakdecay.getVal(), nweakdecay.getError());
+  printf("material    = %f +- %f\n", nmaterial.getVal(), nmaterial.getError());
+  printf("******************\n");
+
+  /*** OUTPUT FIT PARAMS ***/
+  
+  param[kIntegralCounts] = integral;
+  param_err[kIntegralCounts] = sqrt(integral);
+  param[kPrimaryCounts] = nprimary.getVal();
+  param_err[kPrimaryCounts] = nprimary.getError();
+  param[kWeakDecayCounts] = nweakdecay.getVal();
+  param_err[kWeakDecayCounts] = nweakdecay.getError();
+  param[kMaterialCounts] = nmaterial.getVal();
+  param_err[kMaterialCounts] = nmaterial.getError();
+
+  return;
+
+}
+
+enum EFitFunc_t {
+  kExpo,
+  kInverseExpo,
+  kPowerLaw,
+  kInversePowerLaw,
+  kExpoPowerLaw
+};
+
+DCAdeltafeed_param()
+{
+#if 0
+  DCAdeltafeed_param(2, 0, "WeakDecayCutFraction", kExpo);
+  DCAdeltafeed_param(2, 1, "WeakDecayCutFraction", kExpo);
+  DCAdeltafeed_param(4, 0, "WeakDecayCutFraction", kExpo);
+  DCAdeltafeed_param(4, 1, "WeakDecayCutFraction", kExpo);
+  DCAdeltafeed_param(2, 0, "MaterialCutFraction", kPowerLaw);
+  DCAdeltafeed_param(2, 1, "MaterialCutFraction", kPowerLaw);
+  DCAdeltafeed_param(4, 0, "MaterialCutFraction", kPowerLaw);
+  DCAdeltafeed_param(4, 1, "MaterialCutFraction", kPowerLaw);
+#endif
+  DCAdeltafeed_param_bothcharges(2, 0, "PrimaryCutFraction", kInverseExpo);
+  DCAdeltafeed_param_bothcharges(2, 1, "PrimaryCutFraction", kInverseExpo);
+  DCAdeltafeed_param_bothcharges(4, 0, "PrimaryCutFraction", kInverseExpo);
+  DCAdeltafeed_param_bothcharges(4, 1, "PrimaryCutFraction", kInverseExpo);
+}
+
+DCAdeltafeed_param_bothcharges(Int_t ipart, Int_t icharge, const Char_t *name, Int_t fitFunc)
+{
+
+  TVirtualFitter::SetMaxIterations(1000000);
+  
+  /* load HistoUtils */
+  gROOT->LoadMacro("HistoUtils.C");
+
+  Char_t outfilename[1024];
+  TH1D *hDeltaFeed_mb[kNCharges];
+  TH1D *hDeltaFeed_cent[kNCharges][NcentralityBins];
+  for (Int_t iicharge = 0; iicharge < kNCharges; iicharge++) {
+
+    /* get minimum-bias results */
+    sprintf(outfilename, "DCAdeltafeed_cent0090_%s_%s.root", AliPID::ParticleName(ipart), chargeName[iicharge]);
+    TFile *filein = TFile::Open(outfilename);
+    hDeltaFeed_mb[iicharge] = (TH1D *)filein->Get(Form("PostAnalysis/h%s", name));
+    if (!hDeltaFeed_mb[iicharge]) {
+      printf("cannot find PostAnalysis/h%s in %s\n", name, outfilename);
+      return;
+    }
+
+    /* get centrality-binned results */
+    for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+      sprintf(outfilename, "DCAdeltafeed_cent%02d%02d_%s_%s.root", centralityBin[icent], centralityBin[icent + 1], AliPID::ParticleName(ipart), chargeName[iicharge]);
+      filein = TFile::Open(outfilename);
+      if (!filein || !filein->IsOpen()) continue;
+      hDeltaFeed_cent[iicharge][icent] = (TH1D *)filein->Get(Form("PostAnalysis/h%s", name));
+      if (!hDeltaFeed_cent[iicharge][icent]) {
+       printf("cannot find PostAnalysis/h%s in %s\n", name, outfilename);
+       return;
+      }
+    }
+  }
+
+  /* define delta feed-down function */
+  switch (fitFunc) {
+  case kExpo:
+    printf("expo function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_expo", "[0] * ([1] + [2] * TMath::Exp([3] * x))", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 0.01);
+    fDeltaFeed->SetParLimits(1, 0., 0.1);
+    fDeltaFeed->SetParameter(2, 0.1);
+    fDeltaFeed->SetParameter(3, -1.);
+    break;
+  case kInverseExpo:
+    printf("inverse-expo function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_expo", "[0] * ([1] + [2] * TMath::Exp([3] * x))", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 1.);
+    fDeltaFeed->SetParLimits(1, 0.9, 1.0);
+    fDeltaFeed->SetParameter(2, -0.1);
+    fDeltaFeed->SetParLimits(2, -1., 0.);
+    fDeltaFeed->SetParameter(3, -1.);
+    break;
+  case kPowerLaw:
+    printf("powerlaw function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_powerlaw", "[0] * ([1] + [2] * TMath::Power(x, [3]))", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 0.01);
+    fDeltaFeed->SetParLimits(1, 0., 0.1);
+    fDeltaFeed->SetParameter(2, 0.1);
+    fDeltaFeed->SetParameter(3, -1.);
+    break;
+  case kInversePowerLaw:
+    printf("inverse-powerlaw function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_powerlaw", "[0] * ([1] + [2] * TMath::Power(x, [3]) + [4] * x)", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 1.);
+    fDeltaFeed->SetParLimits(1, 0.9, 1.);
+    fDeltaFeed->SetParameter(2, -0.1);
+    fDeltaFeed->SetParameter(3, -1.);
+    fDeltaFeed->SetParameter(4, 0.);
+    fDeltaFeed->SetParLimits(4, 0., 1.)
+    break;
+  case kExpoPowerLaw:
+    printf("expo+powerlaw function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_expopowerlaw", "[0] * ([1] + [2] * TMath::Exp([3] * x) + [4] * TMath::Exp([5] * x))", 0.5, 5.);
+
+    fDeltaFeed->SetParameter(1, 0.95);
+    fDeltaFeed->SetParLimits(1, 0.9, 1.);
+    fDeltaFeed->SetParameter(2, -0.1);
+    fDeltaFeed->SetParLimits(2, -1000., 0.);
+    fDeltaFeed->SetParameter(3, -1.);
+    fDeltaFeed->SetParameter(4, -100.);
+    fDeltaFeed->SetParLimits(4, -100., 0.);
+    fDeltaFeed->SetParameter(5, -20.);
+    fDeltaFeed->SetParLimits(5, -100., 10.);
+    break;
+  default:
+    printf("fit function not defined\n");
+    return;
+    break;
+  }
+  fDeltaFeed->FixParameter(0, 1.);
+
+  /* output */
+  TFile *fileout = TFile::Open(Form("DCAdeltafeed_param_%s_%s_%s.root", name, AliPID::ParticleName(ipart), chargeName[icharge]), "RECREATE");
+
+  /* extra-material function */
+  TF1 *fExtraMaterial = new TF1("fExtraMaterial", "1. + [0] * TMath::Exp([1] * x)", 0., 5.);
+  fExtraMaterial->SetParameter(0, 0.1);
+  fExtraMaterial->SetParameter(1, -0.5);
+
+  /* loop over centrality bins */
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+
+    /* fit material from proton-antiproton ratio and remove it */
+    if (ipart == AliPID::kProton) {
+      printf("fitting extra-material for positive protons\n");
+      TH1D *hr = new TH1D(*hDeltaFeed_cent[kPositive][icent]);
+      hr->Divide(hDeltaFeed_cent[kNegative][icent]);
+      hr->Fit(fExtraMaterial, "R", "", fitPtMin[ipart], fitPtMax[ipart]);
+      hDeltaFeed_cent[kPositive][icent]->Divide(fExtraMaterial);
+    }
+   
+    /* build graph with both charges */
+    TGraphErrors *gDeltaFeed = new TGraphErrors();
+    Int_t npoints = 0;
+    Double_t pt, pte, val, vale;
+    for (Int_t iicharge = 0; iicharge < kNCharges; iicharge++) {
+      for (Int_t ipt = 0; ipt < NptBins; ipt++) {
+       if (hDeltaFeed_cent[iicharge][icent]->GetBinError(ipt + 1) == 0.)
+         continue;
+       pt = hDeltaFeed_cent[iicharge][icent]->GetBinCenter(ipt + 1);
+       pte = 0.5 * hDeltaFeed_cent[iicharge][icent]->GetBinWidth(ipt + 1);
+       val = hDeltaFeed_cent[iicharge][icent]->GetBinContent(ipt + 1);
+       vale = hDeltaFeed_cent[iicharge][icent]->GetBinError(ipt + 1);
+       gDeltaFeed->SetPoint(npoints, pt, val);
+       gDeltaFeed->SetPointError(npoints, pte, vale);
+       npoints++;
+      }
+    }
+
+    /* fit graph */
+    Int_t fitres = -1;
+    fitres = gDeltaFeed->Fit(fDeltaFeed, "R", "", 0.5, 2.0);
+    if (fitres != 0) {
+      fDeltaFeed->SetParLimits(1, 0.9, 1.0);
+      fDeltaFeed->SetParameter(2, -0.1);
+      fDeltaFeed->SetParLimits(2, -1., 0.);
+      fDeltaFeed->SetParameter(3, -1.);
+    }
+    fitres = -1;
+    while(fitres != 0)
+      fitres = gDeltaFeed->Fit(fDeltaFeed, "R", "", fitPtMin[ipart], fitPtMax[ipart]);
+    
+    gDeltaFeed->Draw("ap*");
+    fDeltaFeed->Draw("same");
+    gPad->Update();
+    
+    printf("done part = %d, charge = %d, cent = %d\n", ipart, icharge, icent);
+
+    /* build fit profile */
+    TProfile *pDeltaFeed = new TProfile("pDeltaFeed", "", NptBins, ptBin);
+    HistoUtils_Function2Profile(fDeltaFeed, pDeltaFeed);
+
+    /* put material back */
+    if (ipart == AliPID::kProton && icharge == kPositive) {
+      hDeltaFeed_cent[kPositive][icent]->Multiply(fExtraMaterial);
+      pDeltaFeed->Multiply(fExtraMaterial);
+    }
+    
+    /* write */
+    fileout->cd();
+    hDeltaFeed_cent[icharge][icent]->Write(Form("hDeltaFeed_cent%d", icent));
+    fDeltaFeed->Write(Form("fDeltaFeed_cent%d", icent));
+    pDeltaFeed->Write(Form("pDeltaFeed_cent%d", icent));
+    fExtraMaterial->Write(Form("fExtraMaterial_cent%d", icent));
+  }
+  
+  fileout->Close();
+}
+
+DCAdeltafeed_param(Int_t ipart, Int_t icharge, const Char_t *name, Int_t fitFunc)
+{
+
+  TVirtualFitter::SetMaxIterations(1000000);
+
+  /* load HistoUtils */
+  gROOT->LoadMacro("HistoUtils.C");
+  
+  /* get minimum-bias results */
+  Char_t outfilename[1024];
+  sprintf(outfilename, "DCAdeltafeed_cent0090_%s_%s.root", AliPID::ParticleName(ipart), chargeName[icharge]);
+  TFile *filein = TFile::Open(outfilename);
+  TH1D *hDeltaFeed_mb = (TH1D *)filein->Get(Form("PostAnalysis/h%s", name));
+  if (!hDeltaFeed_mb) {
+    printf("cannot find PostAnalysis/h%s in %s\n", name, outfilename);
+    return;
+  }
+
+  /* get centrality-binned results */
+  TH1D *hDeltaFeed_cent[NcentralityBins];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    sprintf(outfilename, "DCAdeltafeed_cent%02d%02d_%s_%s.root", centralityBin[icent], centralityBin[icent + 1], AliPID::ParticleName(ipart), chargeName[icharge]);
+    filein = TFile::Open(outfilename);
+    if (!filein || !filein->IsOpen()) continue;
+    hDeltaFeed_cent[icent] = (TH1D *)filein->Get(Form("PostAnalysis/h%s", name));
+    if (!hDeltaFeed_cent[icent]) {
+      printf("cannot find PostAnalysis/h%s in %s\n", name, outfilename);
+      return;
+    }
+  }
+  /* define delta feed-down function */
+  switch (fitFunc) {
+  case kExpo:
+    printf("expo function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_expo", "[0] * ([1] + [2] * TMath::Exp([3] * x))", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 0.01);
+    fDeltaFeed->SetParLimits(1, 0., 0.1);
+    fDeltaFeed->SetParameter(2, 0.1);
+    fDeltaFeed->SetParameter(3, -1.);
+    break;
+  case kInverseExpo:
+    printf("inverse-expo function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_expo", "[0] * ([1] + [2] * TMath::Exp([3] * x))", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 1.);
+    fDeltaFeed->SetParLimits(1, 0.9, 1.0);
+    fDeltaFeed->SetParameter(2, -0.1);
+    fDeltaFeed->SetParameter(3, -1.);
+    break;
+  case kPowerLaw:
+    printf("powerlaw function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_powerlaw", "[0] * ([1] + [2] * TMath::Power(x, [3]))", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 0.01);
+    fDeltaFeed->SetParLimits(1, 0., 0.1);
+    fDeltaFeed->SetParameter(2, 0.1);
+    fDeltaFeed->SetParameter(3, -1.);
+    break;
+  case kInversePowerLaw:
+    printf("inverse-powerlaw function selected\n");
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_powerlaw", "[0] * ([1] + [2] * TMath::Power(x, [3]) + [4] * x)", 0.5, 5.);
+    fDeltaFeed->SetParameter(1, 1.);
+    fDeltaFeed->SetParLimits(1, 0.9, 1.);
+    fDeltaFeed->SetParameter(2, -0.1);
+    fDeltaFeed->SetParameter(3, -1.);
+    fDeltaFeed->SetParameter(4, 0.);
+    fDeltaFeed->SetParLimits(4, 0., 1.)
+    break;
+  case kExpoPowerLaw:
+    printf("expo+powerlaw function selected\n");
+    //    TF1 *fDeltaFeed = new TF1("fDeltaFeed_expopowerlaw", "[0] * ([1] + [2] * TMath::Exp([3] * x) + [4] * TMath::Exp([5] * x))", 0.5, 5.);
+    TF1 *fDeltaFeed = new TF1("fDeltaFeed_expopowerlaw", "[0] * ([1] + [2] * TMath::Exp([3] * x) * TMath::Exp([5] / x))", 0.5, 5.);
+
+    fDeltaFeed->SetParameter(1, 0.95);
+    fDeltaFeed->SetParLimits(1, 0.9, 1.);
+    fDeltaFeed->SetParameter(2, -0.1);
+    fDeltaFeed->SetParLimits(2, -1000., 0.);
+    fDeltaFeed->SetParameter(3, -1.);
+    fDeltaFeed->SetParameter(4, -100.);
+    fDeltaFeed->SetParLimits(4, -100., 0.);
+    fDeltaFeed->SetParameter(5, -20.);
+    fDeltaFeed->SetParLimits(5, -100., 10.);
+    break;
+  default:
+    printf("fit function not defined\n");
+    return;
+    break;
+  }
+  fDeltaFeed->FixParameter(0, 1.);
+
+  /* output */
+  TFile *fileout = TFile::Open(Form("DCAdeltafeed_param_%s_%s_%s.root", name, AliPID::ParticleName(ipart), chargeName[icharge]), "RECREATE");
+
+  /* fit minimum-bias */
+  TCanvas *cMinimumBias = new TCanvas("cMinimumBias");
+  if (fitFunc == kExpoPowerLaw) {
+    fDeltaFeed->FixParameter(4, 0.);
+    hDeltaFeed_mb->Fit(fDeltaFeed, "IMRE", "", 1.0, 3.0);
+    fDeltaFeed->FixParameter(1, fDeltaFeed->GetParameter(1));
+    fDeltaFeed->FixParameter(2, fDeltaFeed->GetParameter(2));
+    fDeltaFeed->FixParameter(3, fDeltaFeed->GetParameter(3));
+    fDeltaFeed->ReleaseParameter(4);
+    hDeltaFeed_mb->Fit(fDeltaFeed, "IMRE", "", 0.5, 3.0);
+  }
+  else {
+    hDeltaFeed_mb->Fit(fDeltaFeed, "IMRE", "", 0.5, 3.0);
+  }
+  cMinimumBias->SetLogy();
+
+  /* build fit profile */
+  TProfile *pDeltaFeed = new TProfile("pDeltaFeed", "", NptBins, ptBin);
+  HistoUtils_Function2Profile(fDeltaFeed, pDeltaFeed);
+
+  /* save MB params */
+  Double_t parMB[100];
+  for (Int_t ipar = 0; ipar < fDeltaFeed->GetNpar(); ipar++)
+    parMB[ipar] = fDeltaFeed->GetParameter(ipar);
+  
+  /* write */
+  fileout->cd();
+  hDeltaFeed_mb->Write("hDeltaFeed_mb");
+  fDeltaFeed->Write("fDeltaFeed_mb");
+  pDeltaFeed->Write("pDeltaFeed_mb");
+
+  /* fix pt-depencence and release scale factor
+     to fit centrality bins */
+  TCanvas *cCentralityDependence = new TCanvas("cCentralityDependence");
+  TH1D *hCentDep = new TH1D("hCentDep", "", NcentralityBins, centralityBin);
+  //fDeltaFeed->ReleaseParameter(0);
+  //  for (Int_t ipar = 1; ipar < fDeltaFeed->GetNpar(); ipar++)
+  //    fDeltaFeed->FixParameter(ipar, fDeltaFeed->GetParameter(ipar));
+  //fDeltaFeed->FixParameter(1, fDeltaFeed->GetParameter(1));
+  TProfile *pDeltaFeed_cent[NcentralityBins]; = new TProfile("pDeltaFeed", "", NptBins, ptBin);
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    if (!hDeltaFeed_cent[icent]) continue;
+
+    /* restore MB parameters */
+    for (Int_t ipar = 0; ipar < fDeltaFeed->GetNpar(); ipar++)
+      fDeltaFeed->SetParameter(ipar, parMB[ipar]);
+
+    if (fitFunc == kExpoPowerLaw) {
+      fDeltaFeed->FixParameter(4, 0.);
+      hDeltaFeed_mb->Fit(fDeltaFeed, "IMRE", "", 1.0, 3.0);
+      fDeltaFeed->FixParameter(1, fDeltaFeed->GetParameter(1));
+      fDeltaFeed->FixParameter(2, fDeltaFeed->GetParameter(2));
+      fDeltaFeed->FixParameter(3, fDeltaFeed->GetParameter(3));
+      fDeltaFeed->ReleaseParameter(4);
+      hDeltaFeed_cent[icent]->Fit(fDeltaFeed, "IMRE", "", 0.5, 3.0);
+    }
+    else {
+      hDeltaFeed_cent[icent]->Fit(fDeltaFeed, "IMRE", "", 0.5, 3.0);
+    }
+
+    pDeltaFeed_cent[icent] = new TProfile(Form("pDeltaFeed_cent%d", icent), "", NptBins, ptBin);
+    HistoUtils_Function2Profile(fDeltaFeed, pDeltaFeed_cent[icent]);
+    hCentDep->SetBinContent(icent + 1, fDeltaFeed->GetParameter(0.));
+    hCentDep->SetBinError(icent + 1, fDeltaFeed->GetParError(0.));
+
+    /* write */
+    fileout->cd();
+    hDeltaFeed_cent[icent]->Write(Form("hDeltaFeed_cent%d", icent));
+    fDeltaFeed->Write(Form("fDeltaFeed_cent%d", icent));
+    pDeltaFeed_cent[icent]->Write(Form("pDeltaFeed_cent%d", icent));
+    
+  }
+
+  /* fit centrality dependence */
+  TF1 *fCentDep = (TF1 *)gROOT->GetFunction("pol3");
+  //  hCentDep->Fit(fCentDep);
+  
+  /* build fit profile */
+  TProfile *pCentDep = new TProfile("pCentDep", "", NcentralityBins, centralityBin);
+  HistoUtils_Function2Profile(fCentDep, pCentDep);
+  
+  /* write */
+  fileout->cd();
+  hCentDep->Write("hCentDep");
+  fCentDep->Write("fCentDep");
+  pCentDep->Write("pCentDep");
+  fileout->Close();
+
+}
+
+DCA_primaryFraction(const Char_t *destdir)
+{
+
+  Int_t marker[2] = {20, 21};
+  Int_t color[AliPID::kSPECIES] = {1, 1, 4, 8, 2};
+  Char_t *partLatex[AliPID::kSPECIES][2] = {
+    "", "", "", "", "#pi^{+}", "#pi^{-}", "K^{+}", "K^{-}", "p", "#bar{p}"
+  };
+
+  TFile *fileout = TFile::Open("TOF_primaryFraction.root", "RECREATE");
+
+  TProfile *pFrac;
+  TH1D *hFrac = new TH1D("hFrac", "", NptBins, ptBin);
+  Char_t title[1024];
+  for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+    if (ipart == 3) continue;
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      TFile *filein = TFile::Open(Form("%s/DCAdeltafeed_param_PrimaryCutFraction_%s_%s.root", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+      for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+       pFrac = (TProfile *)filein->Get(Form("pDeltaFeed_cent%d", icent));
+       /* copy profile in TH1D */
+       for (Int_t ipt = 0; ipt < NptBins; ipt++) {
+         hFrac->SetBinContent(ipt + 1, pFrac->GetBinContent(ipt + 1));
+         hFrac->SetBinError(ipt + 1, pFrac->GetBinError(ipt + 1));
+       }
+       sprintf(title, "%s (%d-%d%%);p_{T} (GeV/c);fraction of primary particle;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]);
+       hFrac->SetMarkerStyle(marker[icharge]);
+       hFrac->SetMarkerColor(color[ipart]);
+       hFrac->SetTitle(title);
+       hFrac->SetName(Form("hPrimaryFrac_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       fileout->cd();
+       hFrac->Write();
+      }
+    }
+  }
+
+  fileout->Close();
+
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/FinalSpectra.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/FinalSpectra.C
new file mode 100644 (file)
index 0000000..e00482e
--- /dev/null
@@ -0,0 +1,197 @@
+/**************************************************************/
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative",
+};
+/**************************************************************/
+const Int_t NcentralityBins = 10;
+Double_t centralityBin[NcentralityBins + 1] = {0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.};
+/**************************************************************/
+const Int_t NptBins = 46;
+Double_t ptBin[NptBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+/**************************************************************/
+Char_t *partLatex[AliPID::kSPECIES][2] = {
+  "", "", "", "", "#pi^{+}", "#pi^{-}", "K^{+}", "K^{-}", "p", "#bar{p}"
+};
+ /**************************************************************/
+
+FinalSpectra(const Char_t *rawfilename = "TOF_rawSpectra.root", const Char_t *matchfilename = "TOF_matchingEfficiency.root", const Char_t *trackfilename = "TOF_trackingEfficiency.root", const Char_t *primaryfilename = "TOF_primaryFraction.root", const Char_t *electronfilename = "TOF_electronCorrection.root")
+ {
+
+   Int_t marker[2] = {20, 25};
+   Int_t color[AliPID::kSPECIES] = {1, 1, 4, 8, 2};
+
+   TFile *rawfile = TFile::Open(rawfilename);
+   TFile *matchfile = TFile::Open(matchfilename);
+   TFile *trackfile = TFile::Open(trackfilename);
+   TFile *primaryfile = TFile::Open(primaryfilename);
+   TFile *electronfile = TFile::Open(electronfilename);
+
+   TFile *fileout = TFile::Open("TOF_finalSpectra.root", "RECREATE");
+   TH1D *hRaw, *hMatch, *hTrack, *hPrim, *hElectron;
+   Char_t title[1024];
+   for (Int_t icent = 0; icent < NcentralityBins; icent++)
+     for (Int_t icharge = 0; icharge < kNCharges; icharge++)
+       for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+        hRaw = (TH1D *)rawfile->Get(Form("hRaw_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+        if (!hRaw) {
+          printf("cannot find %s in %s\n", Form("hRaw_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]), rawfilename);
+          continue;
+        }
+        hMatch = (TH1D *)matchfile->Get(Form("hMatchEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+        if (!hMatch) {
+          printf("cannot find %s in %s\n", Form("hMatchEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]), matchfilename);
+          continue;
+        }
+        hTrack = (TH1D *)trackfile->Get(Form("hTrackingEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+        if (!hTrack) {
+          printf("cannot find %s in %s\n", Form("hTrackingEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]), trackfilename);
+          continue;
+        }
+        hPrim = (TH1D *)primaryfile->Get(Form("hPrimaryFrac_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+        if (ipart != 3 && !hPrim) {
+          printf("cannot find %s in %s\n", Form("hPrimaryFrac_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]), primaryfilename);
+          continue;
+        }
+        hElectron = (TH1D *)electronfile->Get("hElectronCorr_average");
+        if (!hElectron) {
+          printf("cannot find hElectronCorr_average in %s\n", electronfilename);
+          continue;
+        }
+        hRaw->Divide(hMatch);
+        hRaw->Divide(hTrack);
+        if (hPrim) hRaw->Multiply(hPrim);
+        if (ipart == 2) hRaw->Multiply(hElectron);
+        sprintf(title, "%s (%d-%d%%);p_{T} (GeV/c);#frac{d^{2}N}{dy dp_{T}} (c/GeV);", partLatex[ipart][icharge], centralityBin[icent], centralityBin[icent + 1]);
+        hRaw->SetName(Form("hFinal_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+        hRaw->SetTitle(title);
+        hRaw->SetMarkerStyle(marker[icharge]);
+        hRaw->SetMarkerColor(color[ipart]);
+        fileout->cd();
+        hRaw->Write();
+       }
+
+   fileout->Close();
+
+   FinalRatios();
+ }
+
+
+/**************************************************************/
+
+FinalRatios(const Char_t *filename = "TOF_finalSpectra.root")
+{
+
+  printf("WARNING: skipping ratios\n");
+  return;
+
+  Int_t marker[2] = {20, 25};
+  Int_t color[AliPID::kSPECIES] = {1, 1, 4, 8, 2};
+
+  /* open data */
+  TFile *filein = TFile::Open(filename);
+  /* get spectra */
+  TH1D *hSpectrum[NcentralityBins][AliPID::kSPECIES][kNCharges];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       hSpectrum[icent][ipart][icharge] = (TH1D *)filein->Get(Form("hFinal_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+      }
+    }
+  }
+
+  /* output */
+  TFile *fileout = TFile::Open("TOF_finalRatios.root", "RECREATE");
+
+  /* particle/anti-particle ratios */
+  TH1D *hRatio;
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+      if (!hSpectrum[icent][ipart][kNegative] ||
+         !hSpectrum[icent][ipart][kPositive]) continue;
+      hRatio = new TH1D(*hSpectrum[icent][ipart][kNegative]);
+      hRatio->Divide(hSpectrum[icent][ipart][kPositive]);
+      hRatio->SetName(Form("hRatio_cent%d_%s_negative_%s_positive", icent, AliPID::ParticleName(ipart), AliPID::ParticleName(ipart)));
+      hRatio->SetTitle(Form("%s/%s (%d-%d%%);p_{T} (GeV/c);%s/%s;", partLatex[ipart][kNegative], partLatex[ipart][kPositive], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1], partLatex[ipart][kNegative], partLatex[ipart][kPositive]));
+      hRatio->SetMarkerStyle(20);
+      hRatio->SetMarkerColor(color[ipart]);
+      fileout->cd();
+      hRatio->Write();
+    }
+  }
+
+  /* kaon/pion ratios */
+  TH1D *hSum1, *hSum2;
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      if (!hSpectrum[icent][ipart][kNegative] ||
+         !hSpectrum[icent][AliPID::kPion][icharge]) continue;
+      hRatio = new TH1D(*hSpectrum[icent][AliPID::kKaon][icharge]);
+      hRatio->Divide(hSpectrum[icent][AliPID::kPion][icharge]);
+      hRatio->SetName(Form("hRatio_cent%d_kaon_%s_pion_%s", icent, chargeName[icharge], chargeName[icharge]));
+      hRatio->SetTitle(Form("%s/%s (%d-%d%%);p_{T} (GeV/c);%s/%s;", partLatex[AliPID::kKaon][icharge], partLatex[AliPID::kPion][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1], partLatex[AliPID::kKaon][icharge], partLatex[AliPID::kPion][icharge]));
+      hRatio->SetMarkerStyle(marker[icharge]);
+      hRatio->SetMarkerColor(color[AliPID::kKaon]);
+      fileout->cd();
+      hRatio->Write();
+    }
+    if (!hSpectrum[icent][AliPID::kKaon][kPositive] ||
+       !hSpectrum[icent][AliPID::kKaon][kNegative] ||
+       !hSpectrum[icent][AliPID::kPion][kPositive] ||
+       !hSpectrum[icent][AliPID::kPion][kNegative]) continue;
+    hSum1 = new TH1D(*hSpectrum[icent][AliPID::kKaon][kPositive]);
+    hSum1->Add(hSpectrum[icent][AliPID::kKaon][kNegative]);
+    hSum2 = new TH1D(*hSpectrum[icent][AliPID::kPion][kPositive]);
+    hSum2->Add(hSpectrum[icent][AliPID::kPion][kNegative]);
+    hRatio = new TH1D(*hSum1);
+    hRatio->Divide(hSum2);
+    hRatio->SetName(Form("hRatio_cent%d_kaon_pion", icent));
+    hRatio->SetTitle(Form("(%s+%s)/(%s+%s) (%d-%d%%);p_{T} (GeV/c);(%s+%s)/(%s+%s);", partLatex[AliPID::kKaon][kPositive], partLatex[AliPID::kKaon][kNegative], partLatex[AliPID::kPion][kPositive], partLatex[AliPID::kPion][kNegative], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1], partLatex[AliPID::kKaon][kPositive], partLatex[AliPID::kKaon][kNegative], partLatex[AliPID::kPion][kPositive], partLatex[AliPID::kPion][kNegative]));
+    hRatio->SetMarkerStyle(20);
+    hRatio->SetMarkerColor(color[AliPID::kKaon]);
+    fileout->cd();
+    hRatio->Write();
+  }
+  
+  /* proton/pion ratios */
+  TH1D *hSum1, *hSum2;
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      if (!hSpectrum[icent][AliPID::kProton][icharge] ||
+         !hSpectrum[icent][AliPID::kPion][icharge]) continue;
+      hRatio = new TH1D(*hSpectrum[icent][AliPID::kProton][icharge]);
+      hRatio->Divide(hSpectrum[icent][AliPID::kPion][icharge]);
+      hRatio->SetName(Form("hRatio_cent%d_proton_%s_pion_%s", icent, chargeName[icharge], chargeName[icharge]));
+      hRatio->SetTitle(Form("%s/%s (%d-%d%%);p_{T} (GeV/c);%s/%s;", partLatex[AliPID::kProton][icharge], partLatex[AliPID::kPion][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1], partLatex[AliPID::kProton][icharge], partLatex[AliPID::kPion][icharge]));
+      hRatio->SetMarkerStyle(marker[icharge]);
+      hRatio->SetMarkerColor(color[AliPID::kProton]);
+      fileout->cd();
+      hRatio->Write();
+    }
+    if (!hSpectrum[icent][AliPID::kProton][kPositive] ||
+       !hSpectrum[icent][AliPID::kProton][kNegative] ||
+       !hSpectrum[icent][AliPID::kPion][kPositive] ||
+       !hSpectrum[icent][AliPID::kPion][kNegative]) continue;
+    hSum1 = new TH1D(*hSpectrum[icent][AliPID::kProton][kPositive]);
+    hSum1->Add(hSpectrum[icent][AliPID::kProton][kNegative]);
+    hSum2 = new TH1D(*hSpectrum[icent][AliPID::kPion][kPositive]);
+    hSum2->Add(hSpectrum[icent][AliPID::kPion][kNegative]);
+    hRatio = new TH1D(*hSum1);
+    hRatio->Divide(hSum2);
+    hRatio->SetName(Form("hRatio_cent%d_proton_pion", icent));
+    hRatio->SetTitle(Form("(%s+%s)/(%s+%s) (%d-%d%%);p_{T} (GeV/c);(%s+%s)/(%s+%s);", partLatex[AliPID::kProton][kPositive], partLatex[AliPID::kProton][kNegative], partLatex[AliPID::kPion][kPositive], partLatex[AliPID::kPion][kNegative], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1], partLatex[AliPID::kProton][kPositive], partLatex[AliPID::kProton][kNegative], partLatex[AliPID::kPion][kPositive], partLatex[AliPID::kPion][kNegative]));
+    hRatio->SetMarkerStyle(20);
+    hRatio->SetMarkerColor(color[AliPID::kProton]);
+    fileout->cd();
+    hRatio->Write();
+  }
+  
+
+  fileout->Close();
+}
+
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/HistoUtils.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/HistoUtils.C
new file mode 100644 (file)
index 0000000..97f3902
--- /dev/null
@@ -0,0 +1,299 @@
+//__________________________________________________________________
+
+HistoUtils_drawthemall(const Char_t *filename, Int_t sleepms = 100)
+{
+  TFile *f1 = TFile::Open(filename);
+  TList *l1 = f1->GetListOfKeys();
+  TObject *o;
+  Char_t *name;
+  for (Int_t i = 0; i < l1->GetEntries(); i++) {
+    name = l1->At(i)->GetName();
+    o = f1->Get(name);
+    o->Draw();
+    gPad->Update();
+    gSystem->Sleep(sleepms);
+  }
+  f1->Close();
+}
+
+//__________________________________________________________________
+
+HistoUtils_autoratio(const Char_t *f1name, const Char_t *f2name, const Char_t *outname, const Char_t *title = NULL)
+{
+
+  TFile *f1 = TFile::Open(f1name);
+  TFile *f2 = TFile::Open(f2name);
+  TFile *fo = TFile::Open(outname, "RECREATE");
+  TList *l1 = f1->GetListOfKeys();
+
+
+  TH1D *h1, *h2, *hr;
+  Char_t *name;
+  for (Int_t i = 0; i < l1->GetEntries(); i++) {
+    name = l1->At(i)->GetName();
+    h1 = (TH1D *)f1->Get(name);
+    h2 = (TH1D *)f2->Get(name);
+    if (!h1 || !h2) continue;
+    hr = new TH1D(*h1);
+    hr->Divide(h2);
+    if (title)
+      hr->SetTitle(title);
+    fo->cd();
+    hr->Write();
+  }
+
+  delete hr;
+  f1->Close();
+  f2->Close();
+  fo->Close();
+
+}
+
+//__________________________________________________________________
+
+HistoUtils_autosystematics(const Char_t *f1name, const Char_t *f2name, const Char_t *outname, const Char_t *title = NULL)
+{
+
+  TFile *f1 = TFile::Open(f1name);
+  TFile *f2 = TFile::Open(f2name);
+  if (!f1 || !f1->IsOpen() || !f2 || !f2->IsOpen()) return;
+  TFile *fo = TFile::Open(outname, "RECREATE");
+  TList *l1 = f1->GetListOfKeys();
+
+
+  TH1D *h1, *h2, *hd;
+  Char_t *name;
+  for (Int_t i = 0; i < l1->GetEntries(); i++) {
+    name = l1->At(i)->GetName();
+    h1 = (TH1D *)f1->Get(name);
+    h2 = (TH1D *)f2->Get(name);
+    if (!h1 || !h2) continue;
+
+    hd = new TH1D(*h1);
+    Double_t val1, val2, vald, vale1, vale2, valde;
+    for (Int_t ii = 0; ii < hd->GetNbinsX(); ii++) {
+      val1 = h1->GetBinContent(ii + 1);
+      vale1 = h1->GetBinError(ii + 1);
+      val2 = h2->GetBinContent(ii + 1);
+      vale2 = h2->GetBinError(ii + 1);
+      if (val2 == 0.) continue;
+      vald = (val1 - val2) / val2;
+      valde = TMath::Sqrt(TMath::Abs((vale1 * vale1 - vale2 * vale2))) / val2;
+      hd->SetBinContent(ii + 1, vald);
+      hd->SetBinError(ii + 1, valde);
+    }
+
+    if (title)
+      hd->SetTitle(title);
+    fo->cd();
+    hd->Write();
+    delete hd;
+  }
+
+  f1->Close();
+  f2->Close();
+  fo->Close();
+
+}
+
+//__________________________________________________________________
+
+TH1 *
+HistoUtils_ratio(const Char_t *f1name, const Char_t *f2name, const Char_t *h1name, const Char_t *h2name)
+{
+
+  if (!f2name) f2name = f1name;
+  TFile *f1 = TFile::Open(f1name);
+  TFile *f2 = TFile::Open(f2name);
+
+  if (!h2name) h2name = h1name;
+  TH1 *h1 = (TH1 *)f1->Get(h1name);
+  TH1 *h2 = (TH1 *)f2->Get(h2name);
+
+  TH1 *hr = h1->Clone("hr");
+  hr->Sumw2();
+  hr->Divide(h2);
+
+  return hr;
+  
+}
+
+//__________________________________________________________________
+
+TH1 *
+HistoUtils_systematics(const Char_t *f1name, const Char_t *f2name, const Char_t *h1name, const Char_t *h2name)
+{
+
+  if (!f2name) f2name = f1name;
+  TFile *f1 = TFile::Open(f1name);
+  TFile *f2 = TFile::Open(f2name);
+
+  if (!h2name) h2name = h1name;
+  TH1 *h1 = (TH1 *)f1->Get(h1name);
+  TH1 *h2 = (TH1 *)f2->Get(h2name);
+
+  TH1 *hd = h1->Clone("hd");
+  Double_t val1, val2, vald, vale1, vale2, valde;
+  for (Int_t i = 0; i < h1->GetNbinsX(); i++) {
+    val1 = h1->GetBinContent(i + 1);
+    vale1 = h1->GetBinError(i + 1);
+    val2 = h2->GetBinContent(i + 1);
+    vale2 = h2->GetBinError(i + 1);
+    if (val2 == 0.) continue;
+    vald = (val1 - val2) / val2;
+    valde = TMath::Sqrt(TMath::Abs((vale1 * vale1 - vale2 * vale2))) / val2;
+    hd->SetBinContent(i + 1, vald);
+    hd->SetBinError(i + 1, valde);
+  }
+
+  return hd;
+  
+}
+
+//__________________________________________________________________
+
+HistoUtils_BinLogX(TH1 *h)
+{
+  TAxis *axis = h->GetXaxis();
+  Int_t bins = axis->GetNbins();
+  Axis_t from = axis->GetXmin();
+  Axis_t to = axis->GetXmax();
+  Axis_t width = (to - from) / bins;
+  Axis_t *new_bins = new Axis_t[bins + 1];
+  for (int i = 0; i <= bins; i++) new_bins[i] = TMath::Power(10, from + i * width);
+  axis->Set(bins, new_bins);
+  delete new_bins;
+}
+
+//__________________________________________________________________
+
+HistoUtils_BinNormX(TH1 *h)
+{
+  TAxis *axis = h->GetXaxis();
+  Int_t bins = axis->GetNbins();
+  Double_t c, ec;
+  Double_t w;
+  for (Int_t i = 0; i < bins; i++) {
+    c = h->GetBinContent(i + 1);
+    ec = h->GetBinError(i + 1);
+    w = axis->GetBinWidth(i + 1);
+    c /= w;
+    ec /= w;
+    h->SetBinContent(i + 1, c);
+    h->SetBinError(i + 1, ec);
+  }
+}
+
+//__________________________________________________________________
+
+TObjArray *
+HistoUtils_FitPeak(TF1 *fitFunc, TH2 *h, Float_t startSigma, Float_t nSigmaMin, Float_t nSigmaMax, Int_t minIntegral = 100., const Char_t *basename = "hParam", Bool_t monitor = kFALSE)
+{
+
+  /* gaus function if not specified */
+  if (!fitFunc)
+    fitFunc = (TF1*)gROOT->GetFunction("gaus");
+
+  /* prepare output histos */
+  TObjArray *outArray = new TObjArray();
+  Int_t npars = fitFunc->GetNpar();
+  TH1D *hpx = h->ProjectionX("hpx");
+  TH1D *hParam;
+  for (Int_t ipar = 0; ipar < npars; ipar++) {
+    hParam = new TH1D(*hpx);
+    hParam->SetName(Form("%s_%d", basename, ipar));
+    hParam->Reset();
+    outArray->Add(hParam);
+  }
+
+  /* loop over x-bins */
+  for (Int_t ibin = 0; ibin < hpx->GetNbinsX(); ibin++) {
+
+    /* check integral */
+    if (hpx->GetBinContent(ibin + 1) < minIntegral) continue;
+    /* projection y */
+    TH1D *hpy = h->ProjectionY("hpy", ibin + 1, ibin + 1);
+    /* fit peak */
+    if (HistoUtils_FitPeak(fitFunc, hpy, startSigma, nSigmaMin, nSigmaMax) != 0) {
+      delete hpy;
+      continue;
+    }
+    /* setup output histos */
+    for (Int_t ipar = 0; ipar < npars; ipar++) {
+      hParam = (TH1D *)outArray->At(ipar);
+      hParam->SetBinContent(ibin + 1, fitFunc->GetParameter(ipar));
+      hParam->SetBinError(ibin + 1, fitFunc->GetParError(ipar));
+    }
+    /* monitor */
+    if (monitor) {
+      hpy->SetMarkerStyle(20);
+      hpy->SetMarkerColor(4);
+      hpy->Draw("E1");
+      fitFunc->Draw("same");
+      gPad->Update();
+      getchar();
+    }
+    /* delete */
+    delete hpy;
+
+  }
+  /* delete */
+  delete hpx;
+  /* return output array */
+  return outArray;
+}
+
+//__________________________________________________________________
+
+Int_t
+HistoUtils_FitPeak(TF1 *fitFunc, TH1 *h, Float_t startSigma, Float_t nSigmaMin, Float_t nSigmaMax)
+{
+
+  Double_t fitCent = h->GetBinCenter(h->GetMaximumBin());
+  Double_t fitMin = fitCent - nSigmaMin * startSigma;
+  Double_t fitMax = fitCent + nSigmaMax * startSigma;
+  if (fitMin < h->GetXaxis()->GetXmin()) fitMin = h->GetXaxis()->GetXmin();
+  if (fitMax > h->GetXaxis()->GetXmax()) fitMax = h->GetXaxis()->GetXmax();
+  fitFunc->SetParameter(1, fitCent);
+  fitFunc->SetParameter(2, startSigma);
+  Int_t fitres = h->Fit(fitFunc, "WWq0", "", fitMin, fitMax);
+  if (fitres != 0) return fitres;
+  /* refit with better range */
+  for (Int_t i = 0; i < 3; i++) {
+    fitCent = fitFunc->GetParameter(1);
+    fitMin = fitCent - nSigmaMin * fitFunc->GetParameter(2);
+    fitMax = fitCent + nSigmaMax * fitFunc->GetParameter(2);
+    if (fitMin < h->GetXaxis()->GetXmin()) fitMin = h->GetXaxis()->GetXmin();
+    if (fitMax > h->GetXaxis()->GetXmax()) fitMax = h->GetXaxis()->GetXmax();
+    fitres = h->Fit(fitFunc, "q0", "", fitMin, fitMax);
+    if (fitres != 0) return fitres;
+  }
+  return fitres;
+
+}
+
+//__________________________________________________________________
+
+void
+HistoUtils_Function2Profile(TF1 *fin, TProfile *p, Int_t ntry = 10000)
+{
+
+  TF1 *f = new TF1(*fin);
+  Int_t npars = f->GetNpar();
+  Double_t par[1000];
+  Double_t pare[1000];
+  for (Int_t ipar = 0; ipar < npars; ipar++) {
+    par[ipar] = f->GetParameter(ipar);
+    pare[ipar] = f->GetParError(ipar);
+  }
+
+  Double_t x;
+  for (Int_t ibin = 0; ibin < p->GetNbinsX(); ibin++) {
+    for (Int_t itry = 0; itry < ntry; itry++) {
+      for (Int_t ipar = 0; ipar < npars; ipar++)
+       f->SetParameter(ipar, gRandom->Gaus(par[ipar], pare[ipar]));
+      x = gRandom->Uniform(p->GetXaxis()->GetBinLowEdge(ibin + 1), p->GetXaxis()->GetBinUpEdge(ibin + 1));
+      p->Fill(x, f->Eval(x));
+    }
+  }
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MakeLibs.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MakeLibs.C
new file mode 100644 (file)
index 0000000..381f5ee
--- /dev/null
@@ -0,0 +1,14 @@
+MakeLibs()
+{
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MakeRooShapes.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MakeRooShapes.C
new file mode 100644 (file)
index 0000000..9fd827a
--- /dev/null
@@ -0,0 +1,6 @@
+{
+  gSystem->Load("libRooFit");
+  using namespace RooFit;
+  gROOT->ProcessLine(".L RooFermiCutoff.cxx++");
+  gROOT->ProcessLine(".L RooGaussianTail.cxx++");
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MultCent.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/MultCent.C
new file mode 100644 (file)
index 0000000..d22efd7
--- /dev/null
@@ -0,0 +1,106 @@
+MultCent(const Char_t *filename, Int_t evMax = kMaxInt)
+{
+  
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* histo */
+  TH2F *hMultCent = new TH2F("hMultCent", "", 100, 0., 100., 5000, 0., 5000.);
+  TH2F *hMultCent_T0TOF = new TH2F("hMultCent_T0TOF", "", 100, 0., 100., 5000, 0., 5000.);
+
+  /* loop over events */
+  Int_t mult;
+  Double_t cent;
+  for (Int_t iev = 0; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 1000 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* count tracks for multiplicity */
+    mult = analysisTrackArray->GetEntries();
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+    /* check centrality percentile (V0M) */
+    if (cent == 100.) continue;
+
+    /*** ACCEPTED EVENT ***/
+
+    /* fill histo */
+    hMultCent->Fill(cent, mult);
+
+    /* check if event has T0-TOF */
+    if (analysisEvent->GetTimeZeroTOFSigma(9) > 150.) continue;
+
+    hMultCent_T0TOF->Fill(cent, mult);
+
+  }
+
+  /* output */
+  TFile *fileout = new TFile(Form("MultCent.%s", filename), "RECREATE");
+  hMultCent->Write();
+  hMultCent_T0TOF->Write();
+  fileout->Close();
+
+}
+
+MultCent_T0TOFeff(const Char_t *filename)
+{
+
+  TFile *filein = TFile::Open(filename);
+  TH2F *hMultCent = (TH2F *)filein->Get("hMultCent");
+  TH2F *hMultCent_T0TOF = (TH2F *)filein->Get("hMultCent_T0TOF");
+
+  /* projections */
+  TH1D *hMultCent_px = hMultCent->ProjectionX();
+  TH1D *hMultCent_T0TOF_px = hMultCent_T0TOF->ProjectionX();
+  TH1D *hMultCent_py = hMultCent->ProjectionY();
+  TH1D *hMultCent_T0TOF_py = hMultCent_T0TOF->ProjectionY();
+
+  /* efficiency centrality */
+  TH1D *hEfficiency_centrality = new TH1D(*hMultCent_T0TOF_px);
+  hEfficiency_centrality->SetNameTitle("hEfficiency_centrality", ";centrality percentile;T0-TOF efficiency");
+  hEfficiency_centrality->Sumw2();
+  hEfficiency_centrality->Divide(hEfficiency_centrality, hMultCent_px, 1., 1., "B");
+
+  /* efficiency tracks */
+  TH1D *hEfficiency_tracks = new TH1D(*hMultCent_T0TOF_py);
+  hEfficiency_tracks->SetNameTitle("hEfficiency_tracks", ";N_{tracks};T0-TOF efficiency");
+  hEfficiency_tracks->Sumw2();
+  hEfficiency_tracks->Divide(hEfficiency_tracks, hMultCent_py, 1., 1., "B");
+
+  /* draw */
+  TCanvas *cCentrality = new TCanvas("cCentrality");
+  hEfficiency_centrality->DrawCopy();
+  TCanvas *cTracks = new TCanvas("cTracks");
+  hEfficiency_tracks->DrawCopy();
+
+  /* output */
+  TFile *fileout = new TFile(Form("MultCent_T0TOFeff.%s", filename), "RECREATE");
+  hEfficiency_centrality->Write();
+  hEfficiency_tracks->Write();
+  fileout->Close();
+
+
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/SystematicChecks.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/SystematicChecks.C
new file mode 100644 (file)
index 0000000..4dbbcef
--- /dev/null
@@ -0,0 +1,550 @@
+/**************************************************************/
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative",
+};
+/**************************************************************/
+const Int_t NcentralityBins = 10;
+Double_t centralityBin[NcentralityBins + 1] = {0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.};
+/**************************************************************/
+const Int_t NptBins = 46;
+Double_t ptBin[NptBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+/**************************************************************/
+Char_t *partLatex[AliPID::kSPECIES][2] = {
+  "", "", "", "", "#pi^{+}", "#pi^{-}", "K^{+}", "K^{-}", "p", "#bar{p}"
+};
+ /**************************************************************/
+
+SystematicChecks()
+{
+  SystematicCheck();
+  SystematicPlots_spectra();
+}
+
+
+SystematicPlots_spectra()
+{
+
+
+  enum EData_t {
+    kuseTPCcrossedRows,
+    kminTPCclusters_60,
+    kminTPCclusters_80, 
+    kscaleDCAxy_09,
+    kscaleDCAxy_11,
+    kscaleDCAxy_10x,
+    ketaCut_75,
+    ketaCut_85,
+    kbkgFit_fixed_scaleSigma_09,
+    kbkgFit_fixed_scaleSigma_11,
+    kbkgFit_fixed_scaleTail_09,
+    kbkgFit_fixed_scaleTail_11,
+    kbkgFit_fixed_scaleSigma_09_scaleTail_11,
+    kbkgFit_fixed_scaleSigma_11_scaleTail_09,
+    ksignalFit_fixed_scaleSigma_09,
+    ksignalFit_fixed_scaleSigma_11,
+    ksignalFit_fixed_scaleTail_09,
+    ksignalFit_fixed_scaleTail_11,
+    ksignalFit_fixed_scaleSigma_09_scaleTail_11,
+    ksignalFit_fixed_scaleSigma_11_scaleTail_09,
+    kbkgFit_fixed,
+    kbkgFit_free,
+    ksignalFit_fixed,
+    ksignalFit_free,
+    ksignalbkgFit_free,
+    kdefaultFit_fitElectrons,
+    kdefaultFit_limitedRange,
+    kfieldReversal
+  };
+  const Int_t ndata = 28;
+  const Char_t *name[ndata] = {
+    "useTPCcrossedRows",
+    "minTPCclusters_60",
+    "minTPCclusters_80", 
+    "scaleDCAxy_09",
+    "scaleDCAxy_11",
+    "scaleDCAxy_10x",
+    "etaCut_75",
+    "etaCut_85",
+    "bkgFit_fixed_scaleSigma_09",
+    "bkgFit_fixed_scaleSigma_11",
+    "bkgFit_fixed_scaleTail_09",
+    "bkgFit_fixed_scaleTail_11",
+    "bkgFit_fixed_scaleSigma_09_scaleTail_11",
+    "bkgFit_fixed_scaleSigma_11_scaleTail_09",
+    "signalFit_fixed_scaleSigma_09",
+    "signalFit_fixed_scaleSigma_11",
+    "signalFit_fixed_scaleTail_09",
+    "signalFit_fixed_scaleTail_11",
+    "signalFit_fixed_scaleSigma_09_scaleTail_11",
+    "signalFit_fixed_scaleSigma_11_scaleTail_09",
+    "bkgFit_fixed",
+    "bkgFit_free",
+    "signalFit_fixed",
+    "signalFit_free",
+    "signalbkgFit_free",
+    "defaultFit_fitElectrons",
+    "defaultFit_limitedRange",
+    "fieldReversal"
+  };
+  Int_t marker[ndata] = {
+    25, 20, 21,
+    20, 21, 25,
+    20, 21,
+    20, 21, 20, 21, 20, 21,
+    20, 21, 20, 21, 20, 21,
+    20, 21, 20, 21, 25,
+    20,
+    20,
+    20
+  };
+  Int_t color[ndata] = {
+    4, 2, 8,
+    2, 8, 4,
+    2, 8,
+    2, 2, 4, 4, 8, 8,
+    2, 2, 4, 4, 8, 8,
+    2, 8, 4,
+    4,
+    4,
+    4
+  };
+
+  TFile *fin[ndata];
+  for (Int_t idata = 0; idata < ndata; idata++) 
+    fin[idata] = TFile::Open(Form("SystematicCheck_finalSpectra_%s.root", name[idata]));
+
+  TFile *fileout = TFile::Open("SystematicPlots_spectra.root", "RECREATE");
+    
+  TH1D *hin[ndata];
+  TH1D *hArea = new TH1D("hArea", "", NptBins, ptBin);
+  hArea->SetStats(kFALSE);
+  Char_t title[1024];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       for (Int_t idata = 0; idata < ndata; idata++) {
+         if (!fin[idata] || !fin[idata]->IsOpen()) continue;
+         hin[idata] = (TH1D *)fin[idata]->Get(Form("hFinal_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+         if (!hin[idata]) {
+           printf("cannot find hFinal_cent%d_%s_%s in %s\n", icent, AliPID::ParticleName(ipart), chargeName[icharge], fin[idata]->GetName());
+           continue;
+         }
+         hin[idata]->SetMarkerStyle(marker[idata]);
+         hin[idata]->SetMarkerColor(color[idata]);
+       }
+
+       /* set common title */
+       sprintf(title, "%s (%d-%d%%);p_{T} (GeV/c);relative variation wrt. standard;", partLatex[ipart][icharge], centralityBin[icent], centralityBin[icent + 1]);
+       hArea->SetTitle(title);
+
+       /* TPC quality cuts */
+       hArea->SetMinimum(-0.05);
+       hArea->SetMaximum(0.05);
+       hArea->Draw();
+       hin[kuseTPCcrossedRows]->Draw("same");
+       hin[kminTPCclusters_60]->Draw("same");
+       hin[kminTPCclusters_80]->Draw("same");
+       TLegend *l = gPad->BuildLegend();
+       l->DeleteEntry();
+       l->SetFillColor(0);
+       l->SetBorderSize(1);
+       fileout->cd();
+       gPad->Write(Form("cSpectraSys_TPCcuts_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+
+       /* DCA cuts */
+       hArea->SetMinimum(-0.05);
+       hArea->SetMaximum(0.05);
+       hArea->Draw();
+       hin[kscaleDCAxy_09]->Draw("same");
+       hin[kscaleDCAxy_11]->Draw("same");
+       hin[kscaleDCAxy_10x]->Draw("same");
+       TLegend *l = gPad->BuildLegend();
+       l->DeleteEntry();
+       l->SetFillColor(0);
+       l->SetBorderSize(1);
+       fileout->cd();
+       gPad->Write(Form("cSpectraSys_DCAcuts_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+
+       /* eta cut */
+       hArea->SetMinimum(-0.05);
+       hArea->SetMaximum(0.05);
+       hArea->Draw();
+       hin[ketaCut_75]->Draw("same");
+       hin[ketaCut_85]->Draw("same");
+       TLegend *l = gPad->BuildLegend();
+       l->DeleteEntry();
+       l->SetFillColor(0);
+       l->SetBorderSize(1);
+       fileout->cd();
+       gPad->Write(Form("cSpectraSys_etaCut_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+
+       /* background fit */
+       hArea->SetMinimum(-0.5);
+       hArea->SetMaximum(0.5);
+       hArea->Draw();
+       hin[kbkgFit_fixed_scaleSigma_09]->Draw("same");
+       hin[kbkgFit_fixed_scaleSigma_11]->Draw("same");
+       hin[kbkgFit_fixed_scaleTail_09]->Draw("same");
+       hin[kbkgFit_fixed_scaleTail_11]->Draw("same");
+       hin[kbkgFit_fixed_scaleSigma_09_scaleTail_11]->Draw("same");
+       hin[kbkgFit_fixed_scaleSigma_11_scaleTail_09]->Draw("same");
+       TLegend *l = gPad->BuildLegend();
+       l->DeleteEntry();
+       l->SetFillColor(0);
+       l->SetBorderSize(1);
+       fileout->cd();
+       gPad->Write(Form("cSpectraSys_bkgFit_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+
+       /* signal fit */
+       hArea->SetMinimum(-0.5);
+       hArea->SetMaximum(0.5);
+       hArea->Draw();
+       hin[ksignalFit_fixed_scaleSigma_09]->Draw("same");
+       hin[ksignalFit_fixed_scaleSigma_11]->Draw("same");
+       hin[ksignalFit_fixed_scaleTail_09]->Draw("same");
+       hin[ksignalFit_fixed_scaleTail_11]->Draw("same");
+       hin[ksignalFit_fixed_scaleSigma_09_scaleTail_11]->Draw("same");
+       hin[ksignalFit_fixed_scaleSigma_11_scaleTail_09]->Draw("same");
+       TLegend *l = gPad->BuildLegend();
+       l->DeleteEntry();
+       l->SetFillColor(0);
+       l->SetBorderSize(1);
+       fileout->cd();
+       gPad->Write(Form("cSpectraSys_signalFit_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+      }
+    }
+  }
+
+  fileout->Close();
+  for (Int_t idata = 0; idata < ndata; idata++) 
+    if (fin[idata])
+    fin[idata]->Close();
+}
+
+SystematicCheck()
+{
+  SystematicCheck("rawSpectra");
+  SystematicCheck("matchingEfficiency");
+  SystematicCheck("trackingEfficiency");
+  SystematicCheck("primaryFraction");
+  SystematicCheck("finalSpectra");
+  SystematicCheck("finalRatios");
+}
+
+SystematicCheck(const Char_t *checkname)
+{
+
+  gROOT->LoadMacro("HistoUtils.C");
+
+  const Int_t ndata = 30;
+  const Char_t *name[ndata] = {
+    "useTPCcrossedRows",
+    "minTPCclusters_60",
+    "minTPCclusters_80",
+    "scaleDCAxy_09",
+    "scaleDCAxy_11",
+    "scaleDCAxy_10x",
+    "DCAz_1",
+    "etaCut_75",
+    "etaCut_85",
+    "bkgFit_fixed",
+    "bkgFit_fixed_scaleSigma_09",
+    "bkgFit_fixed_scaleSigma_09_scaleTail_11",
+    "bkgFit_fixed_scaleSigma_11",
+    "bkgFit_fixed_scaleSigma_11_scaleTail_09",
+    "bkgFit_fixed_scaleTail_09",
+    "bkgFit_fixed_scaleTail_11",
+    "bkgFit_free",
+    "mismatchCorrected",
+    "defaultFit_fitElectrons",
+    "defaultFit_limitedRange",
+    "defaultFit_tightRange",
+    "fieldReversal",
+    "signalbkgFit_free",
+    "signalFit_fixed_scaleSigma_09",
+    "signalFit_fixed_scaleSigma_09_scaleTail_11",
+    "signalFit_fixed_scaleSigma_11",
+    "signalFit_fixed_scaleSigma_11_scaleTail_09",
+    "signalFit_fixed_scaleTail_09",
+    "signalFit_fixed_scaleTail_11",
+    "signalFit_free"
+  };
+
+
+  const Char_t *title[ndata] = {
+    "N_{crossed-rows} cut",
+    "N_{clusters}^{min} = 60",
+    "N_{clusters}^{min} = 80",
+    "-10% DCA_{xy} cut",
+    "+10% DCA_{xy} cut",
+    "10x larger DCA_{xy} cut",
+    "DCA_{z} < 1 cm",
+    "|#eta| < 0.75",
+    "|#eta| < 0.85",
+    "background fit (fixed params)",
+    "-10% #sigma background",
+    "-10% #sigma +10% #tau background",
+    "+10% #sigma background",
+    "+10% #sigma -10% #tau background",
+    "-10% #tau background",
+    "+10% #tau background",
+    "background fit (free params)",
+    "with mismatch correction",
+    "with electron background",
+    "fit in limited range",
+    "fit in tight range",
+    "reversed magnetic field",
+    "signal+background fit (free params)",
+    "-10% #sigma signal",
+    "-10% #sigma +10% #tau signal",
+    "+10% #sigma signal",
+    "+10% #sigma -10% #tau signal",
+    "-10% #tau signal",
+    "+10% #tau signal",
+    "signal fit (free params)"
+  };
+
+#if 0
+  Char_t filename1[1024], filename2[1024], ofilename[1024];
+  for (Int_t idata = 1; idata < ndata; idata++) {
+    sprintf(filename1, "standardPrimaryCuts_%s/TOF_%s.root", name[idata], checkname);
+    sprintf(filename2, "standardPrimaryCuts/TOF_%s.root", checkname);
+    sprintf(ofilename, "SystematicCheck_%s_%s.root", checkname, name[idata]);
+    printf("%s %s %s\n", filename1, filename2, ofilename);
+    HistoUtils_autosystematics(filename1, filename2, ofilename, Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[idata]));
+  }
+  return;
+#endif
+  
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[0], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[0]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[0]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[1], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[1]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[1]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[2], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[2]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[2]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[3], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[3]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[3]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[4], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[4]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[4]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[5], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[5]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[5]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[6], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[6]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[6]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[7], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[7]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[7]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[8], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[8]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[8]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[9], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[9]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[9]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[10], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[10]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[10]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[11], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[11]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[11]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[12], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[12]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[12]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[13], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[13]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[13]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[14], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[14]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[14]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[15], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[15]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[15]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[16], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[16]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[16]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[17], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[17]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[17]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[18], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[18]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[18]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[19], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[19]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[19]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[20], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[20]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[20]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[21], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[21]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[21]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[22], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[22]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[22]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[23], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[23]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[23]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[24], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[24]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[24]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[25], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[25]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[25]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[26], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[26]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[26]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[26], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[27]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[27]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[26], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[28]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[28]));
+  HistoUtils_autosystematics(Form("standardPrimaryCuts_%s/TOF_%s.root", name[26], checkname), Form("standardPrimaryCuts/TOF_%s.root", checkname), Form("SystematicCheck_%s_%s.root", checkname, name[29]), Form("%s;p_{T} (GeV/c);relative variation wrt. default;", title[29]));
+
+  
+}
+
+/**************************************************************/
+/**************************************************************/
+
+FinalSpectra_systematics_useTPCcrossedRows()
+{
+  
+  TFile *fileout = TFile::Open("FinalSpectra_systematics_useTPCcrossedRows.root", "RECREATE");
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       FinalSpectra_systematics_useTPCcrossedRows(ipart, icharge, icent, fileout);
+      }
+  fileout->Close();
+}
+
+FinalSpectra_systematics_useTPCcrossedRows(Int_t ipart, Int_t icharge, Int_t icent, TFile *fileout = NULL)
+{
+  const Int_t ndata = 1;
+  const Char_t *name[ndata] = {
+    "standardPrimaryCuts_useTPCcrossedRows"
+  };
+  const Char_t *title[ndata] = {
+    "TPC crossed-rows cut;p_{T} (GeV/c); ratio"
+  };
+  Int_t marker[ndata] = {22};
+  Int_t color[ndata] = {2};
+  
+  TH1D *hArea = new TH1D("hArea", Form("%s (%d-%d%%);p_{T} (GeV/c);ratio;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]), NptBins, ptBin);
+  hArea->SetMinimum(0.9);
+  hArea->SetMaximum(1.1); 
+  hArea->SetStats(kFALSE);
+  hArea->Draw();
+  
+  TH1D *hr[ndata];
+  for (Int_t idata = 0; idata < ndata; idata++) {
+    hr[idata] = FinalSpectra_systematics_ratio(name[idata], "standardPrimaryCuts", ipart, icharge, icent, name[idata], title[idata], marker[idata], color[idata]);
+    hr[idata]->Draw("same");
+  }
+  
+  gPad->SetGridy();
+  TLegend *legend = gPad->BuildLegend();
+  legend->DeleteEntry();
+  legend->SetFillColor(0);
+  legend->SetBorderSize(1);
+  if (fileout) {
+    fileout->cd();
+    gPad->Write(Form("cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+  }
+}
+
+FinalSpectra_systematics_minTPCclusters()
+{
+  
+  TFile *fileout = TFile::Open("FinalSpectra_systematics_minTPCclusters.root", "RECREATE");
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       FinalSpectra_systematics_minTPCclusters(ipart, icharge, icent, fileout);
+      }
+  fileout->Close();
+}
+
+FinalSpectra_systematics_minTPCclusters(Int_t ipart, Int_t icharge, Int_t icent, TFile *fileout = NULL)
+{
+  const Int_t ndata = 2;
+  const Char_t *name[ndata] = {
+    "standardPrimaryCuts_minTPCclusters_60",
+    "standardPrimaryCuts_minTPCclusters_80"
+  };
+  const Char_t *title[ndata] = {
+    "N_{TPC-cls}^{min} = 60;p_{T} (GeV/c); ratio",
+    "N_{TPC-cls}^{min} = 80;p_{T} (GeV/c); ratio"
+  };
+  Int_t marker[ndata] = {22, 28};
+  Int_t color[ndata] = {2, 8};
+
+  TH1D *hArea = new TH1D("hArea", Form("%s (%d-%d%%);p_{T} (GeV/c);ratio;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]), NptBins, ptBin);
+  hArea->SetMinimum(0.9);
+  hArea->SetMaximum(1.1);
+  hArea->SetStats(kFALSE);
+  hArea->Draw();
+  
+  TH1D *hr[ndata];
+  for (Int_t idata = 0; idata < ndata; idata++) {
+    hr[idata] = FinalSpectra_systematics_ratio(name[idata], "standardPrimaryCuts", ipart, icharge, icent, name[idata], title[idata], marker[idata], color[idata]);
+    hr[idata]->Draw("same");
+  }
+
+  gPad->SetGridy();
+  TLegend *legend = gPad->BuildLegend();
+  legend->DeleteEntry();
+  legend->SetFillColor(0);
+  legend->SetBorderSize(1);
+  if (fileout) {
+    fileout->cd();
+    gPad->Write(Form("cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+  }
+}
+
+FinalSpectra_systematics_scaleDCAxy()
+{
+  
+  TFile *fileout = TFile::Open("FinalSpectra_systematics_scaleDCAxy.root", "RECREATE");
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       FinalSpectra_systematics_scaleDCAxy(ipart, icharge, icent, fileout);
+      }
+  fileout->Close();
+}
+
+FinalSpectra_systematics_scaleDCAxy(Int_t ipart, Int_t icharge, Int_t icent, TFile *fileout = NULL)
+{
+  const Int_t ndata = 2;
+  const Char_t *name[ndata] = {
+    "standardPrimaryCuts_scaleDCAxy_09",
+    "standardPrimaryCuts_scaleDCAxy_11"
+  };
+  const Char_t *title[ndata] = {
+    "-10% DCA_{xy} cut;p_{T} (GeV/c); ratio",
+    "+10% DCA_{xy} cut;p_{T} (GeV/c); ratio"
+  };
+  Int_t marker[ndata] = {22, 28};
+  Int_t color[ndata] = {2, 8};
+
+  TH1D *hArea = new TH1D("hArea", Form("%s (%d-%d%%);p_{T} (GeV/c);ratio;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]), NptBins, ptBin);
+  hArea->SetMinimum(0.9);
+  hArea->SetMaximum(1.1);
+  hArea->SetStats(kFALSE);
+  hArea->Draw();
+  
+  TH1D *hr[ndata];
+  for (Int_t idata = 0; idata < ndata; idata++) {
+    hr[idata] = FinalSpectra_systematics_ratio(name[idata], "standardPrimaryCuts", ipart, icharge, icent, name[idata], title[idata], marker[idata], color[idata]);
+    hr[idata]->Draw("same");
+  }
+
+  gPad->SetGridy();
+  TLegend *legend = gPad->BuildLegend();
+  legend->DeleteEntry();
+  legend->SetFillColor(0);
+  legend->SetBorderSize(1);
+  if (fileout) {
+    fileout->cd();
+    gPad->Write(Form("cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+  }
+}
+
+TH1D *
+FinalSpectra_systematics_ratio(const Char_t *dirname1, const Char_t *dirname2, Int_t ipart, Int_t icharge, Int_t icent, const Char_t *name = "finalRatio", const Char_t *title = ";p_{T} (GeV/c);final yield ratio;", Int_t marker = 20, Int_t color = 2, Bool_t correlated = kFALSE)
+{
+
+  TH1D *hr = new TH1D("hr", "", NptBins, ptBin);
+
+  /* open data */
+  Char_t outfilename1[1024];
+  sprintf(outfilename1, "%s/TOF_finalSpectra.root", dirname1);
+  TFile *filein1 = TFile::Open(outfilename1);
+  if (!filein1 || !filein1->IsOpen()) {
+    printf("cannot open %s\n", outfilename1);
+    return;
+  }
+  Char_t outfilename2[1024];
+  sprintf(outfilename2, "%s/TOF_finalSpectra.root", dirname2);
+  TFile *filein2 = TFile::Open(outfilename2);
+  if (!filein2 || !filein2->IsOpen()) {
+    printf("cannot open %s\n", outfilename2);
+    return;
+  }
+  /* get data */
+  TH1D *h1 = (TH1D *)filein1->Get(Form("hFinal_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+  if (!h1) {
+    printf("cannot get hFinal_cent%d_%s_%s from %s\n", icent, AliPID::ParticleName(ipart), chargeName[icharge], outfilename1);
+    return;
+  }
+  TH1D *h2 = (TH1D *)filein2->Get(Form("hFinal_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+  if (!h2) {
+    printf("cannot get hFinal_cent%d_%s_%s from %s\n", icent, AliPID::ParticleName(ipart), chargeName[icharge], outfilename2);
+    return;
+  }
+  /* ratio */
+  if (correlated) hr->Divide(h1, h2, 1., 1., "B");
+  else hr->Divide(h1, h2);
+  hr->SetNameTitle(name, title);
+  hr->SetMarkerStyle(marker);
+  hr->SetMarkerColor(color);
+  
+  filein1->Close();
+  filein2->Close();
+  
+  return hr;
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFcalib.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFcalib.C
new file mode 100644 (file)
index 0000000..c85424a
--- /dev/null
@@ -0,0 +1,194 @@
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative",
+};
+
+TOFcalib_centrality(const Char_t *filename, Int_t evMax = kMaxInt)
+{
+
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* histos */
+  TH2F *hTOFcalib_centrality = new TH2F("hTOFcalib_centrality", "", 18, 0., 90., 200, -2440., 2440.);
+
+  /* loop over events */
+  Double_t cent, p, time, t0, tof, texp, deltat, timezerocorr, texpcorr;
+  for (Int_t iev = 0; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 1000 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+    
+    /*** ACCEPTED EVENT ***/
+
+    /* apply time-zero TOF correction */
+    analysisEvent->ApplyTimeZeroTOFCorrection();
+    
+    /* get centrality */
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check TOF PID */
+      if (!analysisTrack->HasTOFPID()) continue;
+
+      /*** ACCEPTED TRACK WITH TOF PID ***/
+
+      /* apply expected time correction */
+      analysisTrack->ApplyTOFExpectedTimeCorrection();
+
+      p = analysisTrack->GetP();
+      time = analysisTrack->GetTOFTime();
+      t0 = analysisEvent->GetTimeZeroTOF(p);
+      tof = time - t0;
+      texp = analysisTrack->GetTOFExpTime(AliPID::kPion);
+      deltat = tof - texp;
+
+      hTOFcalib_centrality->Fill(cent, deltat);
+
+      } /* end of loop over particles */
+  } /* end of loop over events */
+
+  /* output */
+  TFile *fileout = TFile::Open(Form("TOFcalib_centrality.%s", filename), "RECREATE");
+  hTOFcalib_centrality->Write();
+  fileout->Close();
+
+}
+
+TOFcalib_texp(const Char_t *filename, Int_t evMax = kMaxInt)
+{
+
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* histos */
+  TH2F *hTOFcalib_texp[AliPID::kSPECIES][kNCharges];
+  TH2F *hTOFcalib_texpr[AliPID::kSPECIES][kNCharges];
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hTOFcalib_texp[ipart][icharge] = new TH2F(Form("hTOFcalib_texp_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "", 100., 0., 5., 400, -4880., 4880.);
+      hTOFcalib_texpr[ipart][icharge] = new TH2F(Form("hTOFcalib_texpr_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "", 100., 0., 5., 400, 0.8, 1.2);
+    }
+  }
+
+  /* loop over events */
+  Int_t charge;
+  Double_t cent, p, pt, time, t0, tof, texp, deltat, timezerocorr, texpcorr;
+  for (Int_t iev = 0; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 1000 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+    
+    /*** ACCEPTED EVENT ***/
+
+    /* apply time-zero TOF correction */
+    analysisEvent->ApplyTimeZeroTOFCorrection();
+    
+    /* get centrality */
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+    //    if (cent > 90.) continue;
+
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check eta */
+      if (TMath::Abs(analysisTrack->GetEta()) > 0.8) continue;
+      /* check TOF PID */
+      if (!analysisTrack->HasTOFPID()) continue;
+      /* get charge */
+      charge = analysisTrack->GetSign() > 0. ? kPositive : kNegative;
+      
+      /*** ACCEPTED TRACK WITH TOF PID ***/
+
+      /* apply expected time correction */
+      analysisTrack->ApplyTOFExpectedTimeCorrection();
+
+      p = analysisTrack->GetP();
+      time = analysisTrack->GetTOFTime();
+      t0 = analysisEvent->GetTimeZeroTOF(p);
+      tof = time - t0;
+
+      /* loop over species */
+      for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+       
+       texp = analysisTrack->GetTOFExpTime(ipart);
+       deltat = tof - texp;
+
+       hTOFcalib_texp[ipart][charge]->Fill(p, deltat);
+       hTOFcalib_texpr[ipart][charge]->Fill(p, tof / texp);
+
+      }/* end of loop over species */
+    } /* end of loop over tracks */
+  } /* end of loop over events */
+
+  /* output */
+  TFile *fileout = TFile::Open(Form("TOFcalib_texp.%s", filename), "RECREATE");
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hTOFcalib_texp[ipart][icharge]->Write();
+      hTOFcalib_texpr[ipart][icharge]->Write();
+    }
+  }
+  fileout->Close();
+
+}
+
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFcalibMC.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFcalibMC.C
new file mode 100644 (file)
index 0000000..929dd9d
--- /dev/null
@@ -0,0 +1,195 @@
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative",
+};
+
+TOFcalibMC_centrality(const Char_t *filename, Int_t evMax = kMaxInt)
+{
+
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* histos */
+  TH2F *hTOFcalib_centrality = new TH2F("hTOFcalib_centrality", "", 18, 0., 90., 200, -2440., 2440.);
+
+  /* loop over events */
+  Double_t cent, p, time, t0, tof, texp, deltat, timezerocorr, texpcorr;
+  for (Int_t iev = 0; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 1000 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+    
+    /*** ACCEPTED EVENT ***/
+
+    /* apply time-zero TOF correction */
+    analysisEvent->ApplyTimeZeroTOFCorrection();
+    
+    /* get centrality */
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check TOF PID */
+      if (!analysisTrack->HasTOFPID()) continue;
+
+      /*** ACCEPTED TRACK WITH TOF PID ***/
+
+      /* apply expected time correction */
+      analysisTrack->ApplyTOFExpectedTimeCorrection();
+
+      p = analysisTrack->GetP();
+      time = analysisTrack->GetTOFTime();
+      t0 = analysisEvent->GetTimeZeroTOF(p);
+      tof = time - t0;
+      texp = analysisTrack->GetTOFExpTime(AliPID::kPion);
+      deltat = tof - texp;
+
+      hTOFcalib_centrality->Fill(cent, deltat);
+
+      } /* end of loop over particles */
+  } /* end of loop over events */
+
+  /* output */
+  TFile *fileout = TFile::Open(Form("TOFcalibMC_centrality.%s", filename), "RECREATE");
+  hTOFcalib_centrality->Write();
+  fileout->Close();
+
+}
+
+TOFcalibMC_texp(const Char_t *filename, Int_t evMax = kMaxInt)
+{
+
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* histos */
+  TH2F *hTOFcalib_texp[AliPID::kSPECIES][kNCharges];
+  TH2F *hTOFcalib_texpr[AliPID::kSPECIES][kNCharges];
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hTOFcalib_texp[ipart][icharge] = new TH2F(Form("hTOFcalib_texp_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "", 100., 0., 5., 400, -4880., 4880.);
+      hTOFcalib_texpr[ipart][icharge] = new TH2F(Form("hTOFcalib_texpr_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "", 100., 0., 5., 400, 0.8, 1.2);
+    }
+  }
+
+  /* loop over events */
+  Int_t charge;
+  Double_t cent, p, pt, time, t0, tof, texp, deltat, timezerocorr, texpcorr;
+  for (Int_t iev = 0; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 1000 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+    
+    /*** ACCEPTED EVENT ***/
+
+    /* apply time-zero TOF correction */
+    analysisEvent->ApplyTimeZeroTOFCorrection();
+    
+    /* get centrality */
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+    //    if (cent > 90.) continue;
+
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check eta */
+      if (TMath::Abs(analysisTrack->GetEta()) > 0.8) continue;
+      /* check TOF PID */
+      if (!analysisTrack->HasTOFPID()) continue;
+      /* get charge */
+      charge = analysisTrack->GetSign() > 0. ? kPositive : kNegative;
+      /* check charged primary with defined PID */
+      Int_t ipart = analysisTrack->GetMCPID();
+      if (!analysisTrack->IsMCPrimary() || ipart < 0 || analysisTrack->GetSign() == 0.) continue;
+      /* check mismatch */
+      if (analysisTrack->IsMismatchMC()) continue;
+
+      /*** ACCEPTED TRACK WITH TOF PID ***/
+
+      /* apply expected time correction */
+      //      analysisTrack->ApplyTOFExpectedTimeCorrection();
+
+      p = analysisTrack->GetP();
+      time = analysisTrack->GetTOFTime();
+      t0 = analysisEvent->GetTimeZeroTOF(p);
+      tof = time - t0;
+
+      texp = analysisTrack->GetTOFExpTime(ipart);
+      deltat = tof - texp;
+      
+      hTOFcalib_texp[ipart][charge]->Fill(p, deltat);
+      hTOFcalib_texpr[ipart][charge]->Fill(p, tof / texp);
+      
+    } /* end of loop over tracks */
+  } /* end of loop over events */
+
+  /* output */
+  TFile *fileout = TFile::Open(Form("TOFcalibMC_texp.%s", filename), "RECREATE");
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hTOFcalib_texp[ipart][icharge]->Write();
+      hTOFcalib_texpr[ipart][icharge]->Write();
+    }
+  }
+  fileout->Close();
+
+}
+
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFmatchEff.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFmatchEff.C
new file mode 100644 (file)
index 0000000..a3e0594
--- /dev/null
@@ -0,0 +1,1459 @@
+enum EHisto_t {
+  kAcceptedTracks,
+  kMatchedTracks,
+  kMismatchedTracks,
+  kUncorrelatedTracks,
+  kMatchedCorrelatedTracks,
+  kMatchedGoodTracks,
+  kNHistos
+};
+const Char_t *histoName[kNHistos] = {
+  "hAcceptedTracks",
+  "hMatchedTracks",
+  "hMismatchedTracks",
+  "hUncorrelatedTracks",
+  "hMatchedCorrelatedTracks",
+  "hMatchedGoodTracks"
+};
+
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative"
+};
+
+enum EParam_t {
+  kCentrality,
+  kPt,
+  kEta,
+  kPhi,
+  kNParams
+};
+
+const Int_t NcentralityBins = 10;
+Double_t centralityBin[NcentralityBins + 1] = {0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.};
+
+const Int_t NptBins = 46;
+Double_t ptBin[NptBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+
+const Int_t NetaBins = 20;
+Double_t etaMin = -1.;
+Double_t etaMax = 1.;
+Double_t etaStep = (etaMax - etaMin) / NetaBins;
+Double_t etaBin[NetaBins + 1]; /* computed at run-time */
+
+const Int_t NphiBins = 200;
+Double_t phiMin = 0.;
+Double_t phiMax = 2. * TMath::Pi();
+Double_t phiStep = (phiMax - phiMin) / NphiBins;
+Double_t phiBin[NphiBins + 1]; /* computed at run-time */
+
+const Int_t NptsubBins = 5;
+Double_t ptsubBin[NptsubBins + 1] = {0.2, 0.5, 1.0, 1.5, 3.0, 5.0};
+Int_t ptsubBinMin[NptsubBins] = {0, 6, 16, 21, 36};
+Int_t ptsubBinMax[NptsubBins] = {5, 15, 20, 35, 45};
+
+Int_t multcentColor[10] = {
+  kRed,
+  kOrange+1,
+  kOrange,
+  kYellow,
+  kYellow+1,
+  kGreen,
+  kGreen+1,
+  kCyan+1,
+  kBlue,
+  kMagenta,
+  //  kMagenta+1  
+};
+
+const Char_t *extendedChargeName[2] = {"positive", "negative"};
+
+const Double_t kEpsilon = 0.001;
+
+TOFmatchEff(const Char_t *filename, const Char_t *enabledfilename = NULL, Int_t evMax = kMaxInt)
+{
+  
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* open enabled flag map */
+  TH1F *hEnabledFlag = NULL;
+  if (enabledfilename) {
+    TFile *enabledfile = TFile::Open(enabledfilename);
+    hEnabledFlag = (TH1F *)enabledfile->Get("hEnabledFlag");
+  }
+
+  /* binning */
+  for (Int_t ieta = 0; ieta < NetaBins + 1; ieta++)
+    etaBin[ieta] = etaMin + ieta * etaStep;
+  for (Int_t iphi = 0; iphi < NphiBins + 1; iphi++)
+    phiBin[iphi] = phiMin + iphi * phiStep;
+  /* THnSparse */
+  Int_t NparamBins[kNParams] = {NcentralityBins, NptBins, NetaBins, NphiBins};
+  Double_t *paramBin[kNParams] = {centralityBin, ptBin, etaBin, phiBin};
+  THnSparseF *hHisto[kNHistos][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hHisto[ihisto][icharge] = new THnSparseF(Form("hHisto_%s_%s", histoName[ihisto], chargeName[icharge]), "", kNParams, NparamBins);
+      for (Int_t iparam = 0; iparam < kNParams; iparam++)
+       hHisto[ihisto][icharge]->SetBinEdges(iparam, paramBin[iparam]);
+    }
+#if 0
+  TH2F *hHistoPID[kNHistos][AliPID::kSPECIES][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       hHistoPID[ihisto][ipart][icharge] = new TH2F(Form("hHistoPID_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]), "", NcentralityBins, centralityBin, NptBins, ptBin);
+      }
+#endif
+  /* histos */
+  TH2F *hFEAMap = new TH2F("hFEAMap", "", 72, 0., 18., 91, 0., 91.);
+
+  /* start stopwatch */
+  TStopwatch timer;
+  timer.Start();
+  
+  /* loop over events */
+  Double_t param[kNParams];
+  Int_t charge;
+  Int_t index, sector, sectorStrip, padx, fea;
+  Float_t hitmapx, hitmapy;
+  AliTOFcalibHisto calib;
+  calib.LoadCalibHisto();
+  for (Int_t iev = 0; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 1000 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+
+    /*** ACCEPTED EVENT ***/
+
+    /* get centrality */
+    param[kCentrality] = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+    
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check accepted track */
+      if (!analysisTrack->AcceptTrack()) continue;
+
+      /*** ACCEPTED TRACK ***/
+      
+      /* get track info */
+      param[kPt] = analysisTrack->GetPt();
+      param[kEta] = analysisTrack->GetEta();
+      param[kPhi] = analysisTrack->GetPhi();
+      charge = analysisTrack->GetSign() > 0. ? kPositive : kNegative;
+      index = analysisTrack->GetTOFIndex();
+      
+      /* fill accepted tracks histos */
+      hHisto[kAcceptedTracks][charge]->Fill(param);
+#if 0
+      for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+       if (TMath::Abs(analysisTrack->GetY(AliPID::ParticleMass(ipart))) > 0.5) continue;
+       hHistoPID[kAcceptedTracks][ipart][charge]->Fill(param[kCentrality], param[kPt]);
+      }
+#endif
+
+      /* check TOF PID */
+      if (!analysisTrack->HasTOFPID()) continue;
+      /* check channel enabled */
+      //      if (hEnabledFlag && hEnabledFlag->GetBinContent(index + 1) == 0.) continue;
+
+      /*** ACCEPTED TRACK WITH TOF SIGNAL ***/
+
+      /* fill FEA map */
+      sector = calib.GetCalibMap(AliTOFcalibHisto::kSector, index);
+      sectorStrip = calib.GetCalibMap(AliTOFcalibHisto::kSectorStrip, index);
+      padx = calib.GetCalibMap(AliTOFcalibHisto::kPadX, index);
+      fea = padx / 12;
+      hitmapx = sector + ((Double_t)(3 - fea) + 0.5) / 4.;
+      hitmapy = sectorStrip;
+      hFEAMap->Fill(hitmapx, hitmapy);
+      
+      /* fill matched tracks histos */
+      hHisto[kMatchedTracks][charge]->Fill(param);
+      if (!analysisTrack->IsMismatchMC()) {
+       hHisto[kMatchedGoodTracks][charge]->Fill(param);
+       hHisto[kMatchedCorrelatedTracks][charge]->Fill(param);
+      }
+      else {
+       hHisto[kMismatchedTracks][charge]->Fill(param);
+       if (!analysisTrack->IsUncorrelatedMismatchMC())
+         hHisto[kMatchedCorrelatedTracks][charge]->Fill(param);
+       else
+         hHisto[kUncorrelatedTracks][charge]->Fill(param);
+      }
+#if 0
+      for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+       if (TMath::Abs(analysisTrack->GetY(AliPID::ParticleMass(ipart))) > 0.5) continue;
+       hHistoPID[kMatchedTracks][ipart][charge]->Fill(param[kCentrality], param[kPt]);
+       if (!analysisTrack->IsMismatchMC()) {
+         hHistoPID[kMatchedGoodTracks][charge]->Fill(param);
+         hHistoPID[kMatchedCorrelatedTracks][charge]->Fill(param);
+       }
+       else {
+         hHistoPID[kMismatchedTracks][charge]->Fill(param);
+         if (!analysisTrack->IsUncorrelatedMismatchMC())
+           hHistoPID[kMatchedCorrelatedTracks][charge]->Fill(param);
+         else
+           hHistoPID[kUncorrelatedTracks][charge]->Fill(param);
+       }
+      }
+#endif
+    }
+  }
+
+  /* stop stopwatch */
+  timer.Stop();
+  timer.Print();
+
+  TFile *fileout = TFile::Open(Form("TOFmatchEff.%s", filename), "RECREATE");
+  hFEAMap->Write();
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      hHisto[ihisto][icharge]->Write();
+    }
+#if 0
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       hHistoPID[ihisto][ipart][icharge]->Write();
+      }
+#endif
+  fileout->Close();
+  
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchEff_efficiencyPt(const Char_t *filename)
+{
+
+  /* get data */
+  TFile *filein = TFile::Open(filename);
+  THnSparseF *hHisto[kNHistos][kNCharges];
+  TH2F *hHistoPID[kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hHistoPt_MB[kNHistos][kNCharges], *hHistoPt_centrality[NcentralityBins][kNHistos][kNCharges];
+  TH1D *hHistoPIDPt_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hHistoPIDPt_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hHistoAllPt_MB[kNHistos], *hHistoAllPt_centrality[NcentralityBins][kNHistos];
+  /* loop over histos */
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+
+    /* INCLUSIVE */
+
+    hHistoAllPt_MB[ihisto] = new TH1D(Form("hHistoAllPt_MB_%s", histoName[ihisto]), "", NptBins, ptBin);
+    for (Int_t icent = 0; icent < NcentralityBins; icent++)
+      hHistoAllPt_centrality[icent][ihisto] = new TH1D(Form("hHistoAllPt_centrality%d_%s", icent, histoName[ihisto]), "", NptBins, ptBin);
+
+    /* SINGLE PARTICLE */
+
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      
+      /* get histo */
+      hHisto[ihisto][icharge] = (THnSparseF *)filein->Get(Form("hHisto_%s_%s", histoName[ihisto], chargeName[icharge]));
+      
+      /* MB projection */
+      hHistoPt_MB[ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kPt);
+      hHistoPt_MB[ihisto][icharge]->SetName(Form("hHistoPt_MB_%s_%s", histoName[ihisto], chargeName[icharge]));
+      hHistoPt_MB[ihisto][icharge]->Sumw2();
+      hHistoAllPt_MB[ihisto]->Add(hHistoPt_MB[ihisto][icharge]);
+       
+      /* centrality projection */
+      for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+
+       hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+       hHistoPt_centrality[icent][ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kPt);
+       hHistoPt_centrality[icent][ihisto][icharge]->SetName(Form("hHistoPt_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hHistoPt_centrality[icent][ihisto][icharge]->Sumw2();
+       hHistoAllPt_centrality[icent][ihisto]->Add(hHistoPt_centrality[icent][ihisto][icharge]);
+      }
+      
+#if 0
+      for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+
+       /* get histo */
+       hHistoPID[ihisto][ipart][icharge] = (TH2F *)filein->Get(Form("hHistoPID_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+
+       /* MB projection */
+       hHistoPIDPt_MB[ihisto][ipart][icharge] = hHistoPID[ihisto][ipart][icharge]->ProjectionY("hpy");
+       hHistoPIDPt_MB[ihisto][ipart][icharge]->SetName(Form("hHistoPIDPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       hHistoPIDPt_MB[ihisto][ipart][icharge]->Sumw2();
+       
+       /* centrality projection */
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+         hHistoPIDPt_centrality[icent][ihisto][ipart][icharge] = hHistoPID[ihisto][ipart][icharge]->ProjectionY("hpy", icent + 1, icent + 1);
+         hHistoPIDPt_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hHistoPIDPt_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hHistoPIDPt_centrality[icent][ihisto][ipart][icharge]->Sumw2();
+
+       }
+       
+      }
+#endif
+      
+    }
+  }
+
+  /* output */
+  TString str = filename;
+  str.Insert(str.Length() - TString(".root").Length(), ".efficiencyPt");
+  TFile *fileout = TFile::Open(str.Data(), "RECREATE");
+  
+  /* efficiencies/fractions and write */
+  TH1D *hEfficiencyPt_MB[kNHistos][kNCharges], *hEfficiencyPt_centrality[NcentralityBins][kNHistos][kNCharges], *hEfficiencyPt_ratioMB_centrality[NcentralityBins][kNHistos][kNCharges];
+  TH1D *hEfficiencyPIDPt_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyPIDPt_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyPIDPt_ratioMB_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hEfficiencyAllPt_MB[kNHistos], *hEfficiencyAllPt_centrality[NcentralityBins][kNHistos], *hEfficiencyAllPt_ratioMB_centrality[NcentralityBins][kNHistos];
+
+  TH1D *hFractionPt_MB[kNHistos][kNCharges], *hFractionPt_centrality[NcentralityBins][kNHistos][kNCharges], *hFractionPt_ratioMB_centrality[NcentralityBins][kNHistos][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+    
+    if (ihisto == kAcceptedTracks) continue;
+    
+    /* INCLUSIVE */
+    
+    /* MB efficiency */
+    hEfficiencyAllPt_MB[ihisto] = new TH1D(*hHistoAllPt_MB[ihisto]);
+    hEfficiencyAllPt_MB[ihisto]->SetName(Form("hEfficiencyAllPt_MB_%s", histoName[ihisto]));
+    hEfficiencyAllPt_MB[ihisto]->SetLineWidth(2);
+    hEfficiencyAllPt_MB[ihisto]->SetLineColor(1);
+    hEfficiencyAllPt_MB[ihisto]->SetMarkerStyle(20);
+    hEfficiencyAllPt_MB[ihisto]->SetMarkerColor(1);
+    hEfficiencyAllPt_MB[ihisto]->Divide(hEfficiencyAllPt_MB[ihisto], hHistoAllPt_MB[kAcceptedTracks], 1, 1, "B");
+    hEfficiencyAllPt_MB[ihisto]->Write();
+    
+    /* multiplicity/centrality efficiency */
+    for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+      hEfficiencyAllPt_centrality[icent][ihisto] = new TH1D(*hHistoAllPt_centrality[icent][ihisto]);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetName(Form("hEfficiencyAllPt_centrality%d_%s", icent, histoName[ihisto]));
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetLineWidth(2);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetLineColor(multcentColor[icent]);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetMarkerStyle(20);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetMarkerColor(multcentColor[icent]);
+      hEfficiencyAllPt_centrality[icent][ihisto]->Divide(hEfficiencyAllPt_centrality[icent][ihisto], hHistoAllPt_centrality[icent][kAcceptedTracks], 1, 1, "B");
+      hEfficiencyAllPt_centrality[icent][ihisto]->Write();
+      
+      /* ratio wrt. MB */
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto] = new TH1D(*hEfficiencyAllPt_centrality[icent][ihisto]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetName(Form("hEfficiencyAllPt_ratioMB_centrality%d_%s", icent, histoName[ihisto]));
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetLineWidth(2);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetLineColor(multcentColor[icent]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetMarkerStyle(20);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetMarkerColor(multcentColor[icent]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->Divide(hEfficiencyAllPt_MB[ihisto]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->Write();
+    }
+    
+    /* SINGLE PARTICLE */
+    
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      
+      /* MB efficiency */
+      hEfficiencyPt_MB[ihisto][icharge] = new TH1D(*hHistoPt_MB[ihisto][icharge]);
+      hEfficiencyPt_MB[ihisto][icharge]->SetName(Form("hEfficiencyPt_MB_%s_%s", histoName[ihisto], chargeName[icharge]));
+      hEfficiencyPt_MB[ihisto][icharge]->SetLineWidth(2);
+      hEfficiencyPt_MB[ihisto][icharge]->SetLineColor(1);
+      hEfficiencyPt_MB[ihisto][icharge]->SetMarkerStyle(20);
+      hEfficiencyPt_MB[ihisto][icharge]->SetMarkerColor(1);
+      hEfficiencyPt_MB[ihisto][icharge]->Divide(hEfficiencyPt_MB[ihisto][icharge], hHistoPt_MB[kAcceptedTracks][icharge], 1, 1, "B");
+      hEfficiencyPt_MB[ihisto][icharge]->Write();
+      
+      /* multiplicity/centrality efficiency */
+      for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+       hEfficiencyPt_centrality[icent][ihisto][icharge] = new TH1D(*hHistoPt_centrality[icent][ihisto][icharge]);
+       hEfficiencyPt_centrality[icent][ihisto][icharge]->SetName(Form("hEfficiencyPt_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyPt_centrality[icent][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyPt_centrality[icent][ihisto][icharge]->SetLineColor(multcentColor[icent]);
+       hEfficiencyPt_centrality[icent][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyPt_centrality[icent][ihisto][icharge]->SetMarkerColor(multcentColor[icent]);
+       hEfficiencyPt_centrality[icent][ihisto][icharge]->Divide(hEfficiencyPt_centrality[icent][ihisto][icharge], hHistoPt_centrality[icent][kAcceptedTracks][icharge], 1, 1, "B");
+       hEfficiencyPt_centrality[icent][ihisto][icharge]->Write();
+       
+       /* ratio wrt. MB */
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge] = new TH1D(*hEfficiencyPt_centrality[icent][ihisto][icharge]);
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge]->SetName(Form("hEfficiencyPt_ratioMB_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge]->SetLineColor(multcentColor[icent]);
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge]->SetMarkerColor(multcentColor[icent]);
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge]->Divide(hEfficiencyPt_MB[ihisto][icharge]);
+       hEfficiencyPt_ratioMB_centrality[icent][ihisto][icharge]->Write();
+      }
+     
+#if 0
+      for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+
+       /* MB efficiency */
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge] = new TH1D(*hHistoPIDPt_MB[ihisto][ipart][icharge]);
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge]->SetName(Form("hEfficiencyPIDPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge]->SetLineWidth(2);
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge]->SetLineColor(1);
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge]->SetMarkerStyle(20);
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge]->SetMarkerColor(1);
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge]->Divide(hEfficiencyPIDPt_MB[ihisto][ipart][icharge], hHistoPIDPt_MB[kAcceptedTracks][ipart][icharge], 1, 1, "B");
+       hEfficiencyPIDPt_MB[ihisto][ipart][icharge]->Write();
+       
+       /* multiplicity/centrality efficiency */
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hHistoPIDPt_centrality[icent][ihisto][ipart][icharge]);
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hEfficiencyPIDPt_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]->Divide(hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge], hHistoPIDPt_centrality[icent][kAcceptedTracks][ipart][icharge], 1, 1, "B");
+         hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]->Write();
+
+         /* ratio wrt. MB */
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hEfficiencyPIDPt_centrality[icent][ihisto][ipart][icharge]);
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hEfficiencyPIDPt_ratioMB_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->Divide(hEfficiencyPIDPt_MB[ihisto][ipart][icharge]);
+         hEfficiencyPIDPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->Write();
+       }
+       
+       
+      }
+#endif
+      
+    }       
+  }
+  
+  fileout->Close();
+            
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchEff_efficiencyPhi(const Char_t *filename)
+{
+
+  /* get data */
+  TFile *filein = TFile::Open(filename);
+  THnSparseF *hHisto[kNHistos][kNCharges];
+  TH1D *hHistoPhi_MB[kNHistos][kNCharges], *hHistoPhi_centrality[NcentralityBins][kNHistos][kNCharges];
+  TH1D *hHistoPhi_MB_pt[NptsubBins][kNHistos][kNCharges], *hHistoPhi_centrality_pt[NcentralityBins][NptsubBins][kNHistos][kNCharges];
+  /* loop over histos */
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      
+      /* get histo */
+      hHisto[ihisto][icharge] = (THnSparseF *)filein->Get(Form("hHisto_%s_%s", histoName[ihisto], chargeName[icharge]));
+      
+      /* MB projection */
+      hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(0, 0);
+      hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(0, 0);
+      hHistoPhi_MB[ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kPhi);
+      hHistoPhi_MB[ihisto][icharge]->SetName(Form("hHistoPhi_MB_%s_%s", histoName[ihisto], chargeName[icharge]));
+      hHistoPhi_MB[ihisto][icharge]->Sumw2();
+      /* pt bins */
+      for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+       hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(ptsubBinMin[ipt] + 1, ptsubBinMax[ipt] + 1);
+       hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(0, 0);
+       hHistoPhi_MB_pt[ipt][ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kPhi);
+       hHistoPhi_MB_pt[ipt][ihisto][icharge]->SetName(Form("hHistoPhi_MB_pt%d_%s_%s", ipt, histoName[ihisto], chargeName[icharge]));
+       hHistoPhi_MB_pt[ipt][ihisto][icharge]->Sumw2();
+      }
+      
+      /* centrality projection */
+      for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+       hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(0, 0);
+       hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+       hHistoPhi_centrality[icent][ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kPhi);
+       hHistoPhi_centrality[icent][ihisto][icharge]->SetName(Form("hHistoPhi_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hHistoPhi_centrality[icent][ihisto][icharge]->Sumw2();
+       /* pt bins */
+       for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+         hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(ptsubBinMin[ipt] + 1, ptsubBinMax[ipt] + 1);
+         hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+         hHistoPhi_centrality_pt[icent][ipt][ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kPhi);
+         hHistoPhi_centrality_pt[icent][ipt][ihisto][icharge]->SetName(Form("hHistoPhi_centrality%d_pt%d_%s_%s", icent, ipt, histoName[ihisto], chargeName[icharge]));
+         hHistoPhi_centrality_pt[icent][ipt][ihisto][icharge]->Sumw2();
+       }
+      }
+    }
+  
+  /* output */
+  TString str = filename;
+  str.Insert(str.Length() - TString(".root").Length(), ".efficiencyPhi");
+  TFile *fileout = TFile::Open(str.Data(), "RECREATE");
+  
+  /* efficiencies/fractions and write */
+  TH1D *hEfficiencyPhi_MB[kNHistos][kNCharges], *hEfficiencyPhi_centrality[NcentralityBins][kNHistos][kNCharges], *hEfficiencyPhi_ratioMB_centrality[NcentralityBins][kNHistos][kNCharges];
+  TH1D *hEfficiencyPhi_MB_pt[NptsubBins][kNHistos][kNCharges], *hEfficiencyPhi_centrality_pt[NcentralityBins][NptsubBins][kNHistos][kNCharges], *hEfficiencyPhi_ratioMB_centrality_pt[NcentralityBins][NptsubBins][kNHistos][kNCharges];
+
+
+  TH1D *hFractionPhi_MB[kNHistos][kNCharges], *hFractionPhi_centrality[NcentralityBins][kNHistos][kNCharges], *hFractionPhi_ratioMB_centrality[NcentralityBins][kNHistos][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      
+      if (ihisto == kAcceptedTracks) continue;
+      
+      /* MB efficiency */
+      hEfficiencyPhi_MB[ihisto][icharge] = new TH1D(*hHistoPhi_MB[ihisto][icharge]);
+      hEfficiencyPhi_MB[ihisto][icharge]->SetName(Form("hEfficiencyPhi_MB_%s_%s", histoName[ihisto], chargeName[icharge]));
+      hEfficiencyPhi_MB[ihisto][icharge]->SetLineWidth(2);
+      hEfficiencyPhi_MB[ihisto][icharge]->SetLineColor(1);
+      hEfficiencyPhi_MB[ihisto][icharge]->SetMarkerStyle(20);
+      hEfficiencyPhi_MB[ihisto][icharge]->SetMarkerColor(1);
+      hEfficiencyPhi_MB[ihisto][icharge]->Divide(hEfficiencyPhi_MB[ihisto][icharge], hHistoPhi_MB[kAcceptedTracks][icharge], 1, 1, "B");
+      hEfficiencyPhi_MB[ihisto][icharge]->Write();
+      /* pt bins */
+      for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge] = new TH1D(*hHistoPhi_MB_pt[ipt][ihisto][icharge]);
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge]->SetName(Form("hEfficiencyPhi_MB_pt%d_%s_%s", ipt, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge]->SetLineColor(1);
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge]->SetMarkerColor(1);
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge]->Divide(hEfficiencyPhi_MB_pt[ipt][ihisto][icharge], hHistoPhi_MB_pt[ipt][kAcceptedTracks][icharge], 1, 1, "B");
+       hEfficiencyPhi_MB_pt[ipt][ihisto][icharge]->Write();
+      }
+      
+      /* multiplicity/centrality efficiency */
+      for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+       hEfficiencyPhi_centrality[icent][ihisto][icharge] = new TH1D(*hHistoPhi_centrality[icent][ihisto][icharge]);
+       hEfficiencyPhi_centrality[icent][ihisto][icharge]->SetName(Form("hEfficiencyPhi_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyPhi_centrality[icent][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyPhi_centrality[icent][ihisto][icharge]->SetLineColor(multcentColor[icent]);
+       hEfficiencyPhi_centrality[icent][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyPhi_centrality[icent][ihisto][icharge]->SetMarkerColor(multcentColor[icent]);
+       hEfficiencyPhi_centrality[icent][ihisto][icharge]->Divide(hEfficiencyPhi_centrality[icent][ihisto][icharge], hHistoPhi_centrality[icent][kAcceptedTracks][icharge], 1, 1, "B");
+       hEfficiencyPhi_centrality[icent][ihisto][icharge]->Write();
+       
+       /* ratio wrt. MB */
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge] = new TH1D(*hEfficiencyPhi_centrality[icent][ihisto][icharge]);
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge]->SetName(Form("hEfficiencyPhi_ratioMB_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge]->SetLineColor(multcentColor[icent]);
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge]->SetMarkerColor(multcentColor[icent]);
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge]->Divide(hEfficiencyPhi_MB[ihisto][icharge]);
+       hEfficiencyPhi_ratioMB_centrality[icent][ihisto][icharge]->Write();
+      }
+      
+    }       
+  }
+  
+  fileout->Close();
+            
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchEff_efficiencyEta(const Char_t *filename)
+{
+
+  /* get data */
+  TFile *filein = TFile::Open(filename);
+  THnSparseF *hHisto[kNHistos][kNCharges];
+  TH1D *hHistoEta_MB[kNHistos][kNCharges], *hHistoEta_centrality[NcentralityBins][kNHistos][kNCharges];
+  TH1D *hHistoEta_MB_pt[NptsubBins][kNHistos][kNCharges], *hHistoEta_centrality_pt[NcentralityBins][NptsubBins][kNHistos][kNCharges];
+  /* loop over histos */
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      
+      /* get histo */
+      hHisto[ihisto][icharge] = (THnSparseF *)filein->Get(Form("hHisto_%s_%s", histoName[ihisto], chargeName[icharge]));
+      
+      /* MB projection */
+      hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(0, 0);
+      hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(0, 0);
+      hHistoEta_MB[ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kEta);
+      hHistoEta_MB[ihisto][icharge]->SetName(Form("hHistoEta_MB_%s_%s", histoName[ihisto], chargeName[icharge]));
+      hHistoEta_MB[ihisto][icharge]->Sumw2();
+      /* pt bins */
+      for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+       hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(ptsubBinMin[ipt] + 1, ptsubBinMax[ipt] + 1);
+       hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(0, 0);
+       hHistoEta_MB_pt[ipt][ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kEta);
+       hHistoEta_MB_pt[ipt][ihisto][icharge]->SetName(Form("hHistoEta_MB_pt%d_%s_%s", ipt, histoName[ihisto], chargeName[icharge]));
+       hHistoEta_MB_pt[ipt][ihisto][icharge]->Sumw2();
+      }
+      
+      /* centrality projection */
+      for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+       hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(0, 0);
+       hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+       hHistoEta_centrality[icent][ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kEta);
+       hHistoEta_centrality[icent][ihisto][icharge]->SetName(Form("hHistoEta_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hHistoEta_centrality[icent][ihisto][icharge]->Sumw2();
+       /* pt bins */
+       for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+         hHisto[ihisto][icharge]->GetAxis(kPt)->SetRange(ptsubBinMin[ipt] + 1, ptsubBinMax[ipt] + 1);
+         hHisto[ihisto][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+         hHistoEta_centrality_pt[icent][ipt][ihisto][icharge] = hHisto[ihisto][icharge]->Projection(kEta);
+         hHistoEta_centrality_pt[icent][ipt][ihisto][icharge]->SetName(Form("hHistoEta_centrality%d_pt%d_%s_%s", icent, ipt, histoName[ihisto], chargeName[icharge]));
+         hHistoEta_centrality_pt[icent][ipt][ihisto][icharge]->Sumw2();
+       }
+      }
+    }
+  
+  /* output */
+  TString str = filename;
+  str.Insert(str.Length() - TString(".root").Length(), ".efficiencyEta");
+  TFile *fileout = TFile::Open(str.Data(), "RECREATE");
+  
+  /* efficiencies/fractions and write */
+  TH1D *hEfficiencyEta_MB[kNHistos][kNCharges], *hEfficiencyEta_centrality[NcentralityBins][kNHistos][kNCharges], *hEfficiencyEta_ratioMB_centrality[NcentralityBins][kNHistos][kNCharges];
+  TH1D *hEfficiencyEta_MB_pt[NptsubBins][kNHistos][kNCharges], *hEfficiencyEta_centrality_pt[NcentralityBins][NptsubBins][kNHistos][kNCharges], *hEfficiencyEta_ratioMB_centrality_pt[NcentralityBins][NptsubBins][kNHistos][kNCharges];
+
+
+  TH1D *hFractionEta_MB[kNHistos][kNCharges], *hFractionEta_centrality[NcentralityBins][kNHistos][kNCharges], *hFractionEta_ratioMB_centrality[NcentralityBins][kNHistos][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+      
+      if (ihisto == kAcceptedTracks) continue;
+      
+      /* MB efficiency */
+      hEfficiencyEta_MB[ihisto][icharge] = new TH1D(*hHistoEta_MB[ihisto][icharge]);
+      hEfficiencyEta_MB[ihisto][icharge]->SetName(Form("hEfficiencyEta_MB_%s_%s", histoName[ihisto], chargeName[icharge]));
+      hEfficiencyEta_MB[ihisto][icharge]->SetLineWidth(2);
+      hEfficiencyEta_MB[ihisto][icharge]->SetLineColor(1);
+      hEfficiencyEta_MB[ihisto][icharge]->SetMarkerStyle(20);
+      hEfficiencyEta_MB[ihisto][icharge]->SetMarkerColor(1);
+      hEfficiencyEta_MB[ihisto][icharge]->Divide(hEfficiencyEta_MB[ihisto][icharge], hHistoEta_MB[kAcceptedTracks][icharge], 1, 1, "B");
+      hEfficiencyEta_MB[ihisto][icharge]->Write();
+      /* pt bins */
+      for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge] = new TH1D(*hHistoEta_MB_pt[ipt][ihisto][icharge]);
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge]->SetName(Form("hEfficiencyEta_MB_pt%d_%s_%s", ipt, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge]->SetLineColor(1);
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge]->SetMarkerColor(1);
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge]->Divide(hEfficiencyEta_MB_pt[ipt][ihisto][icharge], hHistoEta_MB_pt[ipt][kAcceptedTracks][icharge], 1, 1, "B");
+       hEfficiencyEta_MB_pt[ipt][ihisto][icharge]->Write();
+      }
+      
+      /* multiplicity/centrality efficiency */
+      for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+       hEfficiencyEta_centrality[icent][ihisto][icharge] = new TH1D(*hHistoEta_centrality[icent][ihisto][icharge]);
+       hEfficiencyEta_centrality[icent][ihisto][icharge]->SetName(Form("hEfficiencyEta_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyEta_centrality[icent][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyEta_centrality[icent][ihisto][icharge]->SetLineColor(multcentColor[icent]);
+       hEfficiencyEta_centrality[icent][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyEta_centrality[icent][ihisto][icharge]->SetMarkerColor(multcentColor[icent]);
+       hEfficiencyEta_centrality[icent][ihisto][icharge]->Divide(hEfficiencyEta_centrality[icent][ihisto][icharge], hHistoEta_centrality[icent][kAcceptedTracks][icharge], 1, 1, "B");
+       hEfficiencyEta_centrality[icent][ihisto][icharge]->Write();
+       
+       /* ratio wrt. MB */
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge] = new TH1D(*hEfficiencyEta_centrality[icent][ihisto][icharge]);
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge]->SetName(Form("hEfficiencyEta_ratioMB_centrality%d_%s_%s", icent, histoName[ihisto], chargeName[icharge]));
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge]->SetLineWidth(2);
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge]->SetLineColor(multcentColor[icent]);
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge]->SetMarkerStyle(20);
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge]->SetMarkerColor(multcentColor[icent]);
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge]->Divide(hEfficiencyEta_MB[ihisto][icharge]);
+       hEfficiencyEta_ratioMB_centrality[icent][ihisto][icharge]->Write();
+      }
+      
+    }       
+  }
+  
+  fileout->Close();
+            
+}
+
+#if 0
+//_____________________________________________________________________________-
+
+TOFmatchMC_efficiencyCent(const Char_t *filename, const Char_t *particle = "", const Char_t *charge = "", const Char_t *trdmode = "")
+{
+
+  const Int_t npt = 4;
+  Double_t pt[npt + 1] = {0., 0.5, 1.0, 1.5, 5.0};
+
+  /* get data */
+  TFile *filein = TFile::Open(filename);
+  THnSparseF *hHisto[kNHistos];
+  TH1D *hHisto_all[kNHistos], *hHisto_MB_all[kNHistos], *hHisto_pt[kNHistos][MAXMULTCENTBINS], *hHisto_MB_pt[kNHistos][MAXMULTCENTBINS];
+  /* loop over histos */
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+    if (ihisto == kMatchedCorrelatedTracks) continue;
+    /* get histo */
+    hHisto[ihisto] = (THnSparseF *)filein->Get(histoName[ihisto]);
+    /* set range limits */
+    hHisto[ihisto]->GetAxis(kRapidity)->SetRangeUser(-0.5 + kEpsilon, 0.5 - kEpsilon);
+    hHisto[ihisto]->GetAxis(kEta)->SetRangeUser(-0.8 + kEpsilon, 0.8 - kEpsilon);
+    hHisto[ihisto]->GetAxis(kPt)->SetRangeUser(0. + kEpsilon, 5.0 - kEpsilon);
+    /* select particle if requested */
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+      if (TString(particle) == AliPID::ParticleName(ipart))
+       hHisto[ihisto]->GetAxis(kParticle)->SetRange(ipart + 1, ipart + 1);
+    /* select charge if requested */
+    if (TString(charge) == "plus")
+      hHisto[ihisto]->GetAxis(kCharge)->SetRange(1, 1);
+    else if (TString(charge) == "minus")
+      hHisto[ihisto]->GetAxis(kCharge)->SetRange(2, 2);
+    /* select TRD mode if requested */
+    if (TString(trdmode) == "trdout")
+      hHisto[ihisto]->GetAxis(kTRDmode)->SetRange(1, 1);
+    else if (TString(trdmode) == "notrdout")
+      hHisto[ihisto]->GetAxis(kTRDmode)->SetRange(2, 2);
+    /* all projection */
+    hHisto_all[ihisto] = hHisto[ihisto]->Projection(kMultCent);
+    hHisto_all[ihisto]->SetName(Form("%s_all", histoName[ihisto]));
+    hHisto_all[ihisto]->Sumw2();
+    /* MB all projection */
+    hHisto_MB_all[ihisto] = new TH1D(*hHisto_all[ihisto]);
+    hHisto_MB_all[ihisto]->SetName(Form("%s_MB_all", histoName[ihisto]));
+    for (Int_t i = 0; i < hHisto_MB_all[ihisto]->GetNbinsX(); i++) {
+      hHisto_MB_all[ihisto]->SetBinContent(i + 1, hHisto_all[ihisto]->Integral());
+      hHisto_MB_all[ihisto]->SetBinError(i + 1, TMath::Sqrt(hHisto_all[ihisto]->Integral()));
+    }
+    /* pt projection */
+    for (Int_t ibin = 0; ibin < npt; ibin++) {
+      hHisto[ihisto]->GetAxis(kPt)->SetRangeUser(pt[ibin] + kEpsilon, pt[ibin + 1] - kEpsilon);
+      hHisto_pt[ihisto][ibin] = hHisto[ihisto]->Projection(kMultCent);
+      hHisto_pt[ihisto][ibin]->SetName(Form("%s_pt%3.1f-%3.1f", histoName[ihisto], pt[ibin], pt[ibin + 1]));
+      hHisto_pt[ihisto][ibin]->Sumw2();
+      /* MB pt projection */
+      hHisto_MB_pt[ihisto][ibin] = new TH1D(*hHisto_pt[ihisto][ibin]);
+      hHisto_MB_pt[ihisto][ibin]->SetName(Form("%s_MB_pt%3.1f-%3.1f", histoName[ihisto], pt[ibin], pt[ibin + 1]));
+      for (Int_t i = 0; i < hHisto_MB_pt[ihisto][ibin]->GetNbinsX(); i++) {
+       hHisto_MB_pt[ihisto][ibin]->SetBinContent(i + 1, hHisto_pt[ihisto][ibin]->Integral());
+       hHisto_MB_pt[ihisto][ibin]->SetBinError(i + 1, TMath::Sqrt(hHisto_pt[ihisto][ibin]->Integral()));
+      }
+    }
+  }
+  /*** matched correlated histos ***/
+  /* all projection */
+  hHisto_all[kMatchedCorrelatedTracks] = new TH1D(*hHisto_all[kMatchedTracks]);
+  hHisto_all[kMatchedCorrelatedTracks]->Add(hHisto_all[kUncorrelatedTracks], -1.);
+  hHisto_all[kMatchedCorrelatedTracks]->SetName(Form("%s_all", histoName[kMatchedCorrelatedTracks]));
+  /* MB all projection */
+  hHisto_MB_all[kMatchedCorrelatedTracks] = new TH1D(*hHisto_MB_all[kMatchedTracks]);
+  hHisto_MB_all[kMatchedCorrelatedTracks]->Add(hHisto_MB_all[kUncorrelatedTracks], -1.);
+  hHisto_MB_all[kMatchedCorrelatedTracks]->SetName(Form("%s_MB_all", histoName[kMatchedCorrelatedTracks]));
+  /* pt projection */
+  for (Int_t ibin = 0; ibin < npt; ibin++) {
+    hHisto_pt[kMatchedCorrelatedTracks][ibin] = new TH1D(*hHisto_pt[kMatchedTracks][ibin]);
+    hHisto_pt[kMatchedCorrelatedTracks][ibin]->Add(hHisto_pt[kUncorrelatedTracks][ibin], -1.);
+    hHisto_pt[kMatchedCorrelatedTracks][ibin]->SetName(Form("%s_pt%3.1f-%3.1f", histoName[kMatchedCorrelatedTracks], pt[ibin], pt[ibin + 1]));
+    /* MB pt projection */
+    hHisto_MB_pt[kMatchedCorrelatedTracks][ibin] = new TH1D(*hHisto_MB_pt[kMatchedTracks][ibin]);
+    hHisto_MB_pt[kMatchedCorrelatedTracks][ibin]->Add(hHisto_MB_pt[kUncorrelatedTracks][ibin], -1.);
+    hHisto_MB_pt[kMatchedCorrelatedTracks][ibin]->SetName(Form("%s_MB_pt%3.1f-%3.1f", histoName[kMatchedCorrelatedTracks], pt[ibin], pt[ibin + 1]));
+  }
+
+  /* output */
+  TString str = filename;
+  str.Insert(str.Length() - TString(".root").Length(), ".efficiencyCent");
+  for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+    if (TString(particle) == AliPID::ParticleName(ipart))
+      str.Insert(str.Length() - TString(".root").Length(), Form(".%s", AliPID::ParticleName(ipart)));
+  if (TString(charge) == "plus")
+    str.Insert(str.Length() - TString(".root").Length(), ".plus");
+  else if (TString(charge) == "minus")
+    str.Insert(str.Length() - TString(".root").Length(), ".minus");
+  if (TString(trdmode) == "trdout")
+    str.Insert(str.Length() - TString(".root").Length(), ".trdout");
+  else if (TString(trdmode) == "notrdout")
+    str.Insert(str.Length() - TString(".root").Length(), ".notrdout");
+  TFile *fileout = TFile::Open(str.Data(), "RECREATE");
+  
+  /* efficiencies/fractions and write */
+  TH1D *hEfficiency_all[kNHistos], *hEfficiency_MB_all[kNHistos], *hEfficiency_ratioMB_all[kNHistos], *hEfficiency_pt[kNHistos][MAXMULTCENTBINS], *hEfficiency_MB_pt[kNHistos][MAXMULTCENTBINS], *hEfficiency_ratioMB_pt[kNHistos][MAXMULTCENTBINS];
+
+
+  //  TH1D *hEfficiency_MB[kNHistos], *hEfficiency_multcent[kNHistos][MAXMULTCENTBINS], *hEfficiency_ratioMB_multcent[kNHistos][MAXMULTCENTBINS];
+  //  TH1D *hFraction_MB[kNHistos], *hFraction_multcent[kNHistos][MAXMULTCENTBINS], *hFraction_ratioMB_multcent[kNHistos][MAXMULTCENTBINS];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+    if (ihisto == kAcceptedTracks) continue;
+    /* all efficiency */
+    hEfficiency_all[ihisto] = new TH1D(*hHisto_all[ihisto]);
+    hEfficiency_all[ihisto]->SetName(Form("%s_efficiency_all", histoName[ihisto]));
+    hEfficiency_all[ihisto]->SetLineWidth(2);
+    hEfficiency_all[ihisto]->SetLineColor(1);
+    hEfficiency_all[ihisto]->SetMarkerStyle(20);
+    hEfficiency_all[ihisto]->SetMarkerColor(1);
+    hEfficiency_all[ihisto]->Divide(hHisto_all[kAcceptedTracks]);
+    hEfficiency_all[ihisto]->Write();
+    /* MB all efficiency */
+    hEfficiency_MB_all[ihisto] = new TH1D(*hHisto_MB_all[ihisto]);
+    hEfficiency_MB_all[ihisto]->SetName(Form("%s_efficiency_MB_all", histoName[ihisto]));
+    hEfficiency_MB_all[ihisto]->Divide(hHisto_MB_all[kAcceptedTracks]);
+    hEfficiency_MB_all[ihisto]->Write();
+    /* ratio wrt. MB */
+    hEfficiency_ratioMB_all[ihisto] = new TH1D(*hEfficiency_all[ihisto]);
+    hEfficiency_ratioMB_all[ihisto]->SetName(Form("%s_efficiency_ratioMB_all", histoName[ihisto]));
+    hEfficiency_ratioMB_all[ihisto]->Divide(hEfficiency_MB_all[ihisto]);
+    hEfficiency_ratioMB_all[ihisto]->Write();
+    /* pt efficiency */
+    for (Int_t ibin = 0; ibin < npt; ibin++) {
+      hEfficiency_pt[ihisto][ibin] = new TH1D(*hHisto_pt[ihisto][ibin]);
+      hEfficiency_pt[ihisto][ibin]->SetName(Form("%s_efficiency_pt%3.1f-%3.1f", histoName[ihisto], pt[ibin], pt[ibin + 1]));
+      hEfficiency_pt[ihisto][ibin]->SetLineWidth(2);
+      hEfficiency_pt[ihisto][ibin]->SetLineColor(multcentColor[ibin]);
+      hEfficiency_pt[ihisto][ibin]->SetMarkerStyle(20);
+      hEfficiency_pt[ihisto][ibin]->SetMarkerColor(multcentColor[ibin]);
+      hEfficiency_pt[ihisto][ibin]->Divide(hHisto_pt[kAcceptedTracks][ibin]);
+      hEfficiency_pt[ihisto][ibin]->Write();
+      /* MB pt efficiency */
+      hEfficiency_MB_pt[ihisto][ibin] = new TH1D(*hHisto_MB_pt[ihisto][ibin]);
+      hEfficiency_MB_pt[ihisto][ibin]->SetName(Form("%s_efficiency_MB_pt%3.1f-%3.1f", histoName[ihisto], pt[ibin], pt[ibin + 1]));
+      hEfficiency_MB_pt[ihisto][ibin]->Divide(hHisto_MB_pt[kAcceptedTracks][ibin]);
+      hEfficiency_MB_pt[ihisto][ibin]->Write();
+      /* ratio wrt. central */
+      hEfficiency_ratioMB_pt[ihisto][ibin] = new TH1D(*hEfficiency_pt[ihisto][ibin]);
+      hEfficiency_ratioMB_pt[ihisto][ibin]->SetName(Form("%s_efficiency_ratioMB_pt%3.1f-%3.1f", histoName[ihisto], pt[ibin], pt[ibin + 1]));
+      hEfficiency_ratioMB_pt[ihisto][ibin]->Divide(hEfficiency_MB_pt[ihisto][ibin]);
+      hEfficiency_ratioMB_pt[ihisto][ibin]->Write();
+    }
+
+#if 0
+
+    if (ihisto == kAcceptedTracks || ihisto == kMatchedTracks) continue;
+    /* MB fraction */
+    hFraction_MB[ihisto] = new TH1D(*hHisto_MB[ihisto]);
+    hFraction_MB[ihisto]->SetName(Form("%s_fraction_MB", histoName[ihisto]));
+    hFraction_MB[ihisto]->SetLineWidth(2);
+    hFraction_MB[ihisto]->SetLineColor(1);
+    hFraction_MB[ihisto]->SetMarkerStyle(20);
+    hFraction_MB[ihisto]->SetMarkerColor(1);
+    hFraction_MB[ihisto]->Divide(hHisto_MB[kMatchedTracks]);
+    hFraction_MB[ihisto]->Write();
+    /* multiplicity/centrality fraction */
+    for (Int_t ibin = 0; ibin < hHisto[kMatchedTracks]->GetAxis(kMultCent)->GetNbins(); ibin++) {
+       hFraction_multcent[ihisto][ibin] = new TH1D(*hHisto_multcent[ihisto][ibin]);
+       hFraction_multcent[ihisto][ibin]->SetName(Form("%s_fraction_multcent%d", histoName[ihisto], ibin));
+       hFraction_multcent[ihisto][ibin]->SetLineWidth(2);
+       hFraction_multcent[ihisto][ibin]->SetLineColor(multcentColor[ibin]);
+       hFraction_multcent[ihisto][ibin]->SetMarkerStyle(20);
+       hFraction_multcent[ihisto][ibin]->SetMarkerColor(multcentColor[ibin]);
+       hFraction_multcent[ihisto][ibin]->Divide(hHisto_multcent[kMatchedTracks][ibin]);
+       hFraction_multcent[ihisto][ibin]->Write();
+       /* ratio wrt. MB */
+       hFraction_ratioMB_multcent[ihisto][ibin] = new TH1D(*hFraction_multcent[ihisto][ibin]);
+       hFraction_ratioMB_multcent[ihisto][ibin]->SetName(Form("%s_fraction_ratioMB_multcent%d", histoName[ihisto], ibin));
+       hFraction_ratioMB_multcent[ihisto][ibin]->SetLineWidth(2);
+       hFraction_ratioMB_multcent[ihisto][ibin]->SetLineColor(multcentColor[ibin]);
+       hFraction_ratioMB_multcent[ihisto][ibin]->SetMarkerStyle(20);
+       hFraction_ratioMB_multcent[ihisto][ibin]->SetMarkerColor(multcentColor[ibin]);
+       hFraction_ratioMB_multcent[ihisto][ibin]->Divide(hFraction_MB[ihisto]);
+       hFraction_ratioMB_multcent[ihisto][ibin]->Write();
+    }
+
+    #endif
+  }
+  fileout->Close();
+  
+}
+#endif
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchMC_get(const Char_t *filename, const Char_t *name, Option_t *opt = "", Int_t color = 1, Int_t marker = 20)
+{
+
+  TFile *f = TFile::Open(filename);
+  if (!f || !f->IsOpen())
+    return NULL;
+  TH1D *h = (TH1D *)f->Get(name);
+  if (!h)
+    return NULL;
+  h->SetLineColor(color);
+  h->SetLineWidth(2);
+  h->SetMarkerColor(color);
+  h->SetMarkerStyle(marker);
+  h->Draw(opt);
+  return h;
+}
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchMC_divide(const Char_t *filename, const Char_t *name1, const Char_t *name2, Option_t *opt = "")
+{
+
+  TFile *f = TFile::Open(filename);
+  if (!f || !f->IsOpen())
+    return NULL;
+  TH1D *h1 = (TH1D *)f->Get(name1);
+  TH1D *h2 = (TH1D *)f->Get(name2);
+  if (!h1 || !h2)
+    return NULL;
+  TH1D *hr = new TH1D(*h1);
+  hr->Divide(h2);
+  hr->Draw(opt);
+  return hr;
+}
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchMC_sub(const Char_t *filename, const Char_t *name1, const Char_t *name2, Option_t *opt = "", Int_t color = 1, Int_t marker = 20)
+{
+
+  TFile *f = TFile::Open(filename);
+  if (!f || !f->IsOpen())
+    return NULL;
+  TH1D *h1 = (TH1D *)f->Get(name1);
+  TH1D *h2 = (TH1D *)f->Get(name2);
+  if (!h1 || !h2)
+    return NULL;
+  TH1D *hr = new TH1D(*h1);
+  hr->Add(h2, -1.);
+  hr->SetLineColor(color);
+  hr->SetLineWidth(2);
+  hr->SetMarkerColor(color);
+  hr->SetMarkerStyle(marker);
+  hr->Draw(opt);
+  return hr;
+}
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchMC_compare(const Char_t *filename1, const Char_t *filename2, const Char_t *name, Option_t *opt = "", Int_t color = 1, Int_t marker = 20)
+{
+
+  TFile *f1 = TFile::Open(filename1);
+  TFile *f2 = TFile::Open(filename2);
+  if (!f1 || !f2 || !f1->IsOpen() || !f2->IsOpen())
+    return NULL;
+  TH1D *h1 = (TH1D *)f1->Get(name);
+  TH1D *h2 = (TH1D *)f2->Get(name);
+  if (!h1 || !h2)
+    return NULL;
+  TH1D *hr = new TH1D(*h1);
+  hr->Divide(h2);
+  hr->SetLineColor(color);
+  hr->SetLineWidth(2);
+  hr->SetMarkerColor(color);
+  hr->SetMarkerStyle(marker);
+  hr->Draw(opt);
+  return hr;
+}
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchMC_comparesub(const Char_t *filename1, const Char_t *filename2, const Char_t *name1, const Char_t *name2, Option_t *opt = "", Int_t color = 1, Int_t marker = 20)
+{
+
+  TFile *f1 = TFile::Open(filename1);
+  TFile *f2 = TFile::Open(filename2);
+  if (!f1 || !f2 || !f1->IsOpen() || !f2->IsOpen())
+    return NULL;
+  TH1D *h11 = (TH1D *)f1->Get(name1);
+  TH1D *h21 = (TH1D *)f2->Get(name1);
+  TH1D *h12 = (TH1D *)f1->Get(name2);
+  TH1D *h22 = (TH1D *)f2->Get(name2);
+  if (!h11 || !h21 || !h12 || !h22)
+    return NULL;
+  TH1D *hs1 = new TH1D(*h11);
+  hs1->Add(h12, -1.);
+  TH1D *hs2 = new TH1D(*h21);
+  hs2->Add(h22, -1.);
+  TH1D *hr = new TH1D(*hs1);
+  hr->Divide(hs2);
+  hr->SetLineColor(color);
+  hr->SetLineWidth(2);
+  hr->SetMarkerColor(color);
+  hr->SetMarkerStyle(marker);
+  hr->Draw(opt);
+  return hr;
+}
+
+
+TH1D *
+TOFmatchEff_efficiencyPt_MB_plot(const Char_t *filename, Int_t ihisto = kMatchedTracks, Int_t icharge, Int_t marker = 20, Int_t color = 2, Option_t *opt = "")
+{
+  
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+  const Char_t *destdir = "matchingEfficiency_DATA";
+  
+  Double_t ptMin = 0.5;
+  Double_t ptMax = 5.0;
+
+  TF1 *fEff = new TF1("fEff", "[0] + [1] * x - [2] * TMath::Exp(-[3] * TMath::Power(x, [4]))", 0., 5.0);
+  fEff->SetParameter(0, 0.5);
+  fEff->SetParameter(1, 0.);
+  fEff->SetParameter(2, 0.5);
+  fEff->SetParameter(3, 1.);
+  fEff->SetParameter(4, 2.);
+
+
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyPt = (TH1D *)filein->Get(Form("hEfficiencyPt_MB_%s_%s", histoName[ihisto], chargeName[icharge]));
+  hEfficiencyPt->Fit(fEff, "0", "", 0.5, 5.0);
+  hEfficiencyPt->SetTitle(Form("%s tracks;p_{T} (GeV/c);acceptance #times efficiency;", extendedChargeName[icharge]));
+  hEfficiencyPt->SetMinimum(0.4);
+  hEfficiencyPt->SetMaximum(0.8);
+  hEfficiencyPt->SetMarkerStyle(marker);
+  hEfficiencyPt->SetMarkerColor(color);
+  hEfficiencyPt->SetMarkerSize(1.5);
+  hEfficiencyPt->SetLineWidth(2);
+  hEfficiencyPt->SetLineColor(color);
+  hEfficiencyPt->GetXaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+  hEfficiencyPt->SetStats(kFALSE);
+  cCanvas1->cd();
+  hEfficiencyPt->Draw(opt);
+  fEff->Draw("same");
+
+  cCanvas1->SetGridx();
+  cCanvas1->SetGridy();
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_%s.C", destdir, chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_%s.root", destdir, chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_%s.png", destdir, chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_%s.eps", destdir, chargeName[icharge]));
+  
+  TH1D *hRatioPt = new TH1D(*hEfficiencyPt);
+  hRatioPt->Divide(fEff);
+  hRatioPt->SetTitle(Form("%s tracks;p_{T} (GeV/c);ratio wrt. fitted dependence;", extendedChargeName[icharge]));
+  hRatioPt->SetMinimum(0.9);
+  hRatioPt->SetMaximum(1.1);
+  cCanvas2->cd();
+  hRatioPt->Draw();
+
+  cCanvas2->SetGridx();
+  cCanvas2->SetGridy();
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_%s.C", destdir, chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_%s.root", destdir, chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_%s.png", destdir, chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_%s.eps", destdir, chargeName[icharge]));
+  
+
+  //  hEfficiencyPt->Add(fEff, -1.);
+  return hEfficiencyPt;
+}
+
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchEff_efficiencyPt_centrality_all_plot(const Char_t *filename, Int_t ihisto = kMatchedTracks, Int_t marker = 20, Int_t color = 1, Option_t *opt = "")
+{
+  
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+  const Char_t *destdir = "matchingEfficiency_DATA";
+  
+  Double_t ptMin = 0.5;
+  Double_t ptMax = 5.0;
+
+  TF1 *fMismatchFrac = new TF1("fMismatchFrac", "([0]+[1]*TMath::Exp(-[2]*TMath::Power(x,[3])))*[4]", 0., 5.0);
+  fMismatchFrac->SetParameter(0, 0.0447133);
+  fMismatchFrac->SetParameter(1, 0.179172);
+  fMismatchFrac->SetParameter(2, 2.54333);
+  fMismatchFrac->SetParameter(3, 1.16819);
+  fMismatchFrac->SetParameter(4, 1.);
+  
+  TF1 *fEff = new TF1("fEff", "([0] + [1] * x - [2] * TMath::Exp(-[3] * TMath::Power(x, [4]))) * [5]", 0., 5.0);
+  fEff->SetParameter(0, 0.5);
+  fEff->SetParameter(1, 0.);
+  fEff->SetParameter(2, 0.5);
+  fEff->SetParameter(3, 1.);
+  fEff->SetParameter(4, 2.);
+  fEff->FixParameter(5, 1.);
+  
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyPt = (TH1D *)filein->Get(Form("hEfficiencyAllPt_MB_%s", histoName[ihisto]));
+  hEfficiencyPt->Fit(fEff, "0", "", 0.5, 5.0);
+  hEfficiencyPt->SetTitle("all particles;p_{T} (GeV/c);acceptance #times efficiency;");
+  hEfficiencyPt->SetMinimum(0.4);
+  hEfficiencyPt->SetMaximum(0.8);
+  hEfficiencyPt->SetMarkerStyle(marker);
+  hEfficiencyPt->SetMarkerColor(color);
+  hEfficiencyPt->SetMarkerSize(1.5);
+  hEfficiencyPt->SetLineWidth(2);
+  hEfficiencyPt->SetLineColor(color);
+  hEfficiencyPt->GetXaxis()->SetRangeUser(0.5 + 0.001, 5.0 - 0.001);
+  hEfficiencyPt->SetStats(kFALSE);
+  cCanvas1->cd();
+  hEfficiencyPt->Draw(opt);
+  fEff->Draw("same");
+
+  cCanvas1->SetGridx();
+  cCanvas1->SetGridy();
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.C", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.root", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.png", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.eps", destdir));
+
+  TH1D *hRatioPt = new TH1D(*hEfficiencyPt);
+  hRatioPt->Divide(fEff);
+  hRatioPt->SetTitle("all particles;p_{T} (GeV/c);ratio wrt. fitted dependence;");
+  hRatioPt->SetMinimum(0.9);
+  hRatioPt->SetMaximum(1.1);
+  cCanvas2->cd();
+  hRatioPt->Draw();
+
+  cCanvas2->SetGridx();
+  cCanvas2->SetGridy();
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_all.C", destdir));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_all.root", destdir));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_all.png", destdir));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_all.eps", destdir));
+  
+  /* fix efficiency shape and release scale factor */
+  fEff->FixParameter(0, fEff->GetParameter(0));
+  fEff->FixParameter(1, fEff->GetParameter(1));
+  fEff->FixParameter(2, fEff->GetParameter(2));
+  fEff->FixParameter(3, fEff->GetParameter(3));
+  fEff->FixParameter(4, fEff->GetParameter(4));
+  fEff->ReleaseParameter(5);
+  
+  TH1D *hEfficiencyCent = new TH1D("hEfficiencyCent", "all particles;centrality percentile;acceptance x efficiency scale factor;", NcentralityBins, centralityBin);
+  hEfficiencyCent->SetMinimum(0.95);
+  hEfficiencyCent->SetMaximum(1.05);
+  hEfficiencyCent->SetMarkerStyle(marker);
+  hEfficiencyCent->SetMarkerColor(color);
+  hEfficiencyCent->SetMarkerSize(1.5);
+  hEfficiencyCent->SetLineWidth(2);
+  hEfficiencyCent->SetLineColor(color);
+  hEfficiencyCent->SetStats(kFALSE);
+  
+  
+  TH1D *hEfficiencyPt_cent[NcentralityBins];
+  TH1D *hRatioPt_cent[NcentralityBins];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    
+  
+    hEfficiencyPt_cent[icent] = (TH1D *)filein->Get(Form("hEfficiencyAllPt_centrality%d_%s", icent, histoName[ihisto]));
+    hEfficiencyPt_cent[icent]->Fit(fEff, "", "", 0.5, 5.0);
+    
+    hEfficiencyPt_cent[icent]->SetTitle(Form("all particles (%d-%d\%);p_{T} (GeV/c);acceptance #times efficiency;", (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hEfficiencyPt_cent[icent]->SetMinimum(0.2);
+    hEfficiencyPt_cent[icent]->SetMaximum(0.8);
+    hEfficiencyPt_cent[icent]->SetMarkerStyle(marker);
+    hEfficiencyPt_cent[icent]->SetMarkerColor(color);
+    hEfficiencyPt_cent[icent]->SetMarkerSize(1.5);
+    hEfficiencyPt_cent[icent]->SetLineWidth(2);
+    hEfficiencyPt_cent[icent]->SetLineColor(color);
+    hEfficiencyPt_cent[icent]->GetXaxis()->SetRangeUser(0.5 + 0.001, 5.0 - 0.001);
+    hEfficiencyPt_cent[icent]->SetStats(kFALSE);
+    cCanvas1->cd();
+    hEfficiencyPt_cent[icent]->Draw(opt);
+    fEff->Draw("same");
+    
+    hEfficiencyCent->SetBinContent(icent + 1, fEff->GetParameter(5));
+    hEfficiencyCent->SetBinError(icent + 1, fEff->GetParError(5));
+    
+    cCanvas1->SetGridx();
+    cCanvas1->SetGridy();
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.C", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.root", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.png", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.eps", destdir, icent));
+    
+    hRatioPt_cent[icent] = new TH1D(*hEfficiencyPt_cent[icent]);
+    hRatioPt_cent[icent]->Divide(fEff);
+    hRatioPt_cent[icent]->SetTitle(Form("all particles (%d-%d\%);p_{T} (GeV/c);ratio wrt. fitted dependence;", (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hRatioPt_cent[icent]->SetMinimum(0.9);
+    hRatioPt_cent[icent]->SetMaximum(1.1);
+    cCanvas2->cd();
+    hRatioPt_cent[icent]->Draw();
+
+    cCanvas2->SetGridx();
+    cCanvas2->SetGridy();
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.C", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.root", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.png", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.eps", destdir, icent));
+
+    
+  }
+
+  TF1 *fEffCent = new TF1("fEffCent", "[0] - [1] * TMath::Exp(-[2] * TMath::Power(x, [3]))", 0., 90.);
+  fEffCent->SetParameter(0, 1.02);
+  fEffCent->SetParameter(1, 0.04);
+  fEffCent->SetParameter(2, 0.001);
+  fEffCent->SetParameter(3, 2.);
+  //  hEfficiencyCent->Fit(fEffCent, "q0", "", 0., 90.);
+  
+  TCanvas *cCanvas3 = new TCanvas("cCanvas3");
+  hEfficiencyCent->Draw();
+  //  fEffCent->Draw("same");
+  
+  cCanvas3->SetGridx();
+  cCanvas3->SetGridy();
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.C", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.root", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.png", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.eps", destdir));
+
+  TCanvas *cCanvas4 = new TCanvas("cCanvas4");
+
+  TH1D *hRatioCent = new TH1D(*hEfficiencyCent);
+  hRatioCent->Divide(fEffCent);
+  hRatioCent->SetTitle(Form("all particles;centrality percentile;ratio wrt. fitted dependence;"));
+  hRatioCent->SetMinimum(0.95);
+  hRatioCent->SetMaximum(1.05);
+  cCanvas4->cd();
+  hRatioCent->Draw();
+
+  cCanvas4->SetGridx();
+  cCanvas4->SetGridy();
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.C", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.root", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.png", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.eps", destdir));
+  
+
+
+  //  hEfficiencyPt->Add(fEff, -1.);
+  return hEfficiencyCent;
+}
+
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchEff_efficiencyPt_centrality_all_plot_nomismatch(const Char_t *filename, Int_t ihisto = kMatchedTracks, Int_t marker = 20, Int_t color = 1, Option_t *opt = "")
+{
+
+  TF1 *fpol0 = (TF1 *)gROOT->GetFunction("pol0");
+  fpol0->SetRange(0., 5.0);
+
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+  const Char_t *destdir = "matchingEfficiency_DATA";
+  
+  Double_t ptMin = 0.5;
+  Double_t ptMax = 5.0;
+
+  TF1 *fMismatchCorr = new TF1("fMismatchCorr", "1. - ([0]+[1]*TMath::Exp(-[2]*TMath::Power(x,[3])))*[4]", 0., 5.0);
+  fMismatchCorr->SetParameter(0, 4.47133e-02);
+  fMismatchCorr->SetParameter(1, 1.79172e-01);
+  fMismatchCorr->SetParameter(2, 2.54333e+00);
+  fMismatchCorr->SetParameter(3, 1.16819e+00);
+  fMismatchCorr->SetParameter(4, 1.);
+
+  TF1 *fMismatchScale = new TF1("fMismatchScale", "[0] + [1] * TMath::Exp(-[2] * x)", 0., 100.);
+  fMismatchScale->SetParameter(0, -6.36877e-02);
+  fMismatchScale->SetParameter(1, 1.74818e+00);
+  fMismatchScale->SetParameter(2, 3.00818e-02);
+  
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyPt = (TH1D *)filein->Get(Form("hEfficiencyAllPt_MB_%s", histoName[ihisto]));
+  if (ihisto != kMatchedCorrelatedTracks)
+    hEfficiencyPt->Multiply(fMismatchCorr);
+  hEfficiencyPt->SetTitle("all particles;p_{T} (GeV/c);acceptance #times efficiency;");
+  hEfficiencyPt->SetMinimum(0.4);
+  hEfficiencyPt->SetMaximum(0.8);
+  hEfficiencyPt->SetMarkerStyle(marker);
+  hEfficiencyPt->SetMarkerColor(color);
+  hEfficiencyPt->SetMarkerSize(1.5);
+  hEfficiencyPt->SetLineWidth(2);
+  hEfficiencyPt->SetLineColor(color);
+  hEfficiencyPt->GetXaxis()->SetRangeUser(0.5 + 0.001, 5.0 - 0.001);
+  hEfficiencyPt->SetStats(kFALSE);
+  cCanvas1->cd();
+  hEfficiencyPt->Draw(opt);
+
+  cCanvas1->SetGridx();
+  cCanvas1->SetGridy();
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.C", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.root", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.png", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.eps", destdir));
+
+  TH1D *hEfficiencyCent = new TH1D("hEfficiencyCent", "all particles;centrality percentile;acceptance x efficiency scale factor;", NcentralityBins, centralityBin);
+  hEfficiencyCent->SetMinimum(0.95);
+  hEfficiencyCent->SetMaximum(1.05);
+  hEfficiencyCent->SetMarkerStyle(marker);
+  hEfficiencyCent->SetMarkerColor(color);
+  hEfficiencyCent->SetMarkerSize(1.5);
+  hEfficiencyCent->SetLineWidth(2);
+  hEfficiencyCent->SetLineColor(color);
+  hEfficiencyCent->SetStats(kFALSE);
+  
+  
+  TH1D *hEfficiencyPt_cent[NcentralityBins];
+  TH1D *hRatioPt_cent[NcentralityBins];
+  Double_t centmean;
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    
+    centmean = 0.5 * (centralityBin[icent] + centralityBin[icent + 1]);
+    hEfficiencyPt_cent[icent] = (TH1D *)filein->Get(Form("hEfficiencyAllPt_centrality%d_%s", icent, histoName[ihisto]));
+    fMismatchCorr->SetParameter(4, fMismatchScale->Eval(centmean));
+    if (ihisto != kMatchedCorrelatedTracks)
+      hEfficiencyPt_cent[icent]->Multiply(fMismatchCorr);
+    hEfficiencyPt_cent[icent]->Divide(hEfficiencyPt);
+    hEfficiencyPt_cent[icent]->Fit(fpol0, "q0", "", 0.5, 5.0);
+    hEfficiencyPt_cent[icent]->SetTitle(Form("all particles (%d-%d\%);p_{T} (GeV/c);acceptance #times efficiency;", (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hEfficiencyPt_cent[icent]->SetMinimum(0.2);
+    hEfficiencyPt_cent[icent]->SetMaximum(0.8);
+    hEfficiencyPt_cent[icent]->SetMarkerStyle(marker);
+    hEfficiencyPt_cent[icent]->SetMarkerColor(color);
+    hEfficiencyPt_cent[icent]->SetMarkerSize(1.5);
+    hEfficiencyPt_cent[icent]->SetLineWidth(2);
+    hEfficiencyPt_cent[icent]->SetLineColor(color);
+    hEfficiencyPt_cent[icent]->GetXaxis()->SetRangeUser(0.5 + 0.001, 5.0 - 0.001);
+    hEfficiencyPt_cent[icent]->SetStats(kFALSE);
+    cCanvas1->cd();
+    hEfficiencyPt_cent[icent]->Draw(opt);
+    fpol0->Draw("same");
+    
+    hEfficiencyCent->SetBinContent(icent + 1, fpol0->GetParameter(0));
+    hEfficiencyCent->SetBinError(icent + 1, fpol0->GetParError(0));
+    
+    cCanvas1->SetGridx();
+    cCanvas1->SetGridy();
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.C", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.root", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.png", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.eps", destdir, icent));
+    
+    hRatioPt_cent[icent] = new TH1D(*hEfficiencyPt_cent[icent]);
+    hRatioPt_cent[icent]->Divide(fpol0);
+    hRatioPt_cent[icent]->SetTitle(Form("all particles (%d-%d\%);p_{T} (GeV/c);ratio wrt. fitted dependence;", (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hRatioPt_cent[icent]->SetMinimum(0.9);
+    hRatioPt_cent[icent]->SetMaximum(1.1);
+    cCanvas2->cd();
+    hRatioPt_cent[icent]->Draw();
+
+    cCanvas2->SetGridx();
+    cCanvas2->SetGridy();
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.C", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.root", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.png", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.eps", destdir, icent));
+
+    
+  }
+
+  TF1 *fEffCent = new TF1("fEffCent", "[0] - [1] * TMath::Exp(-[2] * TMath::Power(x, [3]))", 0., 90.);
+  fEffCent->SetParameter(0, 1.02);
+  fEffCent->SetParameter(1, 0.04);
+  fEffCent->SetParameter(2, 0.001);
+  fEffCent->SetParameter(3, 2.);
+  //  hEfficiencyCent->Fit(fEffCent, "q0", "", 0., 90.);
+  
+  TCanvas *cCanvas3 = new TCanvas("cCanvas3");
+  hEfficiencyCent->Draw();
+  //  fEffCent->Draw("same");
+  
+  cCanvas3->SetGridx();
+  cCanvas3->SetGridy();
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.C", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.root", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.png", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.eps", destdir));
+
+  TCanvas *cCanvas4 = new TCanvas("cCanvas4");
+
+  TH1D *hRatioCent = new TH1D(*hEfficiencyCent);
+  hRatioCent->Divide(fEffCent);
+  hRatioCent->SetTitle(Form("all particles;centrality percentile;ratio wrt. fitted dependence;"));
+  hRatioCent->SetMinimum(0.95);
+  hRatioCent->SetMaximum(1.05);
+  cCanvas4->cd();
+  hRatioCent->Draw();
+
+  cCanvas4->SetGridx();
+  cCanvas4->SetGridy();
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.C", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.root", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.png", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.eps", destdir));
+  
+
+
+  //  hEfficiencyPt->Add(fEff, -1.);
+  return hEfficiencyCent;
+}
+
+
+TH1D *
+TOFmatchEff_rapidityCut(const Char_t *filename, Int_t ipart, Int_t icharge, Int_t color = 2, Int_t marker = 20, Option_t *opt = "")
+{
+
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiency_MB = (TH1D *)filein->Get(Form("hEfficiencyPt_MB_hMatchedTracks_%s", chargeName[icharge]));
+  TH1D *hEfficiencyPID_MB = (TH1D *)filein->Get(Form("hEfficiencyPIDPt_MB_hMatchedTracks_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]));
+
+  TH1D *hRatio = new TH1D(*hEfficiencyPID_MB);
+  hRatio->Divide(hEfficiency_MB);
+  hRatio->SetLineColor(color);
+  hRatio->SetLineWidth(2);
+  hRatio->SetMarkerColor(color);
+  hRatio->SetMarkerStyle(marker);
+  hRatio->Draw(opt);
+  return hRatio;
+}
+
+void
+TOFmatchEff_checkFEAmap(const Char_t *filename)
+{
+
+  TFile *filein = TFile::Open(filename);
+  TH2F *hFEAMap = (TH2F *)filein->Get("hFEAMap");
+  TH2F *hEmptyFEA = new TH2F("hEmptyFEA", "", 72, 0., 18., 91, 0., 91.);
+
+  Float_t nhits = hFEAMap->GetEntries();
+  if (nhits <= 0) {
+    printf("found not hits.\n");
+    return;
+  }
+  printf("found %d hits\n", nhits);
+  Float_t avhits = nhits / (hFEAMap->GetNbinsX() * hFEAMap->GetNbinsX());
+  printf("on average %f hits/FEA\n", avhits);
+  
+  TH1F *hFEANormHit = new TH1F("hFEANormHit", "", 1000, 0., 3.);
+  for (Int_t ibinx = 0; ibinx < hFEAMap->GetNbinsX(); ibinx++)
+    for (Int_t ibiny = 0; ibiny < hFEAMap->GetNbinsY(); ibiny++) {
+      if (hFEAMap->GetBinContent(ibinx + 1, ibiny + 1) == 0.) {
+       hEmptyFEA->SetBinContent(ibinx + 1, ibiny + 1, 1.);
+       continue;
+      }
+      hFEANormHit->Fill(hFEAMap->GetBinContent(ibinx + 1, ibiny + 1) / avhits);
+    }
+
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  cCanvas1->Divide(1, 2);
+  cCanvas1->cd(1);
+  hFEAMap->Draw("colz");
+  cCanvas1->cd(2);
+  hEmptyFEA->Draw("colz");
+
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+  hFEANormHit->Draw();
+
+
+  TFile *fileout = TFile::Open(Form("TOFmatchEff_checkFEAmap.%s", filename), "RECREATE");
+  hFEAMap->Write();
+  hFEANormHit->Write();
+  hEmptyFEA->Write();
+  fileout->Close();
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFmatchMC.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFmatchMC.C
new file mode 100644 (file)
index 0000000..c809c8d
--- /dev/null
@@ -0,0 +1,1492 @@
+const Char_t *destdir = "plots";
+
+enum EHisto_t {
+  kAcceptedTracks,
+  kMatchedTracks,
+  kMismatchedTracks,
+  kUncorrelatedTracks,
+  kMatchedCorrelatedTracks,
+  kMatchedGoodTracks,
+  kNHistos
+};
+const Char_t *histoName[kNHistos] = {
+  "hAcceptedTracks",
+  "hMatchedTracks",
+  "hMismatchedTracks",
+  "hUncorrelatedTracks",
+  "hMatchedCorrelatedTracks",
+  "hMatchedGoodTracks"
+};
+
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative"
+};
+
+enum EParam_t {
+  kCentrality,
+  kPt,
+  kEta,
+  kPhi,
+  kNParams
+};
+
+const Int_t NcentralityBins = 10;
+Double_t centralityBin[NcentralityBins + 1] = {0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.};
+
+const Int_t NptBins = 46;
+Double_t ptBin[NptBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+
+const Int_t NetaBins = 20;
+Double_t etaMin = -1.;
+Double_t etaMax = 1.;
+Double_t etaStep = (etaMax - etaMin) / NetaBins;
+Double_t etaBin[NetaBins + 1]; /* computed at run-time */
+
+const Int_t NphiBins = 20;
+Double_t phiMin = 0.;
+Double_t phiMax = 2. * TMath::Pi();
+Double_t phiStep = (phiMax - phiMin) / NphiBins;
+Double_t phiBin[NphiBins + 1]; /* computed at run-time */
+
+const Int_t NptsubBins = 4;
+Double_t ptsubBin[NptsubBins + 1] = {0.2, 0.5, 1.0, 1.5, 5.0};
+Int_t ptsubBinMin[NptsubBins] = {0, 6, 16, 21};
+Int_t ptsubBinMax[NptsubBins] = {5, 15, 20, 45};
+
+Int_t multcentColor[10] = {
+  kRed,
+  kOrange+1,
+  kOrange,
+  kYellow,
+  kYellow+1,
+  kGreen,
+  kGreen+1,
+  kCyan+1,
+  kBlue,
+  kMagenta,
+  //  kMagenta+1  
+};
+
+Int_t particleColor[5] = {1, 1, 4, 8, 2};
+Int_t chargeMarker[2] = {20, 25};
+
+const Char_t *partChargeName[5][2] = {"e^{+}", "e^{-}", "#mu^{+}", "#mu^{-}", "#pi^{+}", "#pi^{-}", "K^{+}", "K^{-}", "p", "#bar{p}"};
+
+const Double_t kEpsilon = 0.001;
+
+TOFmatchMC(const Char_t *filename, const Char_t *enabledfilename = NULL, Int_t evMax = kMaxInt)
+{
+  
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* open enabled flag map */
+  TH1F *hEnabledFlag = NULL;
+  if (enabledfilename) {
+    TFile *enabledfile = TFile::Open(enabledfilename);
+    hEnabledFlag = (TH1F *)enabledfile->Get("hEnabledFlag");
+  }
+  
+  /* binning */
+  for (Int_t ieta = 0; ieta < NetaBins + 1; ieta++)
+    etaBin[ieta] = etaMin + ieta * etaStep;
+  for (Int_t iphi = 0; iphi < NphiBins + 1; iphi++)
+    phiBin[iphi] = phiMin + iphi * phiStep;
+  /* THnSparse */
+  Int_t NparamBins[kNParams] = {NcentralityBins, NptBins, NetaBins, NphiBins};
+  Double_t *paramBin[kNParams] = {centralityBin, ptBin, etaBin, phiBin};
+  THnSparseF *hHisto[kNHistos][AliPID::kSPECIES][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       hHisto[ihisto][ipart][icharge] = new THnSparseF(Form("hHisto_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]), "", kNParams, NparamBins);
+       for (Int_t iparam = 0; iparam < kNParams; iparam++)
+         hHisto[ihisto][ipart][icharge]->SetBinEdges(iparam, paramBin[iparam]);
+      }
+  /* histos */
+  TH2F *hFEAMap = new TH2F("hFEAMap", "", 72, 0., 18., 91, 0., 91.);
+
+  /* start stopwatch */
+  TStopwatch timer;
+  timer.Start();
+
+  /* loop over events */
+  Double_t param[kNParams];
+  Int_t part, charge;
+  Int_t index, sector, sectorStrip, padx, fea;
+  Float_t hitmapx, hitmapy;
+  AliTOFcalibHisto calib;
+  calib.LoadCalibHisto();
+  for (Int_t iev = 0; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 1000 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+
+    /*** ACCEPTED EVENT ***/
+
+    /* get centrality */
+    param[kCentrality] = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+    
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check charged primary with defined PID */
+      part = analysisTrack->GetMCPID();
+      if (!analysisTrack->IsMCPrimary() || part < 0 || analysisTrack->GetSign() == 0.) continue;
+      /* check accepted track */
+      if (!analysisTrack->AcceptTrack()) continue;
+      /* check rapidity */
+      if (TMath::Abs(analysisTrack->GetY(AliPID::ParticleMass(part))) > 0.5)
+       continue;
+
+      /*** ACCEPTED TRACK ***/
+      
+      /* get track info */
+      param[kPt] = analysisTrack->GetPt();
+      param[kEta] = analysisTrack->GetEta();
+      param[kPhi] = analysisTrack->GetPhi();
+      charge = analysisTrack->GetSign() > 0. ? kPositive : kNegative;
+      
+      /* fill accepted tracks histos */
+      hHisto[kAcceptedTracks][part][charge]->Fill(param);
+
+      /* check TOF PID */
+      if (!analysisTrack->HasTOFPID()) continue;
+      /* check channel enabled */
+      index = analysisTrack->GetTOFIndex();
+      //      if (hEnabledFlag && hEnabledFlag->GetBinContent(index + 1) == 0.) continue;
+
+      /*** ACCEPTED TRACK WITH TOF SIGNAL ***/
+
+      /* fill FEA map */
+      sector = calib.GetCalibMap(AliTOFcalibHisto::kSector, index);
+      sectorStrip = calib.GetCalibMap(AliTOFcalibHisto::kSectorStrip, index);
+      padx = calib.GetCalibMap(AliTOFcalibHisto::kPadX, index);
+      fea = padx / 12;
+      hitmapx = sector + ((Double_t)(3 - fea) + 0.5) / 4.;
+      hitmapy = sectorStrip;
+      hFEAMap->Fill(hitmapx, hitmapy);
+      
+      /* fill matched tracks histos */
+      hHisto[kMatchedTracks][part][charge]->Fill(param);
+      
+      /* check mismatch */
+      if (!analysisTrack->IsMismatchMC()) {
+       hHisto[kMatchedGoodTracks][part][charge]->Fill(param);
+       hHisto[kMatchedCorrelatedTracks][part][charge]->Fill(param);
+       continue;
+      }
+
+      /*** MIS-MATCHED TRACK ***/
+
+      /* fill mis-matched tracks histos */
+      hHisto[kMismatchedTracks][part][charge]->Fill(param);
+
+      /* check uncorrelated mismatch */
+      if (!analysisTrack->IsUncorrelatedMismatchMC()) {
+       hHisto[kMatchedCorrelatedTracks][part][charge]->Fill(param);
+       continue;
+      }
+      
+      /*** UNCORRELATED MIS-MATCHED TRACK ***/
+
+      /* fill uncorrelated mis-matched tracks histos */
+      hHisto[kUncorrelatedTracks][part][charge]->Fill(param);
+
+    }
+  }
+
+  /* stop stopwatch */
+  timer.Stop();
+  timer.Print();
+  
+  /* output */
+  TFile *fileout = TFile::Open(Form("TOFmatchMC.%s", filename), "RECREATE");
+  hFEAMap->Write();
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++)
+       hHisto[ihisto][ipart][icharge]->Write();
+  fileout->Close();
+  
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchMC_efficiencyPt(const Char_t *filename)
+{
+
+  /* get data */
+  TFile *filein = TFile::Open(filename);
+  THnSparseF *hHisto[kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hHistoPt_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hHistoPt_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hHistoAllPt_MB[kNHistos], *hHistoAllPt_centrality[NcentralityBins][kNHistos];
+  /* loop over histos */
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+
+    /* INCLUSIVE */
+
+    hHistoAllPt_MB[ihisto] = new TH1D(Form("hHistoAllPt_MB_%s", histoName[ihisto]), "", NptBins, ptBin);
+    for (Int_t icent = 0; icent < NcentralityBins; icent++)
+      hHistoAllPt_centrality[icent][ihisto] = new TH1D(Form("hHistoAllPt_centrality%d_%s", icent, histoName[ihisto]), "", NptBins, ptBin);
+
+    /* SINGLE PARTICLE */
+
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+
+       /* get histo */
+       hHisto[ihisto][ipart][icharge] = (THnSparseF *)filein->Get(Form("hHisto_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+
+       /* MB projection */
+       hHistoPt_MB[ihisto][ipart][icharge] = hHisto[ihisto][ipart][icharge]->Projection(kPt);
+       hHistoPt_MB[ihisto][ipart][icharge]->SetName(Form("hHistoPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       hHistoPt_MB[ihisto][ipart][icharge]->Sumw2();
+       hHistoAllPt_MB[ihisto]->Add(hHistoPt_MB[ihisto][ipart][icharge]);
+       
+       /* centrality projection */
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+         hHisto[ihisto][ipart][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+         hHistoPt_centrality[icent][ihisto][ipart][icharge] = hHisto[ihisto][ipart][icharge]->Projection(kPt);
+         hHistoPt_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hHistoPt_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hHistoPt_centrality[icent][ihisto][ipart][icharge]->Sumw2();
+         hHistoAllPt_centrality[icent][ihisto]->Add(hHistoPt_centrality[icent][ihisto][ipart][icharge]);
+       }
+      }
+    }
+  }    
+  
+  /* output */
+  TString str = filename;
+  str.Insert(str.Length() - TString(".root").Length(), ".efficiencyPt");
+  TFile *fileout = TFile::Open(str.Data(), "RECREATE");
+  
+  /* efficiencies/fractions and write */
+  TH1D *hEfficiencyPt_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyPt_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyPt_ratioMB_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hEfficiencyAllPt_MB[kNHistos], *hEfficiencyAllPt_centrality[NcentralityBins][kNHistos], *hEfficiencyAllPt_ratioMB_centrality[NcentralityBins][kNHistos];
+
+
+  TH1D *hFractionPt_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hFractionPt_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges], *hFractionPt_ratioMB_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+
+    if (ihisto == kAcceptedTracks) continue;
+
+    /* INCLUSIVE */
+
+    /* MB efficiency */
+    hEfficiencyAllPt_MB[ihisto] = new TH1D(*hHistoAllPt_MB[ihisto]);
+    hEfficiencyAllPt_MB[ihisto]->SetName(Form("hEfficiencyAllPt_MB_%s", histoName[ihisto]));
+    hEfficiencyAllPt_MB[ihisto]->SetLineWidth(2);
+    hEfficiencyAllPt_MB[ihisto]->SetLineColor(1);
+    hEfficiencyAllPt_MB[ihisto]->SetMarkerStyle(20);
+    hEfficiencyAllPt_MB[ihisto]->SetMarkerColor(1);
+    hEfficiencyAllPt_MB[ihisto]->Divide(hEfficiencyAllPt_MB[ihisto], hHistoAllPt_MB[kAcceptedTracks], 1, 1, "B");
+    hEfficiencyAllPt_MB[ihisto]->Write();
+    
+    /* multiplicity/centrality efficiency */
+    for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+      hEfficiencyAllPt_centrality[icent][ihisto] = new TH1D(*hHistoAllPt_centrality[icent][ihisto]);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetName(Form("hEfficiencyAllPt_centrality%d_%s", icent, histoName[ihisto]));
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetLineWidth(2);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetLineColor(multcentColor[icent]);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetMarkerStyle(20);
+      hEfficiencyAllPt_centrality[icent][ihisto]->SetMarkerColor(multcentColor[icent]);
+      hEfficiencyAllPt_centrality[icent][ihisto]->Divide(hEfficiencyAllPt_centrality[icent][ihisto], hHistoAllPt_centrality[icent][kAcceptedTracks], 1, 1, "B");
+      hEfficiencyAllPt_centrality[icent][ihisto]->Write();
+      
+      /* ratio wrt. MB */
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto] = new TH1D(*hEfficiencyAllPt_centrality[icent][ihisto]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetName(Form("hEfficiencyAllPt_ratioMB_centrality%d_%s", icent, histoName[ihisto]));
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetLineWidth(2);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetLineColor(multcentColor[icent]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetMarkerStyle(20);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->SetMarkerColor(multcentColor[icent]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->Divide(hEfficiencyAllPt_MB[ihisto]);
+      hEfficiencyAllPt_ratioMB_centrality[icent][ihisto]->Write();
+    }
+    
+    /* SINGLE PARTICLE */
+
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++) {
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+
+       /* MB efficiency */
+       hEfficiencyPt_MB[ihisto][ipart][icharge] = new TH1D(*hHistoPt_MB[ihisto][ipart][icharge]);
+       hEfficiencyPt_MB[ihisto][ipart][icharge]->SetName(Form("hEfficiencyPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       hEfficiencyPt_MB[ihisto][ipart][icharge]->SetLineWidth(2);
+       hEfficiencyPt_MB[ihisto][ipart][icharge]->SetLineColor(1);
+       hEfficiencyPt_MB[ihisto][ipart][icharge]->SetMarkerStyle(20);
+       hEfficiencyPt_MB[ihisto][ipart][icharge]->SetMarkerColor(1);
+       hEfficiencyPt_MB[ihisto][ipart][icharge]->Divide(hEfficiencyPt_MB[ihisto][ipart][icharge], hHistoPt_MB[kAcceptedTracks][ipart][icharge], 1, 1, "B");
+       hEfficiencyPt_MB[ihisto][ipart][icharge]->Write();
+       
+       /* multiplicity/centrality efficiency */
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hHistoPt_centrality[icent][ihisto][ipart][icharge]);
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hEfficiencyPt_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]->Divide(hEfficiencyPt_centrality[icent][ihisto][ipart][icharge], hHistoPt_centrality[icent][kAcceptedTracks][ipart][icharge], 1, 1, "B");
+         hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]->Write();
+         
+         /* ratio wrt. MB */
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hEfficiencyPt_centrality[icent][ihisto][ipart][icharge]);
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hEfficiencyPt_ratioMB_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->Divide(hEfficiencyPt_MB[ihisto][ipart][icharge]);
+         hEfficiencyPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->Write();
+       }
+       
+       /* fractions */
+       
+       if (ihisto == kAcceptedTracks || ihisto == kMatchedTracks) continue;
+
+       /* MB fraction */
+       hFractionPt_MB[ihisto][ipart][icharge] = new TH1D(*hHistoPt_MB[ihisto][ipart][icharge]);
+       hFractionPt_MB[ihisto][ipart][icharge]->SetName(Form("hFractionPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       hFractionPt_MB[ihisto][ipart][icharge]->SetLineWidth(2);
+       hFractionPt_MB[ihisto][ipart][icharge]->SetLineColor(1);
+       hFractionPt_MB[ihisto][ipart][icharge]->SetMarkerStyle(20);
+       hFractionPt_MB[ihisto][ipart][icharge]->SetMarkerColor(1);
+       hFractionPt_MB[ihisto][ipart][icharge]->Divide(hFractionPt_MB[ihisto][ipart][icharge], hHistoPt_MB[kMatchedTracks][ipart][icharge], 1, 1, "B");
+       hFractionPt_MB[ihisto][ipart][icharge]->Write();
+
+       /* multiplicity/centrality fraction */
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+         hFractionPt_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hHistoPt_centrality[icent][ihisto][ipart][icharge]);
+         hFractionPt_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hFractionPt_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hFractionPt_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hFractionPt_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hFractionPt_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hFractionPt_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+         hFractionPt_centrality[icent][ihisto][ipart][icharge]->Divide(hFractionPt_centrality[icent][ihisto][ipart][icharge], hHistoPt_centrality[icent][kMatchedTracks][ipart][icharge], 1, 1, "B");
+         hFractionPt_centrality[icent][ihisto][ipart][icharge]->Write();
+
+         /* ratio wrt. MB */
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hFractionPt_centrality[icent][ihisto][ipart][icharge]);
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hFractionPt_ratioMB_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->Divide(hFractionPt_MB[ihisto][ipart][icharge]);
+         hFractionPt_ratioMB_centrality[icent][ihisto][ipart][icharge]->Write();
+       }
+      }       
+    }
+  }
+  
+  fileout->Close();
+            
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchMC_efficiencyEta(const Char_t *filename)
+{
+
+  /* get data */
+  TFile *filein = TFile::Open(filename);
+  THnSparseF *hHisto[kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hHistoEta_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hHistoEta_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hHistoEta_MB_pt[NptsubBins][kNHistos][AliPID::kSPECIES][kNCharges], *hHistoEta_centrality_pt[NcentralityBins][NptsubBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  /* loop over histos */
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++)
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       
+       /* get histo */
+       hHisto[ihisto][ipart][icharge] = (THnSparseF *)filein->Get(Form("hHisto_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       
+       /* MB projection */
+       hHisto[ihisto][ipart][icharge]->GetAxis(kPt)->SetRange(0, 0);
+       hHisto[ihisto][ipart][icharge]->GetAxis(kCentrality)->SetRange(0, 0);
+       hHistoEta_MB[ihisto][ipart][icharge] = hHisto[ihisto][ipart][icharge]->Projection(kEta);
+       hHistoEta_MB[ihisto][ipart][icharge]->SetName(Form("hHistoEta_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       hHistoEta_MB[ihisto][ipart][icharge]->Sumw2();
+       /* pt bins */
+       for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+         hHisto[ihisto][ipart][icharge]->GetAxis(kPt)->SetRange(ptsubBinMin[ipt] + 1, ptsubBinMax[ipt] + 1);
+         hHisto[ihisto][ipart][icharge]->GetAxis(kCentrality)->SetRange(0, 0);
+         hHistoEta_MB_pt[ipt][ihisto][ipart][icharge] = hHisto[ihisto][ipart][icharge]->Projection(kEta);
+         hHistoEta_MB_pt[ipt][ihisto][ipart][icharge]->SetName(Form("hHistoEta_MB_pt%d_%s_%s_%s", ipt, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hHistoEta_MB_pt[ipt][ihisto][ipart][icharge]->Sumw2();
+       }
+       
+       /* centrality projection */
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+         hHisto[ihisto][ipart][icharge]->GetAxis(kPt)->SetRange(0, 0);
+         hHisto[ihisto][ipart][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+         hHistoEta_centrality[icent][ihisto][ipart][icharge] = hHisto[ihisto][ipart][icharge]->Projection(kEta);
+         hHistoEta_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hHistoEta_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hHistoEta_centrality[icent][ihisto][ipart][icharge]->Sumw2();
+         /* pt bins */
+         for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+           hHisto[ihisto][ipart][icharge]->GetAxis(kPt)->SetRange(ptsubBinMin[ipt] + 1, ptsubBinMax[ipt] + 1);
+           hHisto[ihisto][ipart][icharge]->GetAxis(kCentrality)->SetRange(icent + 1, icent + 1);
+           hHistoEta_centrality_pt[icent][ipt][ihisto][ipart][icharge] = hHisto[ihisto][ipart][icharge]->Projection(kEta);
+           hHistoEta_centrality_pt[icent][ipt][ihisto][ipart][icharge]->SetName(Form("hHistoEta_centrality%d_pt%d_%s_%s_%s", icent, ipt, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+           hHistoEta_centrality_pt[icent][ipt][ihisto][ipart][icharge]->Sumw2();
+         }
+       }
+      }
+  
+  /* output */
+  TString str = filename;
+  str.Insert(str.Length() - TString(".root").Length(), ".efficiencyEta");
+  TFile *fileout = TFile::Open(str.Data(), "RECREATE");
+  
+  /* efficiencies/fractions and write */
+  TH1D *hEfficiencyEta_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyEta_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyEta_ratioMB_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hEfficiencyEta_MB_pt[NptsubBins][kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyEta_centrality_pt[NcentralityBins][NptsubBins][kNHistos][AliPID::kSPECIES][kNCharges], *hEfficiencyEta_ratioMB_centrality_pt[NcentralityBins][NptsubBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  
+  
+  TH1D *hFractionEta_MB[kNHistos][AliPID::kSPECIES][kNCharges], *hFractionEta_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges], *hFractionEta_ratioMB_centrality[NcentralityBins][kNHistos][AliPID::kSPECIES][kNCharges];
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+    for (Int_t ipart = 0; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       
+       if (ihisto == kAcceptedTracks) continue;
+       
+       /* MB efficiency */
+       hEfficiencyEta_MB[ihisto][ipart][icharge] = new TH1D(*hHistoEta_MB[ihisto][ipart][icharge]);
+       hEfficiencyEta_MB[ihisto][ipart][icharge]->SetName(Form("hEfficiencyEta_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+       hEfficiencyEta_MB[ihisto][ipart][icharge]->SetLineWidth(2);
+       hEfficiencyEta_MB[ihisto][ipart][icharge]->SetLineColor(1);
+       hEfficiencyEta_MB[ihisto][ipart][icharge]->SetMarkerStyle(20);
+       hEfficiencyEta_MB[ihisto][ipart][icharge]->SetMarkerColor(1);
+       hEfficiencyEta_MB[ihisto][ipart][icharge]->Divide(hHistoEta_MB[kAcceptedTracks][ipart][icharge]);
+       hEfficiencyEta_MB[ihisto][ipart][icharge]->Write();
+       /* pt bins */
+       for (Int_t ipt = 0; ipt < NptsubBins; ipt++) {
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge] = new TH1D(*hHistoEta_MB_pt[ipt][ihisto][ipart][icharge]);
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge]->SetName(Form("hEfficiencyEta_MB_pt%d_%s_%s_%s", ipt, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge]->SetLineWidth(2);
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge]->SetLineColor(1);
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge]->SetMarkerColor(1);
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge]->Divide(hHistoEta_MB_pt[ipt][kAcceptedTracks][ipart][icharge]);
+         hEfficiencyEta_MB_pt[ipt][ihisto][ipart][icharge]->Write();
+       }
+       
+       /* multiplicity/centrality efficiency */
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hHistoEta_centrality[icent][ihisto][ipart][icharge]);
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hEfficiencyEta_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]->Divide(hHistoEta_centrality[icent][kAcceptedTracks][ipart][icharge]);
+         hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]->Write();
+         
+         /* ratio wrt. MB */
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge] = new TH1D(*hEfficiencyEta_centrality[icent][ihisto][ipart][icharge]);
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetName(Form("hEfficiencyEta_ratioMB_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineWidth(2);
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetLineColor(multcentColor[icent]);
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerStyle(20);
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge]->SetMarkerColor(multcentColor[icent]);
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge]->Divide(hEfficiencyEta_MB[ihisto][ipart][icharge]);
+         hEfficiencyEta_ratioMB_centrality[icent][ihisto][ipart][icharge]->Write();
+       }
+       
+      }       
+  }
+  
+  fileout->Close();
+  
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchMC_centralityDependence(const Char_t *filename)
+{
+
+  Double_t fitMin[AliPID::kSPECIES] = {0.5, 0.5, 0.5, 0.5, 0.5};
+  Double_t fitMax[AliPID::kSPECIES] = {3.0, 3.0, 3.0, 3.0, 5.0};
+
+  TF1 *pol0 = (TF1 *)gROOT->GetFunction("pol0");
+  TF1 *pol1 = (TF1 *)gROOT->GetFunction("pol1");
+  pol0->SetRange(0., 5.0);
+  TFile *filein = TFile::Open(filename);
+
+  /* output */
+  TString str = filename;
+  str.Insert(str.Length() - TString(".root").Length(), ".centralityDependence");
+  TFile *fileout = TFile::Open(str.Data(), "RECREATE");
+
+  TH1D *hEfficiencyPt_ratioMB;
+  TH1D *hEfficiencyCentrality[kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hChi2Centrality[kNHistos][AliPID::kSPECIES][kNCharges];
+  TH1D *hEfficiencyAllCentrality[kNHistos];
+  TH1F *hHistoEffRatio = new TH1F("hHistoEffRatio", "", 100, 0.5, 1.5);
+  for (Int_t ihisto = 0; ihisto < kNHistos; ihisto++) {
+    if (ihisto == kAcceptedTracks) continue;
+
+    /* INCLUSIVE */
+
+    hEfficiencyAllCentrality[ihisto] = new TH1D(Form("hEfficiencyAllCentrality_ratioMB_%s", histoName[ihisto]), "", NcentralityBins, centralityBin);
+    hEfficiencyAllCentrality[ihisto]->SetLineWidth(2);
+    hEfficiencyAllCentrality[ihisto]->SetLineColor(1);
+    hEfficiencyAllCentrality[ihisto]->SetMarkerStyle(20);
+    hEfficiencyAllCentrality[ihisto]->SetMarkerColor(1);
+    
+    for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+      
+      hEfficiencyPt_ratioMB = (TH1D *)filein->Get(Form("hEfficiencyAllPt_ratioMB_centrality%d_%s", icent, histoName[ihisto]));
+      hEfficiencyPt_ratioMB->Fit(pol0, "q0", "", 0., 5.0);
+      hEfficiencyAllCentrality[ihisto]->SetBinContent(icent + 1, pol0->GetParameter(0));
+      hEfficiencyAllCentrality[ihisto]->SetBinError(icent + 1, pol0->GetParError(0));
+      hEfficiencyPt_ratioMB->Add(pol0, -1.);
+      hEfficiencyPt_ratioMB->Write();
+      
+    }
+    hEfficiencyAllCentrality[ihisto]->Write();
+    
+    
+    /* SINGLE PARTICLE */
+    
+    for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++)
+      for (Int_t icharge = 0; icharge < kNCharges; icharge++) {
+       
+       hEfficiencyCentrality[ihisto][ipart][icharge] = new TH1D(Form("hEfficiencyCentrality_ratioMB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]), "", NcentralityBins, centralityBin);
+       hEfficiencyCentrality[ihisto][ipart][icharge]->SetLineWidth(2);
+       hEfficiencyCentrality[ihisto][ipart][icharge]->SetLineColor(particleColor[ipart]);
+       hEfficiencyCentrality[ihisto][ipart][icharge]->SetMarkerStyle(chargeMarker[icharge]);
+       hEfficiencyCentrality[ihisto][ipart][icharge]->SetMarkerColor(particleColor[ipart]);
+       
+       for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+        
+         hEfficiencyPt_ratioMB = (TH1D *)filein->Get(Form("hEfficiencyPt_ratioMB_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+
+         hEfficiencyPt_ratioMB->Fit(pol0, "q0", "", fitMin[ipart], fitMax[ipart]);
+         hEfficiencyCentrality[ihisto][ipart][icharge]->SetBinContent(icent + 1, pol0->GetParameter(0));
+         hEfficiencyCentrality[ihisto][ipart][icharge]->SetBinError(icent + 1, pol0->GetParError(0));
+         pol0->SetRange(fitMin[ipart], fitMax[ipart]);
+         hEfficiencyPt_ratioMB->Add(pol0, -1.);
+         hEfficiencyPt_ratioMB->Write();
+
+       }
+
+       hEfficiencyCentrality[ihisto][ipart][icharge]->Write();
+      }
+  }
+  
+  fileout->Close();
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchMC_centralityDependenceFit(const Char_t *filename, Int_t ihisto = kMatchedGoodTracks)
+{
+
+  const Char_t *particleLabel[5][2] = {"", "", "", "", "#pi^{+}", "#pi^{-}", "K^{+}", "K^{-}", "p", "#bar{p}"};
+
+  TF1 *fCentralityDependence = new TF1("fCentralityDependence", "[0] + [1] * (1. - TMath::Exp(-x / [2]))", 0., 90.);
+  fCentralityDependence->SetParameter(0, 0.98);
+  fCentralityDependence->SetParameter(1, 0.05);
+  fCentralityDependence->SetParameter(2, 50.);
+
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyAllCentrality;
+  TH1D *hEfficiencyCentrality[AliPID::kSPECIES][kNCharges];
+  hEfficiencyAllCentrality = (TH1D *)filein->Get(Form("hEfficiencyAllCentrality_ratioMB_%s", histoName[ihisto]));
+  TCanvas *cFit = new TCanvas("cFit");
+  hEfficiencyAllCentrality->Fit(fCentralityDependence);
+  hEfficiencyAllCentrality->SetMaximum(1.05);
+  hEfficiencyAllCentrality->SetMinimum(0.95);
+  TCanvas *cRatios = new TCanvas("cRatios");
+  cRatios->Divide(2, 3);
+  for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+    for (Int_t icharge = 0; icharge < 2; icharge++) {
+      cRatios->cd(icharge + 1 + 2 * (ipart - 2));
+      cRatios->cd(icharge + 1 + 2 * (ipart - 2))->SetGridx();
+      cRatios->cd(icharge + 1 + 2 * (ipart - 2))->SetGridy();
+      hEfficiencyCentrality[ipart][icharge] = (TH1D *)filein->Get(Form("hEfficiencyCentrality_ratioMB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+      hEfficiencyCentrality[ipart][icharge]->Divide(fCentralityDependence);
+      hEfficiencyCentrality[ipart][icharge]->SetMaximum(1.05);
+      hEfficiencyCentrality[ipart][icharge]->SetMinimum(0.95);
+      hEfficiencyCentrality[ipart][icharge]->SetTitle(Form("%s;centrality percentile;efficiency ratio wrt. fitted centrality dependence", particleLabel[ipart][icharge]));
+      hEfficiencyCentrality[ipart][icharge]->SetStats(kFALSE);
+      hEfficiencyCentrality[ipart][icharge]->Draw();
+    }
+  }
+  
+
+}
+
+//_____________________________________________________________________________-
+
+TOFmatchMC_efficiencyPt_MB_plot(const Char_t *filename)
+{
+  TOFmatchMC_efficiencyPt_MB_plot(filename, kMatchedGoodTracks, 2, 0, 20, 4);
+  TOFmatchMC_efficiencyPt_MB_plot(filename, kMatchedGoodTracks, 2, 1, 25, 4);
+  TOFmatchMC_efficiencyPt_MB_plot(filename, kMatchedGoodTracks, 3, 0, 20, 8);
+  TOFmatchMC_efficiencyPt_MB_plot(filename, kMatchedGoodTracks, 3, 1, 25, 8);
+  TOFmatchMC_efficiencyPt_MB_plot(filename, kMatchedGoodTracks, 4, 0, 20, 2);
+  TOFmatchMC_efficiencyPt_MB_plot(filename, kMatchedGoodTracks, 4, 1, 25, 2);
+}
+
+TH1D *
+TOFmatchMC_efficiencyPt_MB_plot(const Char_t *filename, Int_t ihisto = kMatchedGoodTracks, Int_t ipart, Int_t icharge, Int_t marker = 20, Int_t color = 2, Option_t *opt = "")
+{
+
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+  
+  Double_t ptMin[AliPID::kSPECIES] = {0.5, 0.5, 0.5, 0.5, 0.5};
+  Double_t ptMax[AliPID::kSPECIES] = {3.0, 3.0, 3.0, 3.0, 5.0};
+
+  TF1 *fEff = new TF1("fEff", "[0] * TMath::Exp(-TMath::Power(x / [1], [2])) / (1. + TMath::Exp(([3] - x) / [4]))", 0., 5.0);
+  fEff->SetParameter(0, 0.5);
+  fEff->SetParameter(1, 0.5);
+  fEff->SetParameter(2, 1.);
+  fEff->SetParameter(3, 0.5);
+  fEff->SetParameter(4, 0.5);
+  fEff->SetParLimits(4, 0.3, 2.0);
+  
+  TFile *fileout = TFile::Open(Form("%s/efficiencyPt_MB_%s_%s.root", destdir, AliPID::ParticleName(ipart), chargeName[icharge]), "RECREATE");
+
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyPt = (TH1D *)filein->Get(Form("hEfficiencyPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+
+  hEfficiencyPt->Fit(fEff, "0q", "IME", 0.5, 5.0);
+  hEfficiencyPt->SetTitle(Form("%s;p_{T} (GeV/c);acceptance #times efficiency;", partChargeName[ipart][icharge]));
+  hEfficiencyPt->SetMinimum(0.2);
+  hEfficiencyPt->SetMaximum(0.7);
+  hEfficiencyPt->SetMarkerStyle(marker);
+  hEfficiencyPt->SetMarkerColor(color);
+  hEfficiencyPt->SetMarkerSize(1.5);
+  hEfficiencyPt->SetLineWidth(2);
+  hEfficiencyPt->SetLineColor(color);
+  hEfficiencyPt->GetXaxis()->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
+  hEfficiencyPt->SetStats(kFALSE);
+  cCanvas1->cd();
+  hEfficiencyPt->DrawCopy();
+  fEff->DrawCopy("same");
+  fileout->cd();
+  hEfficiencyPt->Write("hEfficiencyPt");
+  fEff->Write("fEff");
+
+  cCanvas1->SetGridx();
+  cCanvas1->SetGridy();
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_%s_%s.C", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_%s_%s.png", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_%s_%s.eps", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  
+  TH1D *hRatioPt = new TH1D(*hEfficiencyPt);
+  hRatioPt->Divide(fEff);
+  hRatioPt->SetTitle(Form("%s;p_{T} (GeV/c);ratio wrt. fitted dependence;", partChargeName[ipart][icharge]));
+  hRatioPt->SetMinimum(0.9);
+  hRatioPt->SetMaximum(1.1);
+  cCanvas2->cd();
+  hRatioPt->DrawCopy();
+  fileout->cd();
+  hRatioPt->Write("hRatioPt");
+
+  cCanvas2->SetGridx();
+  cCanvas2->SetGridy();
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_%s_%s.C", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_%s_%s.png", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_%s_%s.eps", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  
+
+  fileout->Close();
+
+  //  hEfficiencyPt->Add(fEff, -1.);
+  return hEfficiencyPt;
+}
+
+
+//_____________________________________________________________________________-
+
+TOFmatchMC_efficiencyPt_centrality_plot(const Char_t *filename)
+{
+  TOFmatchMC_efficiencyPt_centrality_plot(filename, kMatchedGoodTracks, 2, 0, 20, 4);
+  TOFmatchMC_efficiencyPt_centrality_plot(filename, kMatchedGoodTracks, 2, 1, 25, 4);
+  TOFmatchMC_efficiencyPt_centrality_plot(filename, kMatchedGoodTracks, 3, 0, 20, 8);
+  TOFmatchMC_efficiencyPt_centrality_plot(filename, kMatchedGoodTracks, 3, 1, 25, 8);
+  TOFmatchMC_efficiencyPt_centrality_plot(filename, kMatchedGoodTracks, 4, 0, 20, 2);
+  TOFmatchMC_efficiencyPt_centrality_plot(filename, kMatchedGoodTracks, 4, 1, 25, 2);
+}
+
+TOFmatchMC_efficiencyPt_fit(TH1 *h, TF1 *f, Int_t param)
+{
+
+  if (param >= 0) {
+    for (Int_t ipar = 0; ipar < f->GetNpar(); ipar++)
+      if (ipar != param)
+       f->FixParameter(ipar, f->GetParameter(ipar));
+      else
+       f->ReleaseParameter(ipar);
+  }
+  else {
+    for (Int_t ipar = 0; ipar < f->GetNpar(); ipar++)
+      f->ReleaseParameter(ipar);
+  }
+  h->Fit(f);
+
+}
+
+TH1D *
+TOFmatchMC_efficiencyPt_centrality_plot(const Char_t *filename, Int_t ihisto = kMatchedGoodTracks, Int_t ipart, Int_t icharge, Int_t marker = 20, Int_t color = 2, Option_t *opt = "")
+{
+
+  TVirtualFitter::SetMaxIterations(1000000);
+
+  /* load HistoUtils */
+  gROOT->LoadMacro("HistoUtils.C");
+  
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+  TCanvas *cCanvas3 = new TCanvas("cCanvas3");
+
+  Double_t ptMin[AliPID::kSPECIES] = {0.5, 0.5, 0.5, 0.5, 0.5};
+  Double_t ptMax[AliPID::kSPECIES] = {3.0, 3.0, 3.0, 3.0, 5.0};
+
+  /* fit minimum-bias efficiency pt */
+
+  TF1 *fEff = new TF1("fEff", "[0] * TMath::Exp(-TMath::Power([1] / x, [2])) + [3] * x", ptMin[ipart], ptMax[ipart]);
+  fEff->SetParameter(0, 0.5);
+  fEff->SetParameter(1, 0.1);
+  fEff->SetParameter(2, 2.);
+  fEff->SetParameter(3, 0.);
+  fEff->SetParameter(4, 0.);
+  Int_t nPars = fEff->GetNpar();
+  Int_t scalePar = 0.;
+  TF1 *fEffCopy = new TF1(*fEff);
+  
+  TFile *fileout = TFile::Open(Form("%s/efficiencyPt_centrality_%s_%s.root", destdir, AliPID::ParticleName(ipart), chargeName[icharge]), "RECREATE");
+  
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyPt = (TH1D *)filein->Get(Form("hEfficiencyPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+  hEfficiencyPt->Fit(fEff, "0", "", 0.5, 1.0);
+  hEfficiencyPt->Fit(fEff, "0", "", 0.5, 1.5);
+  hEfficiencyPt->Fit(fEff, "0", "", 0.5, 2.0);
+  hEfficiencyPt->Fit(fEff, "0", "IMRE", ptMin[ipart], ptMax[ipart]);
+  hEfficiencyPt->Fit(fEff, "0", "IMRE", ptMin[ipart], ptMax[ipart]);
+  hEfficiencyPt->Fit(fEff, "0", "IMRE", ptMin[ipart], ptMax[ipart]);
+
+  /* build efficiency profile */
+  for (Int_t ipar = 0; ipar < nPars; ipar++) {
+    fEffCopy->SetParameter(ipar, fEff->GetParameter(ipar));
+    fEffCopy->SetParError(ipar, fEff->GetParError(ipar));
+  }
+  TProfile *pEfficiencyPt = new TProfile(Form("pEfficiencyPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]), Form("%s;p_{T} (GeV/c);acceptance #times efficiency;", partChargeName[ipart][icharge]), NptBins, ptBin, "s");
+  HistoUtils_Function2Profile(fEffCopy, pEfficiencyPt);
+
+  /* draw */
+  cCanvas1->cd();
+  pEfficiencyPt->SetMarkerStyle(marker);
+  pEfficiencyPt->SetMarkerColor(color);
+  pEfficiencyPt->SetMarkerSize(0);
+  pEfficiencyPt->SetLineWidth(2);
+  pEfficiencyPt->SetLineColor(color);
+  pEfficiencyPt->SetFillStyle(3001);
+  pEfficiencyPt->SetFillColor(color);
+  pEfficiencyPt->GetXaxis()->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
+  pEfficiencyPt->SetStats(kFALSE);
+  pEfficiencyPt->DrawCopy("E2");
+
+  hEfficiencyPt->SetTitle(Form("%s;p_{T} (GeV/c);acceptance #times efficiency;", partChargeName[ipart][icharge]));
+  hEfficiencyPt->SetMarkerStyle(marker);
+  hEfficiencyPt->SetMarkerColor(color);
+  hEfficiencyPt->SetMarkerSize(1.5);
+  hEfficiencyPt->SetLineWidth(2);
+  hEfficiencyPt->SetLineColor(color);
+  hEfficiencyPt->GetXaxis()->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
+  hEfficiencyPt->SetStats(kFALSE);
+  hEfficiencyPt->DrawCopy("same");
+  fEff->DrawCopy("same");
+  cCanvas1->Update();
+
+  /* write */
+  fileout->cd();
+  pEfficiencyPt->Write("pEfficiencyPt");
+  hEfficiencyPt->Write("hEfficiencyPt");
+  fEff->Write("fEff");
+
+  TH1D *hEfficiencyCent = new TH1D("hEfficiencyCent", Form("%s;centrality percentile;acceptance x efficiency scale factor;", partChargeName[ipart][icharge]), NcentralityBins, centralityBin);
+  hEfficiencyCent->SetMinimum(0.9);
+  hEfficiencyCent->SetMaximum(1.1);
+  hEfficiencyCent->SetMarkerStyle(marker);
+  hEfficiencyCent->SetMarkerColor(color);
+  hEfficiencyCent->SetMarkerSize(1.5);
+  hEfficiencyCent->SetLineWidth(2);
+  hEfficiencyCent->SetLineColor(color);
+  hEfficiencyCent->SetStats(kFALSE);
+  
+  TProfile *pEfficiencyPt_cent[NcentralityBins];
+  TH1D *hEfficiencyPt_cent[NcentralityBins];
+  TH1D *hRatioPt_cent[NcentralityBins];
+  
+  /* fix efficiency shape and release scale factor */
+  for (Int_t ipar = 0; ipar < nPars; ipar++)
+    fEff->FixParameter(ipar, fEff->GetParameter(ipar));
+  fEff->ReleaseParameter(scalePar);
+    
+  gStyle->SetOptStat(1100);
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+
+    hEfficiencyPt_cent[icent] = (TH1D *)filein->Get(Form("hEfficiencyPt_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+    hEfficiencyPt_cent[icent]->Fit(fEff, "", "IME", ptMin[ipart], ptMax[ipart]);
+
+    /* build efficiency profile */
+    fEffCopy->SetParameter(scalePar, fEff->GetParameter(scalePar));
+    fEffCopy->SetParError(scalePar, fEff->GetParError(scalePar));
+    pEfficiencyPt_cent[icent] = new TProfile(Form("pEfficiencyPt_centrality%d_%s_%s_%s", icent, histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]), Form("%s;p_{T} (GeV/c);acceptance #times efficiency;", partChargeName[ipart][icharge]), NptBins, ptBin, "s");
+    HistoUtils_Function2Profile(fEffCopy, pEfficiencyPt_cent[icent]);
+    
+    /* draw */
+    cCanvas1->cd();
+    pEfficiencyPt_cent[icent]->SetMarkerStyle(marker);
+    pEfficiencyPt_cent[icent]->SetMarkerColor(color);
+    pEfficiencyPt_cent[icent]->SetMarkerSize(0);
+    pEfficiencyPt_cent[icent]->SetLineWidth(2);
+    pEfficiencyPt_cent[icent]->SetLineColor(color);
+    pEfficiencyPt_cent[icent]->SetFillStyle(3001);
+    pEfficiencyPt_cent[icent]->SetFillColor(color);
+    pEfficiencyPt_cent[icent]->GetXaxis()->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
+    pEfficiencyPt_cent[icent]->SetStats(kFALSE);
+    pEfficiencyPt_cent[icent]->DrawCopy("E2");
+    
+    hEfficiencyPt_cent[icent]->SetTitle(Form("%s (%d-%d\%);p_{T} (GeV/c);acceptance #times efficiency;", partChargeName[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hEfficiencyPt_cent[icent]->SetMarkerStyle(marker);
+    hEfficiencyPt_cent[icent]->SetMarkerColor(color);
+    hEfficiencyPt_cent[icent]->SetMarkerSize(1.5);
+    hEfficiencyPt_cent[icent]->SetLineWidth(2);
+    hEfficiencyPt_cent[icent]->SetLineColor(color);
+    hEfficiencyPt_cent[icent]->GetXaxis()->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
+    hEfficiencyPt_cent[icent]->SetStats(kFALSE);
+    hEfficiencyPt_cent[icent]->DrawCopy("same");
+    fEff->DrawCopy("same");
+    cCanvas1->Update();
+
+    fileout->cd();
+    pEfficiencyPt_cent[icent]->Write(Form("pEfficiencyPt_cent%d", icent));
+    hEfficiencyPt_cent[icent]->Write(Form("hEfficiencyPt_cent%d", icent));
+    fEff->Write(Form("fEff_cent%d", icent));
+
+    hEfficiencyCent->SetBinContent(icent + 1, fEff->GetParameter(scalePar));
+    hEfficiencyCent->SetBinError(icent + 1, fEff->GetParError(scalePar));
+
+    cCanvas1->SetGridx();
+    cCanvas1->SetGridy();
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_%s_%s.C", destdir, icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_%s_%s.png", destdir, icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_%s_%s.eps", destdir, icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+
+    hRatioPt_cent[icent] = new TH1D(*hEfficiencyPt_cent[icent]);
+    hRatioPt_cent[icent]->Divide(fEff);
+    hRatioPt_cent[icent]->SetTitle(Form("%s (%d-%d\%);p_{T} (GeV/c);ratio wrt. fitted dependence;", partChargeName[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hRatioPt_cent[icent]->SetMinimum(0.75);
+    hRatioPt_cent[icent]->SetMaximum(1.25);
+    cCanvas2->cd();
+    hRatioPt_cent[icent]->DrawCopy();
+    fileout->cd();
+    hRatioPt_cent[icent]->Write(Form("hRatioPt_cent%d", icent));
+    
+
+    cCanvas2->SetGridx();
+    cCanvas2->SetGridy();
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_%s_%s.C", destdir, icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_%s_%s.png", destdir, icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_%s_%s.eps", destdir, icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+    
+  }
+
+  cCanvas3->cd();
+  hEfficiencyCent->DrawCopy();
+  fileout->cd();
+  hEfficiencyCent->Write("hEfficiencyCent");
+  
+  cCanvas3->SetGridx();
+  cCanvas3->SetGridy();
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_%s_%s.C", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_%s_%s.png", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_%s_%s.eps", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+
+  //  hEfficiencyPt->Add(fEff, -1.);
+  return hEfficiencyCent;
+}
+
+
+//_____________________________________________________________________________-
+
+TH1D *
+TOFmatchMC_efficiencyPt_centrality_all_plot(const Char_t *filename, Int_t ihisto = kMatchedGoodTracks, Int_t marker = 20, Int_t color = 1, Option_t *opt = "")
+{
+
+  /*
+    this function measures the centrality-dependent scale factor
+    of the matching efficiency, assuming that the scale factor
+    is common to all particles species
+
+    1.) first the inclusive pt-dependence is fitted for MB events with scale factor = 1.
+    2.) the shape of the pt-dependence is the fixed and the scale factor released
+    3.) using a fixed-shape the inclusive pt-dependence is fitted in centrality bins with only the scale factor as a free parameter    
+    
+  */
+  
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+
+  /* pt-dependent matching efficiency function with scale factor */
+  TF1 *fEff = new TF1("fEff", "[5] * [0] * TMath::Exp(-TMath::Power(x / [1], [2])) / (1. + TMath::Exp(([3] - x) / [4]))", 0., 5.0);
+  fEff->SetParameter(0, 0.5);
+  fEff->SetParameter(1, 0.5);
+  fEff->SetParameter(2, 1.);
+  fEff->SetParameter(3, 0.5);
+  fEff->SetParameter(4, 0.5);
+  fEff->SetParLimits(4, 0.3, 2.0);
+  fEff->FixParameter(5, 1.);
+  
+  TFile *fileout = TFile::Open(Form("%s/efficiencyPt_MB_all.root", destdir), "RECREATE");
+  
+  /* fit inclusive pt-dependence in MB events */
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyPt = (TH1D *)filein->Get(Form("hEfficiencyAllPt_MB_%s", histoName[ihisto]));
+  hEfficiencyPt->Fit(fEff, "0", "IME", 0.5, 5.0);
+  hEfficiencyPt->SetTitle("all particles;p_{T} (GeV/c);acceptance #times efficiency;");
+  hEfficiencyPt->SetMinimum(0.2);
+  hEfficiencyPt->SetMaximum(0.7);
+  hEfficiencyPt->SetMarkerStyle(marker);
+  hEfficiencyPt->SetMarkerColor(color);
+  hEfficiencyPt->SetMarkerSize(1.5);
+  hEfficiencyPt->SetLineWidth(2);
+  hEfficiencyPt->SetLineColor(color);
+  hEfficiencyPt->GetXaxis()->SetRangeUser(0.5 + 0.001, 5.0 - 0.001);
+  hEfficiencyPt->SetStats(kFALSE);
+  cCanvas1->cd();
+  hEfficiencyPt->DrawCopy();
+  fEff->DrawCopy("same");
+  fileout->cd();
+  hEfficiencyPt->Write("hEfficiencyPt");
+  fEff->Write("fEff");
+
+  cCanvas1->SetGridx();
+  cCanvas1->SetGridy();
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.C", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.png", destdir));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_all.eps", destdir));
+
+  TH1D *hRatioPt = new TH1D(*hEfficiencyPt);
+  hRatioPt->Divide(fEff);
+  hRatioPt->SetTitle("all particles;p_{T} (GeV/c);ratio wrt. fitted dependence;");
+  hRatioPt->SetMinimum(0.9);
+  hRatioPt->SetMaximum(1.1);
+  cCanvas2->cd();
+  hRatioPt->DrawCopy();
+  fileout->cd();
+  hRatioPt->Write("hRatioPt");
+
+  cCanvas2->SetGridx();
+  cCanvas2->SetGridy();
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_all.C", destdir));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_all.png", destdir));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_all.eps", destdir));
+  
+  /* fix efficiency shape and release scale factor */
+  fEff->FixParameter(0, fEff->GetParameter(0));
+  fEff->FixParameter(1, fEff->GetParameter(1));
+  fEff->FixParameter(2, fEff->GetParameter(2));
+  fEff->FixParameter(3, fEff->GetParameter(3));
+  fEff->FixParameter(4, fEff->GetParameter(4));
+  fEff->ReleaseParameter(5);
+  
+  TH1D *hEfficiencyCent = new TH1D("hEfficiencyCent", "all particles;centrality percentile;acceptance x efficiency scale factor;", NcentralityBins, centralityBin);
+  hEfficiencyCent->SetMinimum(0.95);
+  hEfficiencyCent->SetMaximum(1.05);
+  hEfficiencyCent->SetMarkerStyle(marker);
+  hEfficiencyCent->SetMarkerColor(color);
+  hEfficiencyCent->SetMarkerSize(1.5);
+  hEfficiencyCent->SetLineWidth(2);
+  hEfficiencyCent->SetLineColor(color);
+  hEfficiencyCent->SetStats(kFALSE);
+  
+  
+  /* fit inclusive pt-dependence in centrality bins
+     with fixed pt-shape and free scale factor */
+  TH1D *hEfficiencyPt_cent[NcentralityBins];
+  TH1D *hRatioPt_cent[NcentralityBins];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++) {
+    
+    hEfficiencyPt_cent[icent] = (TH1D *)filein->Get(Form("hEfficiencyAllPt_centrality%d_%s", icent, histoName[ihisto]));
+    hEfficiencyPt_cent[icent]->Fit(fEff, "", "IME", 0.5, 5.0);
+    
+    hEfficiencyPt_cent[icent]->SetTitle(Form("all particles (%d-%d\%);p_{T} (GeV/c);acceptance #times efficiency;", (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hEfficiencyPt_cent[icent]->SetMinimum(0.2);
+    hEfficiencyPt_cent[icent]->SetMaximum(0.8);
+    hEfficiencyPt_cent[icent]->SetMarkerStyle(marker);
+    hEfficiencyPt_cent[icent]->SetMarkerColor(color);
+    hEfficiencyPt_cent[icent]->SetMarkerSize(1.5);
+    hEfficiencyPt_cent[icent]->SetLineWidth(2);
+    hEfficiencyPt_cent[icent]->SetLineColor(color);
+    hEfficiencyPt_cent[icent]->GetXaxis()->SetRangeUser(0.5 + 0.001, 5.0 - 0.001);
+    hEfficiencyPt_cent[icent]->SetStats(kFALSE);
+    cCanvas1->cd();
+    hEfficiencyPt_cent[icent]->DrawCopy();
+    fEff->DrawCopy("same");
+    hEfficiencyPt_cent[icent]->Write(Form("hEfficiencyPt_cent%d", icent));
+    fEff->Write(Form("fEff_cent%d", icent));
+    
+    hEfficiencyCent->SetBinContent(icent + 1, fEff->GetParameter(5));
+    hEfficiencyCent->SetBinError(icent + 1, fEff->GetParError(5));
+    
+    cCanvas1->SetGridx();
+    cCanvas1->SetGridy();
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.C", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.png", destdir, icent));
+    cCanvas1->SaveAs(Form("%s/efficiencyPt_centrality%d_all.eps", destdir, icent));
+    
+    hRatioPt_cent[icent] = new TH1D(*hEfficiencyPt_cent[icent]);
+    hRatioPt_cent[icent]->Divide(fEff);
+    hRatioPt_cent[icent]->SetTitle(Form("all particles (%d-%d\%);p_{T} (GeV/c);ratio wrt. fitted dependence;", (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]));
+    hRatioPt_cent[icent]->SetMinimum(0.9);
+    hRatioPt_cent[icent]->SetMaximum(1.1);
+    cCanvas2->cd();
+    hRatioPt_cent[icent]->DrawCopy();
+    fileout->cd();
+    hRatioPt_cent[icent]->Write(Form("hRatioPt_cent%d", icent));
+
+    cCanvas2->SetGridx();
+    cCanvas2->SetGridy();
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.C", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.png", destdir, icent));
+    cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_centrality%d_all.eps", destdir, icent));
+
+    
+  }
+
+  TF1 *fEffCent = new TF1("fEffCent", "[0] - [1] * TMath::Exp(-[2] * TMath::Power(x, [3]))", 0., 90.);
+  fEffCent->SetParameter(0, 1.02);
+  fEffCent->SetParameter(1, 0.04);
+  fEffCent->SetParameter(2, 0.001);
+  fEffCent->SetParameter(3, 2.);
+  hEfficiencyCent->Fit(fEffCent, "q0", "IME", 0., 90.);
+  
+  TCanvas *cCanvas3 = new TCanvas("cCanvas3");
+  hEfficiencyCent->DrawCopy();
+  fEffCent->DrawCopy("same");
+  fileout->cd();
+  hEfficiencyCent->Write("hEfficiencyCent");
+  fEffCent->Write("fEffCent");
+  
+  cCanvas3->SetGridx();
+  cCanvas3->SetGridy();
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.C", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.png", destdir));
+  cCanvas3->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_all.eps", destdir));
+
+  TCanvas *cCanvas4 = new TCanvas("cCanvas4");
+
+  TH1D *hRatioCent = new TH1D(*hEfficiencyCent);
+  hRatioCent->Divide(fEffCent);
+  hRatioCent->SetTitle(Form("all particles;centrality percentile;ratio wrt. fitted dependence;"));
+  hRatioCent->SetMinimum(0.95);
+  hRatioCent->SetMaximum(1.05);
+  cCanvas4->cd();
+  hRatioCent->DrawCopy();
+  fileout->cd();
+  hRatioCent->Write("hRatioCent");
+
+  cCanvas4->SetGridx();
+  cCanvas4->SetGridy();
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.C", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.png", destdir));
+  cCanvas4->SaveAs(Form("%s/efficiencyCentrality_scaleFactor_ratioFit_all.eps", destdir));
+  
+
+
+  //  hEfficiencyPt->Add(fEff, -1.);
+  return hEfficiencyCent;
+}
+
+
+//_____________________________________________________________________________-
+
+TOFmatchMC_efficiencyPt_MB_smooth_plot(const Char_t *filename)
+{
+  TOFmatchMC_efficiencyPt_MB_smooth_plot(filename, kMatchedGoodTracks, 2, 0, 20, 4);
+  TOFmatchMC_efficiencyPt_MB_smooth_plot(filename, kMatchedGoodTracks, 2, 1, 25, 4);
+  TOFmatchMC_efficiencyPt_MB_smooth_plot(filename, kMatchedGoodTracks, 3, 0, 20, 8);
+  TOFmatchMC_efficiencyPt_MB_smooth_plot(filename, kMatchedGoodTracks, 3, 1, 25, 8);
+  TOFmatchMC_efficiencyPt_MB_smooth_plot(filename, kMatchedGoodTracks, 4, 0, 20, 2);
+  TOFmatchMC_efficiencyPt_MB_smooth_plot(filename, kMatchedGoodTracks, 4, 1, 25, 2);
+}
+
+TH1D *
+TOFmatchMC_efficiencyPt_MB_smooth_plot(const Char_t *filename, Int_t ihisto = kMatchedGoodTracks, Int_t ipart, Int_t icharge, Int_t marker = 20, Int_t color = 2, Option_t *opt = "")
+{
+  
+  TCanvas *cCanvas1 = new TCanvas("cCanvas1");
+  TCanvas *cCanvas2 = new TCanvas("cCanvas2");
+  
+  Double_t ptMin[AliPID::kSPECIES] = {0.5, 0.5, 0.5, 0.5, 0.5};
+  Double_t ptMax[AliPID::kSPECIES] = {3.0, 3.0, 3.0, 3.0, 5.0};
+
+  TF1 *fEff = new TF1("fEff", "[0] + [1] * x - [2] * TMath::Exp(-[3] * TMath::Power(x, [4]))", 1.0, 5.0);
+  fEff->SetParameter(0, 0.5);
+  fEff->SetParameter(1, 0.);
+  fEff->SetParameter(2, 0.5);
+  fEff->SetParameter(3, 1.);
+  fEff->SetParameter(4, 2.);
+
+
+  TFile *filein = TFile::Open(filename);
+  TH1D *hEfficiencyPt = (TH1D *)filein->Get(Form("hEfficiencyPt_MB_%s_%s_%s", histoName[ihisto], AliPID::ParticleName(ipart), chargeName[icharge]));
+  hEfficiencyPt->Fit(fEff, "0", "IME", 1.0, 5.0);
+  hEfficiencyPt->SetTitle(Form("%s;p_{T} (GeV/c);acceptance #times efficiency;", partChargeName[ipart][icharge]));
+  hEfficiencyPt->SetMinimum(0.2);
+  hEfficiencyPt->SetMaximum(0.7);
+  hEfficiencyPt->SetMarkerStyle(marker);
+  hEfficiencyPt->SetMarkerColor(color);
+  hEfficiencyPt->SetMarkerSize(1.5);
+  hEfficiencyPt->SetLineWidth(2);
+  hEfficiencyPt->SetLineColor(color);
+  hEfficiencyPt->GetXaxis()->SetRangeUser(ptMin[ipart] + 0.001, ptMax[ipart] - 0.001);
+  hEfficiencyPt->SetStats(kFALSE);
+  cCanvas1->cd();
+  hEfficiencyPt->Draw(opt);
+  fEff->Draw("same");
+
+  cCanvas1->SetGridx();
+  cCanvas1->SetGridy();
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_smooth_%s_%s.C", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_smooth_%s_%s.root", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_smooth_%s_%s.png", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas1->SaveAs(Form("%s/efficiencyPt_MB_smooth_%s_%s.eps", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  
+  TH1D *hRatioPt = new TH1D(*hEfficiencyPt);
+  hRatioPt->Divide(fEff);
+  hRatioPt->SetTitle(Form("%s;p_{T} (GeV/c);ratio wrt. fitted dependence;", partChargeName[ipart][icharge]));
+  hRatioPt->SetMinimum(0.9);
+  hRatioPt->SetMaximum(1.1);
+  cCanvas2->cd();
+  hRatioPt->Draw();
+
+  cCanvas2->SetGridx();
+  cCanvas2->SetGridy();
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_smooth_%s_%s.C", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_smooth_%s_%s.root", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_smooth_%s_%s.png", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  cCanvas2->SaveAs(Form("%s/efficiencyPt_ratioFit_MB_smooth_%s_%s.eps", destdir, AliPID::ParticleName(ipart), chargeName[icharge]));
+  
+
+  /* smoothing step */
+  TH1D *hEfficiencyPt_smooth = new TH1D(*hEfficiencyPt);
+  Double_t ratio, value, error;
+  for (Int_t ipt = 0; ipt < hRatioPt->GetNbinsX(); ipt++) {
+    if (hRatioPt->GetBinCenter(ipt + 1) < 1.5) continue;
+    ratio = hRatioPt->GetBinContent(ipt + 1);
+    value = hEfficiencyPt->GetBinContent(ipt + 1);
+    error = hEfficiencyPt->GetBinError(ipt + 1);
+    value /= ratio;
+    hEfficiencyPt_smooth->SetBinContent(ipt + 1, value);
+  }
+  new TCanvas();
+  hEfficiencyPt_smooth->Draw();
+
+  //  hEfficiencyPt->Add(fEff, -1.);
+  return hEfficiencyPt;
+}
+
+TOFmatchMC_matchingEfficiency(const Char_t *filename, Bool_t useGFcorrection = kTRUE)
+{
+
+  Int_t marker[2] = {20, 21};
+  Int_t color[AliPID::kSPECIES] = {1, 1, 4, 8, 2};
+  Char_t *partLatex[AliPID::kSPECIES][2] = {
+    "", "", "#pi^{+}", "K^{+}", "p",
+    "", "", "#pi^{-}", "K^{-}", "#bar{p}"
+  };
+
+  TFile *filein = TFile::Open(filename);
+  if (useGFcorrection)
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency.root", "RECREATE");
+  else
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency_noGF.root", "RECREATE");
+  TH1D *hEff;
+  TF1 *fGF;
+  Char_t title[1024];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++)
+      for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+       hEff = (TH1D *)filein->Get(Form("hEfficiencyPt_centrality%d_hMatchedGoodTracks_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       /* geant-fluka correction */
+       fGF = TOFmatchMC_geantflukaCorrection(ipart, icharge);
+       if (useGFcorrection)
+         hEff->Divide(fGF);
+       sprintf(title, "%s (%d-%d%%);p_{T} (GeV/c);matching efficiency;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]);
+       hEff->SetMarkerStyle(marker[icharge]);
+       hEff->SetMarkerColor(color[ipart]);
+       hEff->SetLineColor(1);
+       hEff->SetLineWidth(1);
+       hEff->SetTitle(title);
+       hEff->SetName(Form("hMatchEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       fileout->cd();
+       hEff->Write();
+      }
+  
+  fileout->Close();
+}
+
+TOFmatchMC_matchingEfficiency_mismatchCorrected(const Char_t *filename, Bool_t useGFcorrection = kTRUE)
+{
+
+  Int_t marker[2] = {20, 21};
+  Int_t color[AliPID::kSPECIES] = {1, 1, 4, 8, 2};
+  Char_t *partLatex[AliPID::kSPECIES][2] = {
+    "", "", "#pi^{+}", "K^{+}", "p",
+    "", "", "#pi^{-}", "K^{-}", "#bar{p}"
+  };
+
+  TFile *filein = TFile::Open(filename);
+  if (useGFcorrection)
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency_mismatchCorrected.root", "RECREATE");
+  else
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency_mismatchCorrected_noGF.root", "RECREATE");
+  TH1D *hEff;
+  TF1 *fGF;
+  Char_t title[1024];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++)
+      for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+       hEff = (TH1D *)filein->Get(Form("hEfficiencyPt_centrality%d_hMatchedTracks_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       /* geant-fluka correction */
+       fGF = TOFmatchMC_geantflukaCorrection(ipart, icharge);
+       if (useGFcorrection)
+         hEff->Divide(fGF);
+       sprintf(title, "%s (%d-%d%%);p_{T} (GeV/c);matching efficiency;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]);
+       hEff->SetMarkerStyle(marker[icharge]);
+       hEff->SetMarkerColor(color[ipart]);
+       hEff->SetLineColor(1);
+       hEff->SetLineWidth(1);
+       hEff->SetTitle(title);
+       hEff->SetName(Form("hMatchEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       fileout->cd();
+       hEff->Write();
+      }
+  
+  fileout->Close();
+}
+
+TOFmatchMC_matchingEfficiency_acceptTRDin(const Char_t *filename, Bool_t useGFcorrection = kTRUE)
+{
+
+  Int_t marker[2] = {20, 21};
+  Int_t color[AliPID::kSPECIES] = {1, 1, 4, 8, 2};
+  Char_t *partLatex[AliPID::kSPECIES][2] = {
+    "", "", "#pi^{+}", "K^{+}", "p",
+    "", "", "#pi^{-}", "K^{-}", "#bar{p}"
+  };
+
+  TFile *filein = TFile::Open(filename);
+  if (useGFcorrection)
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency_acceptTRDin.root", "RECREATE");
+  else
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency_acceptTRDin_noGF.root", "RECREATE");
+  TH1D *hEff;
+  TF1 *fGF;
+  Char_t title[1024];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++)
+      for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+       hEff = (TH1D *)filein->Get(Form("hEfficiencyPt_centrality%d_hMatchedGoodTracks_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       /* geant-fluka correction */
+       fGF = TOFmatchMC_geantflukaCorrection_acceptTRDin(ipart, icharge);
+       if (useGFcorrection)
+         hEff->Divide(fGF);
+       sprintf(title, "%s (%d-%d%%);p_{T} (GeV/c);matching efficiency;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]);
+       hEff->SetMarkerStyle(marker[icharge]);
+       hEff->SetMarkerColor(color[ipart]);
+       hEff->SetLineColor(1);
+       hEff->SetLineWidth(1);
+       hEff->SetTitle(title);
+       hEff->SetName(Form("hMatchEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       fileout->cd();
+       hEff->Write();
+      }
+  
+  fileout->Close();
+}
+
+TOFmatchMC_matchingEfficiency_rejectTRDin(const Char_t *filename, Bool_t useGFcorrection = kTRUE)
+{
+
+  Int_t marker[2] = {20, 21};
+  Int_t color[AliPID::kSPECIES] = {1, 1, 4, 8, 2};
+  Char_t *partLatex[AliPID::kSPECIES][2] = {
+    "", "", "#pi^{+}", "K^{+}", "p",
+    "", "", "#pi^{-}", "K^{-}", "#bar{p}"
+  };
+
+  TFile *filein = TFile::Open(filename);
+  if (useGFcorrection)
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency_rejectTRDin.root", "RECREATE");
+  else
+    TFile *fileout = TFile::Open("TOF_matchingEfficiency_rejectTRDin_noGF.root", "RECREATE");
+  TH1D *hEff;
+  TF1 *fGF;
+  Char_t title[1024];
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++)
+      for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++) {
+       hEff = (TH1D *)filein->Get(Form("hEfficiencyPt_centrality%d_hMatchedGoodTracks_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       /* geant-fluka correction */
+       fGF = TOFmatchMC_geantflukaCorrection_rejectTRDin(ipart, icharge);
+       if (useGFcorrection)
+         hEff->Divide(fGF);
+       sprintf(title, "%s (%d-%d%%);p_{T} (GeV/c);matching efficiency;", partLatex[ipart][icharge], (Int_t)centralityBin[icent], (Int_t)centralityBin[icent + 1]);
+       hEff->SetMarkerStyle(marker[icharge]);
+       hEff->SetMarkerColor(color[ipart]);
+       hEff->SetLineColor(1);
+       hEff->SetLineWidth(1);
+       hEff->SetTitle(title);
+       hEff->SetName(Form("hMatchEff_cent%d_%s_%s", icent, AliPID::ParticleName(ipart), chargeName[icharge]));
+       fileout->cd();
+       hEff->Write();
+      }
+  
+  fileout->Close();
+}
+
+TF1 *
+TOFmatchMC_geantflukaCorrection(Int_t ipart, Int_t icharge)
+{
+
+  if (ipart == 3 && icharge == kNegative) {
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionKaMinus(x)", 0., 5.);
+    return f;
+  }
+  else if (ipart == 4 && icharge == kNegative) {
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionPrMinus(x)", 0., 5.);
+  }
+  else
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionNull(x)", 0., 5.);
+
+  return f;
+}
+
+
+TF1 *
+TOFmatchMC_geantflukaCorrection_acceptTRDin(Int_t ipart, Int_t icharge)
+{
+
+  if (ipart == 3 && icharge == kNegative) {
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionKaMinus_acceptTRDin(x)", 0., 5.);
+    return f;
+  }
+  else if (ipart == 4 && icharge == kNegative) {
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionPrMinus_acceptTRDin(x)", 0., 5.);
+  }
+  else
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionNull(x)", 0., 5.);
+
+  return f;
+}
+
+
+TF1 *
+TOFmatchMC_geantflukaCorrection_rejectTRDin(Int_t ipart, Int_t icharge)
+{
+
+  if (ipart == 3 && icharge == kNegative) {
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionKaMinus_rejectTRDin(x)", 0., 5.);
+    return f;
+  }
+  else if (ipart == 4 && icharge == kNegative) {
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionPrMinus_rejectTRDin(x)", 0., 5.);
+  }
+  else
+    TF1 *f = new TF1(Form("fGeantFluka_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge]), "MatchingPtGeantFlukaCorrectionNull(x)", 0., 5.);
+
+  return f;
+}
+
+
+Double_t
+MatchingPtGeantFlukaCorrectionNull(Double_t pTmc)
+{
+  return 1.;
+}
+
+Double_t 
+MatchingPtGeantFlukaCorrectionPrMinus(Double_t pTmc)
+{
+  Float_t ptTPCoutP =pTmc*(1-6.81059e-01*TMath::Exp(-pTmc*4.20094));
+  return (TMath::Power(1 - 0.129758*TMath::Exp(-ptTPCoutP*0.679612),0.07162/0.03471));
+}
+
+Double_t 
+MatchingPtGeantFlukaCorrectionPrMinus_acceptTRDin(Double_t pTmc)
+{
+  Float_t ptTPCoutP =pTmc*(1-6.81059e-01*TMath::Exp(-pTmc*4.20094));
+  return (TMath::Power(1 - 0.129758*TMath::Exp(-ptTPCoutP*0.679612),0.14638485/0.03471));
+}
+
+Double_t 
+MatchingPtGeantFlukaCorrectionPrMinus_rejectTRDin(Double_t pTmc)
+{
+  Float_t ptTPCoutP =pTmc*(1-6.81059e-01*TMath::Exp(-pTmc*4.20094));
+  return (TMath::Power(1 - 0.129758*TMath::Exp(-ptTPCoutP*0.679612),0.02406/0.03471));
+}
+
+Double_t
+MatchingPtGeantFlukaCorrectionKaMinus(Double_t pTmc)
+{
+  Float_t ptTPCoutK=pTmc*(1- 3.37297e-03/pTmc/pTmc - 3.26544e-03/pTmc);
+  return TMath::Min((TMath::Power(0.972865 + 0.0117093*ptTPCoutK,0.07162/0.03471)), 1.);
+}
+
+Double_t
+MatchingPtGeantFlukaCorrectionKaMinus_acceptTRDin(Double_t pTmc)
+{
+  Float_t ptTPCoutK=pTmc*(1- 3.37297e-03/pTmc/pTmc - 3.26544e-03/pTmc);
+  return TMath::Min((TMath::Power(0.972865 + 0.0117093*ptTPCoutK,0.14638485/0.03471)), 1.);
+}
+
+Double_t
+MatchingPtGeantFlukaCorrectionKaMinus_rejectTRDin(Double_t pTmc)
+{
+  Float_t ptTPCoutK=pTmc*(1- 3.37297e-03/pTmc/pTmc - 3.26544e-03/pTmc);
+  return TMath::Min((TMath::Power(0.972865 + 0.0117093*ptTPCoutK,0.02406/0.03471)), 1.);
+}
diff --git a/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFpid.C b/PWGLF/SPECTRA/PiKaPr/TOF/PbPb276/macros/TOFpid.C
new file mode 100644 (file)
index 0000000..264d83a
--- /dev/null
@@ -0,0 +1,2476 @@
+#define DISPLAY 0
+
+/* SIGNAL SHAPE */
+Bool_t GAUSSIAN_SIGNAL = kFALSE;
+Bool_t GAUSSIANTAIL_SIGNAL = kFALSE;
+Bool_t GAUSSIANTAIL2_SIGNAL = kFALSE;
+Bool_t GAUSSIANPLUSGAUSSIANTAIL_SIGNAL = kFALSE;
+Bool_t GAUSSIANPLUSEXPONENTIAL_SIGNAL = kFALSE;
+Bool_t EXPECTED_SIGNAL_TAIL = kTRUE;
+Bool_t EXPECTED_SIGNAL_TEMPLATE = kTRUE;
+Bool_t EXPECTED_SIGNAL_FIT = kFALSE;
+/* SIGNAL PARAMETERS */
+Bool_t FIX_SIGNAL_MEAN = kTRUE;
+Bool_t FIX_SIGNAL_SIGMA = kTRUE;
+Bool_t FIX_SIGNAL_TAIL = kTRUE;
+Float_t SCALE_SIGNAL_SIGMA = 1.;
+Float_t SCALE_SIGNAL_TAIL = 1.;
+/* OTHER STUFF */
+Char_t *SIGNAL_PARAM_FILE = NULL;//"signalParamFile.root";
+Float_t DEFAULT_SIGNAL_MEAN = 0.;
+Float_t MIN_SIGNAL_MEAN = -0.2;
+Float_t MAX_SIGNAL_MEAN = 0.2.;
+Float_t DEFAULT_SIGNAL_SIGMA = 1.;
+Float_t MIN_SIGNAL_SIGMA = 0.8;
+Float_t MAX_SIGNAL_SIGMA = 1.2;
+Float_t DEFAULT_SIGNAL_TAIL = 1.;
+Float_t MIN_SIGNAL_TAIL = 0.5;
+Float_t MAX_SIGNAL_TAIL = 1.5;
+/* BACKGROUND */
+Bool_t EXPECTED_BACKGROUND_TAIL = kTRUE;
+Bool_t EXPECTED_BACKGROUND_TEMPLATE = kTRUE;
+Bool_t EXPECTED_BACKGROUND_FIT = kFALSE;
+Bool_t GAUSSIAN_BACKGROUND = kFALSE;
+Bool_t USE_ELECTRON_BACKGROUND = kTRUE;
+/* BACKGROUND PARAMETERS */
+Bool_t FIX_BACKGROUND_MEAN = kTRUE;
+Bool_t FIX_BACKGROUND_SIGMA = kTRUE;
+Bool_t FIX_BACKGROUND_TAIL = kTRUE;
+Float_t SCALE_BACKGROUND_SIGMA = 1.;
+Float_t SCALE_BACKGROUND_TAIL = 1.;
+/* MISMATCH */
+Bool_t NO_MISMATCH = kFALSE;
+Bool_t EXPECTED_MISMATCH = kTRUE;
+Bool_t EXPONENTIAL_MISMATCH = kFALSE;
+Bool_t UNIFORM_MISMATCH = kFALSE;
+Bool_t DOUBLEEXPONENTIAL_MISMATCH = kFALSE;
+Bool_t UNIFORMPLUSEXPONENTIAL_MISMATCH = kFALSE;
+/* AUTOMATIC CONSTRAINS */
+Float_t FIT_ELECTRONS_PT_MIN = 0.;
+Float_t FIT_ELECTRONS_PT_MAX = 0.;
+Float_t FIT_MUONS_PT_MIN = 0.;
+Float_t FIT_MUONS_PT_MAX = 0.;
+Float_t FIT_PIONS_PT_MIN = 0.;
+Float_t FIT_PIONS_PT_MAX = 5.;
+
+Float_t CONSTRAINSIGNAL_LIMIT = 0.;
+Float_t CONSTRAINTAIL_LIMIT = 0.;
+
+enum EFitParams_t {
+  kMean,
+  kSigma,
+  kTail,
+  kTotalCounts,
+  kIntegralCounts,
+  kSignalCounts,
+  kBkg1Counts,
+  kBkg2Counts,
+  kBkg3Counts,
+  kBkg4Counts,
+  kMismatchCounts,
+  kNFitParams
+};
+
+/* fit output params name */
+const Char_t *fitParamName[kNFitParams] = {
+  "Mean",
+  "Sigma",
+  "Tail",
+  "TotalCounts",
+  "IntegralCounts",
+  "SignalCounts",
+  "Bkg1Counts",
+  "Bkg2Counts",
+  "Bkg3Counts",
+  "Bkg4Counts",
+  "MismatchCounts"
+};
+
+/* fit output params title */
+const Char_t *fitParamTitle[kNFitParams] = {
+  "Signal mean;p_{T} (GeV/c);#mu (ps)",
+  "Signal sigma;p_{T} (GeV/c);#sigma (ps)",
+  "Signal tail;p_{T} (GeV/c);#sigma_{tail} (ps)",
+  "Total counts;p_{T} (GeV/c);counts",
+  "Total counts within fit range;p_{T} (GeV/c);counts",
+  "Signal counts;p_{T} (GeV/c);counts",
+  "Background-1 counts;p_{T} (GeV/c);counts",
+  "Background-2 counts;p_{T} (GeV/c);counts",
+  "Background-3 counts;p_{T} (GeV/c);counts",
+  "Background-4 counts;p_{T} (GeV/c);counts",
+  "Mismatch counts within fit range;p_{T} (GeV/c);counts"
+};
+
+/**************************************************************/
+/*** GENERATION OF TEMPLATE HISTOS ****************************/
+/**************************************************************/
+
+const Int_t NmismatchTrials = 1;
+const Int_t NexpectedTrials = 1;
+
+/**************************************************************/
+/*** HISTOS AND BINNING ***************************************/
+/**************************************************************/
+
+/**************************************************************/
+enum ECharge_t {
+  kPositive,
+  kNegative,
+  kNCharges
+};
+const Char_t *chargeName[kNCharges] = {
+  "positive",
+  "negative",
+};
+/**************************************************************/
+enum EHistoParam_t {
+  kCentrality,
+  kTOFsigma,
+  kPt,
+  kTPCsigma,
+  kNHistoParams
+};
+/**************************************************************/
+const Int_t NcentralityBins = 10;
+Double_t centralityBin[NcentralityBins + 1] = {0., 5., 10., 20., 30., 40., 50., 60., 70., 80., 90.};
+/**************************************************************/
+const Int_t NtofsigmaBins = 1750;
+Double_t tofsigmaBin[NtofsigmaBins + 1];
+Double_t tofsigmaMin = -100., tofsigmaMax = 250., tofsigmaStep = (tofsigmaMax - tofsigmaMin) / NtofsigmaBins;
+/**************************************************************/
+const Int_t NtofsignalBins = 2000;
+Double_t tofsignalBin[NtofsignalBins + 1];
+Double_t tofsignalMin = -48800., tofsignalMax = 48800., tofsignalStep = (tofsignalMax - tofsignalMin) / NtofsignalBins;
+/**************************************************************/
+const Int_t NptBins = 46;
+Double_t ptBin[NptBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+/**************************************************************/
+const Int_t NmtBins = 46;
+Double_t mtBin[NmtBins + 1] = {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.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.2, 3.4, 3.6, 3.8, 4.0, 4.2, 4.4, 4.6, 4.8, 5.0};
+/**************************************************************/
+const Int_t NtpcsigmaBins = 10;
+Double_t tpcsigmaBin[NtpcsigmaBins + 1];
+Double_t tpcsigmaMin = -5., tpcsigmaMax = 5., tpcsigmaStep = (tpcsigmaMax - tpcsigmaMin) / NtpcsigmaBins;
+/**************************************************************/
+Int_t NparamsBins[kNHistoParams] = {NcentralityBins, NtofsigmaBins, NptBins, NtpcsigmaBins};
+Double_t *paramBin[kNHistoParams] = {centralityBin, tofsigmaBin, ptBin, tpcsigmaBin};
+/**************************************************************/
+
+/**************************************************************/
+/**************************************************************/
+/**************************************************************/
+
+Double_t tofReso = 85.;
+Double_t tofTail = 80.;
+const Char_t *t0FillOnlineFileName = "~/ALICE.2011/ANALYSIS/TOFSpectraPbPb/t0fill/T0FillOnline.139465.extended.root";
+Double_t t0Fill_offset = -1.26416e+04;
+//const Char_t *t0FillOnlineFileName = "T0FillOnline.117116.extended.root";
+//Double_t t0Fill_offset = -1.35543e+04;
+const Char_t *enabledChannelsFileName = "~/ALICE.2011/ANALYSIS/TOFSpectraPbPb/enabledch/enabledChannels.139507.root";
+
+/**************************************************************/
+
+AliTOFGeometry tofGeo;
+Float_t c = TMath::C() * 1.e2 / 1.e12; /* cm/ps */
+Float_t c_1 = 1. / c;
+
+Double_t
+GenerateRandomHit(TH1F *hT0Fill, Double_t t0fill, Int_t index)
+{
+  
+  Int_t det[5];
+  Float_t length, timeexp, pos[3];
+  
+  /* compute length and expected time */
+  tofGeo.GetVolumeIndices(index, det);
+  tofGeo.GetPosPar(det, pos);
+  length = 0.;
+  for (Int_t i = 0; i < 3; i++) length += pos[i] * pos[i];
+  length = TMath::Sqrt(length);
+  timeexp = length * c_1;
+  
+  Double_t hittime = hT0Fill->GetRandom() - t0fill + timeexp;
+  return hittime;
+
+}
+
+/**************************************************************/
+
+TOFpid(const Char_t *filename, Int_t ipart, Int_t icharge, Int_t iipart, Bool_t electronCut = kFALSE, Bool_t cutOnTPC = kFALSE, Float_t tpcsignalMin = -2., Float_t tpcsignalMax = 2., Int_t evMax = kMaxInt, Int_t startEv = 0, Bool_t mcFlag = kFALSE)
+{
+  
+  printf("****************************************\n");
+  printf("RUNNING TOF PID:\n");
+  printf("RAPIDITY-CUT:   %s\n", AliPID::ParticleName(ipart));
+  printf("CHARGE:         %s\n", chargeName[icharge]);
+  printf("PARTICLE-ID:    %s\n", AliPID::ParticleName(iipart));
+  if (electronCut)
+    printf("-> ELECTRON CUT REQUESTED\n");
+  if (cutOnTPC)
+    printf(" -> CUT-ON-TPC [%3.1f,%3.1f]\n", tpcsignalMin, tpcsignalMax);
+  printf("****************************************\n");
+
+  /* include path for ACLic */
+  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
+  gSystem->AddIncludePath("-I$ALICE_ROOT/TOF");
+  /* load libraries */
+  gSystem->Load("libANALYSIS");
+  gSystem->Load("libANALYSISalice");
+  /* build analysis task class */
+  gROOT->LoadMacro("AliAnalysisParticle.cxx+g");
+  gROOT->LoadMacro("AliAnalysisEvent.cxx+g");
+  gROOT->LoadMacro("AliAnalysisTrack.cxx+g");
+
+  /* create TOF response with tail */
+  gROOT->LoadMacro("~/ALICE.2011/ANALYSIS/TOFSpectraPbPb/macros/TOFsignal.C");
+  TF1 *fTOFsignal = new TF1("fTOFsignal", TOFsignal, -2440., 2440., 4);
+  fTOFsignal->SetParameter(0, 1.);
+  fTOFsignal->SetParameter(1, 0.);
+  fTOFsignal->SetParameter(2, tofReso);
+  fTOFsignal->SetParameter(3, tofTail);
+  
+  /* open file, get tree and connect */
+  TFile *filein = TFile::Open(filename);
+  TTree *treein = (TTree *)filein->Get("aodTree");
+  printf("got \"aodTree\": %d entries\n", treein->GetEntries());
+  AliAnalysisEvent *analysisEvent = new AliAnalysisEvent();
+  TClonesArray *analysisTrackArray = new TClonesArray("AliAnalysisTrack");
+  AliAnalysisTrack *analysisTrack = NULL;
+  treein->SetBranchAddress("AnalysisEvent", &analysisEvent);
+  treein->SetBranchAddress("AnalysisTrack", &analysisTrackArray);
+
+  /* open hT0fill for mismatch */
+  TFile *filein_T0Fill = TFile::Open(t0FillOnlineFileName);
+  TH1F *hT0Fill = (TH1F *)filein_T0Fill->Get("hT0Fill");
+  Double_t t0fill = t0Fill_offset;
+
+  /* open enabled flag map */
+  TFile *enabledfile = TFile::Open(enabledChannelsFileName);
+  TH1F *hEnabledFlag = (TH1F *)enabledfile->Get("hEnabledFlag");
+
+  /**************************************************************/
+  /*** HISTOS ***************************************************/
+  /**************************************************************/
+
+  /* run-time binning */
+  for (Int_t ibin = 0; ibin < NtofsigmaBins + 1; ibin++)
+    tofsigmaBin[ibin] = tofsigmaMin + ibin * tofsigmaStep;
+  for (Int_t ibin = 0; ibin < NtofsignalBins + 1; ibin++)
+    tofsignalBin[ibin] = tofsignalMin + ibin * tofsignalStep;
+  for (Int_t ibin = 0; ibin < NtpcsigmaBins + 1; ibin++)
+    tpcsigmaBin[ibin] = tpcsigmaMin + ibin * tpcsigmaStep;
+
+  /* histos */
+  TH1F *hAcceptedEvents = new TH1F(Form("hAcceptedEvents_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)), "", NcentralityBins, centralityBin);
+  TH2I *hAcceptedTracks = new TH2I(Form("hAcceptedTracks_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)), "", NcentralityBins, centralityBin, NptBins, ptBin);
+
+  TH3I *hTOFpid = new TH3I(Form("hTOFpid_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)), "", NcentralityBins, centralityBin, NptBins, ptBin, NtofsigmaBins, tofsigmaBin);
+  TH3I *hTOFmismatch = new TH3I(Form("hTOFmismatch_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)), "", NcentralityBins, centralityBin, NptBins, ptBin, NtofsigmaBins, tofsigmaBin);
+  TH3I *hTOFexpected[AliPID::kSPECIES];
+  for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++) {
+    hTOFexpected[iiipart] = new TH3I(Form("hTOFexpected_%s_%s_%sID_%sBKG", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart), AliPID::ParticleName(iiipart)), "", NcentralityBins, centralityBin, NptBins, ptBin, NtofsigmaBins, tofsigmaBin);
+  }
+  
+  TH3I *hTOFpid_delta = new TH3I(Form("hTOFpid_delta_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)), "", NcentralityBins, centralityBin, NptBins, ptBin, NtofsignalBins, tofsignalBin);
+  TH3I *hTOFmismatch_delta = new TH3I(Form("hTOFmismatch_delta_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)), "", NcentralityBins, centralityBin, NptBins, ptBin, NtofsignalBins, tofsignalBin);
+  TH3I *hTOFexpected_delta[AliPID::kSPECIES];
+  for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++) {
+    hTOFexpected_delta[iiipart] = new TH3I(Form("hTOFexpected_delta_%s_%s_%sID_%sBKG", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart), AliPID::ParticleName(iiipart)), "", NcentralityBins, centralityBin, NptBins, ptBin, NtofsignalBins, tofsignalBin);
+  }
+  
+  /**************************************************************/
+  /**************************************************************/
+  /**************************************************************/
+
+  /* TOF PID response */
+  AliTOFPIDResponse tofResponse;
+  tofResponse.SetTimeResolution(tofReso);
+  /* TPC PID response */
+  AliTPCPIDResponse *tpcResponse = AliAnalysisTrack::GetTPCResponse();
+
+  /* start stopwatch */
+  TStopwatch timer;
+  timer.Start();
+
+  /* verbose */
+  printf("***** RUNNING for %s %s *****\n", chargeName[icharge], AliPID::ParticleName(ipart));
+  if (cutOnTPC) {
+    printf("***** CUT-ON-TPC requested %3.1f-%3.1f *****\n", tpcsignalMin, tpcsignalMax);
+  }
+
+  /* loop over events */
+  Bool_t hastofpid;
+  Int_t charge, index;
+  UShort_t dedxN;
+  Double_t cent, p, pt, mt, tofsignal, tpcsignal;
+  Double_t dedx, bethe, deltadedx, dedx_sigma, ptpc;
+  Double_t time, time_sigma, timezero, timezero_sigma, tof, tof_sigma, texp, texp_sigma, deltat, deltat_sigma, tof_rnd, tof_th, signal_smear, timezero_smear, texp_smear;
+
+  Double_t param[kNHistoParams];
+  for (Int_t iev = startEv; iev < treein->GetEntries() && iev < evMax; iev++) {
+    /* get event */
+    treein->GetEvent(iev);
+    if (iev % 100 == 0) printf("iev = %d\n", iev);
+    /* check vertex */
+    if (!analysisEvent->AcceptVertex()) continue;
+    /* check collision candidate */
+    if (!analysisEvent->IsCollisionCandidate()) continue;
+    /* check centrality quality */
+    if (analysisEvent->GetCentralityQuality() != 0.) continue;
+
+    /*** ACCEPTED EVENT ***/
+
+    /* apply time-zero TOF correction */
+    analysisEvent->ApplyTimeZeroTOFCorrection();
+
+    /* get centrality */
+    cent = analysisEvent->GetCentralityPercentile(AliAnalysisEvent::kCentEst_V0M);
+
+    /* fill histos */
+    hAcceptedEvents->Fill(cent);
+
+    /* loop over tracks */
+    for (Int_t itrk = 0; itrk < analysisTrackArray->GetEntries(); itrk++) {
+      /* get track */
+      analysisTrack = (AliAnalysisTrack *)analysisTrackArray->At(itrk);
+      if (!analysisTrack) continue;
+      /* check accepted track */
+      if (!analysisTrack->AcceptTrack()) continue;
+      /* check rapidity */
+      if (TMath::Abs(analysisTrack->GetY(AliPID::ParticleMass(ipart))) > 0.5) continue;
+      /* check charge */
+      charge = analysisTrack->GetSign() > 0. ? kPositive : kNegative;
+      if (charge != icharge) continue;
+
+      /*** ACCEPTED TRACK ***/
+
+      /* get track info */
+      p = analysisTrack->GetP();
+      pt = analysisTrack->GetPt();
+      
+      /* compute track mt */
+      mt = TMath::Sqrt(pt * pt + AliPID::ParticleMass(ipart) * AliPID::ParticleMass(ipart));
+       
+      /* get TPC info */
+      dedx = analysisTrack->GetTPCdEdx();
+      dedxN = analysisTrack->GetTPCdEdxN();
+      ptpc = analysisTrack->GetTPCmomentum();
+      
+      /* TPC signal */
+      bethe = tpcResponse->GetExpectedSignal(ptpc, iipart);
+      /* fix electron signal */
+      if (iipart == AliPID::kElectron)
+       bethe += 23.;
+      deltadedx = dedx - bethe;
+      dedx_sigma = 0.07 * bethe;
+      tpcsignal = deltadedx / dedx_sigma;
+
+      /* electronCut requested, remove electrons */
+      if (electronCut) {
+       /* TPC signal */
+       bethe = tpcResponse->GetExpectedSignal(ptpc, AliPID::kElectron);
+       /* fix electron signal */
+       bethe += 23.;
+       deltadedx = dedx - bethe;
+       dedx_sigma = 0.07 * bethe;
+       tpcsignal = deltadedx / dedx_sigma;
+       if (TMath::Abs(tpcsignal) < 1.5) continue;
+      }
+      
+      /* cut on TPC signal if requested */
+      if (cutOnTPC && (tpcsignal < tpcsignalMin || tpcsignal > tpcsignalMax))
+       continue;
+      
+      /* fill histos */
+      hAcceptedTracks->Fill(cent, pt);
+      
+      /* set TOF pid flag */
+      hastofpid = analysisTrack->HasTOFPID();
+      /* check channel enabled */
+      index = analysisTrack->GetTOFIndex();
+      //      if (hEnabledFlag->GetBinContent(index + 1) == 0.) hastofpid = kFALSE;
+      
+      /* check TOF pid */
+      if (!hastofpid)
+       continue;
+      
+      /*** ACCEPTED TRACK WITH TOF PID ***/
+      
+      /* apply expected time correction */
+      analysisTrack->ApplyTOFExpectedTimeCorrection();
+      
+      /* get TOF info */
+      time = analysisTrack->GetTOFTime();
+      time_sigma = tofReso;
+      timezero = analysisEvent->GetTimeZeroTOF(p);
+      timezero_sigma = analysisEvent->GetTimeZeroTOFSigma(p);
+      tof = time - timezero;
+      tof_sigma = TMath::Sqrt(time_sigma * time_sigma + timezero_sigma * timezero_sigma);
+      
+      /* TOF expected time */
+      texp = analysisTrack->GetTOFExpTime(iipart);
+      texp_sigma = analysisTrack->GetTOFExpTimeSigma(iipart);
+      
+      /* TOF signal */
+      deltat = tof - texp;
+      deltat_sigma = TMath::Sqrt(tof_sigma * tof_sigma + texp_sigma * texp_sigma);
+      tofsignal = deltat / deltat_sigma;
+      
+      /* fill histo */
+      hTOFpid->Fill(cent, pt, tofsignal);
+      hTOFpid_delta->Fill(cent, p, deltat);
+
+      /*** EXPECTED MISMATCH ***/
+      
+      /* loop to generated random hits */
+      for (Int_t irnd = 0; irnd < NmismatchTrials; irnd++) {
+       
+       /* generate ramdom tof values */
+       tof_rnd = GenerateRandomHit(hT0Fill, t0fill, index);
+
+       /* TOF signal */
+       deltat = tof_rnd - texp;
+       tofsignal = deltat / deltat_sigma;
+       
+       /* fill histo */
+       hTOFmismatch->Fill(cent, pt, tofsignal);
+       hTOFmismatch_delta->Fill(cent, p, deltat);
+       
+      } /* end of loop over generated random hits */
+       
+      /*** EXPECTED SIGNALS ***/
+      
+      /* loop over other particles */
+      for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++) {
+       
+       /* generate expected tof value */
+       tof_th = analysisTrack->GetTOFExpTime(iiipart);
+       texp_sigma = analysisTrack->GetTOFExpTimeSigma(iiipart);
+               
+       /* loop over many trials */
+       for (Int_t irnd = 0; irnd < NexpectedTrials; irnd++) {
+         
+         /* tof response smearing */
+         signal_smear = fTOFsignal->GetRandom();
+         /* timezero resolution smearing */
+         timezero_smear = gRandom->Gaus(0., timezero_sigma);
+         /* texp resolution smearing */
+         texp_smear = gRandom->Gaus(0., texp_sigma);
+         
+         /* deltat and sigma */
+         deltat = tof_th - texp + signal_smear + timezero_smear + texp_smear;
+         tofsignal = deltat / deltat_sigma;
+         
+         /* fill histo */
+         hTOFexpected[iiipart]->Fill(cent, pt, tofsignal);
+         hTOFexpected_delta[iiipart]->Fill(cent, p, deltat);
+           
+       } /* end of loop over many trials */
+      } /* end of loop over other particle */
+    } /* end of loop over tracks */
+  } /* end of loop over events */
+  
+  /* stop stopwatch */
+  timer.Stop();
+  timer.Print();
+  
+  /* output */
+  TString outputstring = "TOFpid";
+  if (electronCut)
+    outputstring += "_electronCut";
+  if (cutOnTPC)
+    outputstring += Form("_cutOnTPC[%3.1f,%3.1f]", , tpcsignalMin, tpcsignalMax);
+  outputstring += Form("_%s_%s_%sID.%s", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart), filename);
+  TFile *fileout = TFile::Open(outputstring.Data(), "RECREATE");
+  hAcceptedEvents->Write();
+  hAcceptedTracks->Write();
+  hTOFpid->Write();
+  hTOFmismatch->Write();
+  for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++)
+    hTOFexpected[iiipart]->Write();
+  hTOFpid_delta->Write();
+  hTOFmismatch_delta->Write();
+  for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++)
+    hTOFexpected_delta[iiipart]->Write();
+  
+  fileout->Close();
+  
+}
+
+//___________________________________________________________________________________
+
+TOFspectra_defaultFit(const Char_t *filename)
+{
+
+Bool_t EXPECTED_SIGNAL_TEMPLATE = kTRUE;
+Bool_t EXPECTED_SIGNAL_FIT = kFALSE;
+Bool_t EXPECTED_BACKGROUND_TEMPLATE = kFALSE;
+Bool_t EXPECTED_BACKGROUND_FIT = kTRUE;
+
+}
+
+//___________________________________________________________________________________
+
+TOFspectra_defaultFit_fitElectrons(const Char_t *filename, Float_t electronLimit = 5.)
+{
+
+
+  TOFspectra(filename, electronLimit);
+}
+
+//___________________________________________________________________________________
+
+TOFspectra_signalFit(Bool_t fixParams = kTRUE, Float_t scaleSigma = 1., Float_t scaleTail = 1.)
+{
+
+  EXPECTED_SIGNAL_TEMPLATE = kFALSE;
+  EXPECTED_SIGNAL_FIT = kTRUE;
+  FIX_SIGNAL_MEAN = fixParams;
+  FIX_SIGNAL_SIGMA = fixParams;
+  FIX_SIGNAL_TAIL = fixParams;
+  SCALE_SIGNAL_SIGMA = scaleSigma;
+  SCALE_SIGNAL_TAIL = scaleTail;
+  
+}
+
+//___________________________________________________________________________________
+
+TOFspectra_bkgFit(Bool_t fixParams = kTRUE, Float_t scaleSigma = 1., Float_t scaleTail = 1.)
+{
+
+  EXPECTED_BACKGROUND_TEMPLATE = kFALSE;
+  EXPECTED_BACKGROUND_FIT = kTRUE;
+  FIX_BACKGROUND_MEAN = fixParams;
+  FIX_BACKGROUND_SIGMA = fixParams;
+  FIX_BACKGROUND_TAIL = fixParams;
+  SCALE_BACKGROUND_SIGMA = scaleSigma;
+  SCALE_BACKGROUND_TAIL = scaleTail;
+  
+  TOFspectra(filename);
+
+}
+
+//___________________________________________________________________________________
+
+void
+TOFspectra(const Char_t *filename, Float_t electronLimit = 0.)
+{
+
+  for (Int_t icent = 0; icent < NcentralityBins; icent++)
+    for (Int_t icharge = 0; icharge < kNCharges; icharge++)
+      for (Int_t ipart = 2; ipart < AliPID::kSPECIES; ipart++)
+       TOFspectrum(filename, ipart, icharge, ipart, icent, -1., -1., electronLimit);
+  
+}
+
+//___________________________________________________________________________________
+
+/* fit ranges */
+Double_t fitPtMin[AliPID::kSPECIES] = {0.5, 0.5, 0.3, 0.4, 0.5};
+Double_t fitPtMax[AliPID::kSPECIES] = {3.0, 3.0, 3.0, 3.0, 5.0};
+Double_t fitSigmaMin[AliPID::kSPECIES] = {tofsigmaMin, tofsigmaMin, -25., -75., -65.};
+Double_t fitSigmaMax[AliPID::kSPECIES] = {tofsigmaMax, tofsigmaMax, 225., 200., 100.};
+
+void
+TOFspectrum(const Char_t *filename, Int_t ipart, Int_t icharge, Int_t iipart, Int_t icent, Float_t ptMin = -1., Float_t ptMax = -1., Bool_t checkHistoFlag = kFALSE)
+{
+
+  printf("****************************************\n");
+  printf("RUNNING SPECTRA FIT:\n");
+  printf("RAPIDITY-CUT:   %s\n", AliPID::ParticleName(ipart));
+  printf("CHARGE:         %s\n", chargeName[icharge]);
+  printf("PARTICLE:       %s\n", AliPID::ParticleName(iipart));
+  printf("CENTRALITY BIN: %d\n", icent);
+  printf("****************************************\n");
+
+  /* open data */
+  TFile *filein = TFile::Open(filename);
+
+  /* get number of events */
+  TH1F *hAcceptedEvents = (TH1F *)filein->Get(Form("hAcceptedEvents_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+  if (!hAcceptedEvents) {
+    printf("cannot find %s\n", Form("hAcceptedEvents_%s_%s", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+    return;
+  }
+  Double_t nevents;
+  if (icent < 0 || icent >= NcentralityBins)
+    nevents = hAcceptedEvents->Integral(1, NcentralityBins);
+  else
+    nevents = hAcceptedEvents->Integral(icent + 1, icent + 1);
+  printf("N_EVENTS      : %d\n", nevents);
+  printf("****************************************\n");
+  
+  /* get histos */
+  TH2I *hAcceptedTracks = (TH2I *)filein->Get(Form("hAcceptedTracks_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+  if (!hAcceptedTracks) {
+    printf("cannot find %s\n", Form("hAcceptedTracks_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+    //    return;
+  }
+  TH3I *hTOFpid = (TH3I *)filein->Get(Form("hTOFpid_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+  if (!hTOFpid) {
+    printf("cannot find %s\n", Form("hTOFpid_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+    return;
+  }
+  TH3I *hTOFmismatch = (TH3I *)filein->Get(Form("hTOFmismatch_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+  if (!hTOFmismatch) {
+    printf("cannot find %s\n", Form("hTOFpid_%s_%s_%sID", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart)));
+    return;
+  }
+  TH3I *hTOFexpected[AliPID::kSPECIES];
+  for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++) {
+    hTOFexpected[iiipart] = (TH3I *)filein->Get(Form("hTOFexpected_%s_%s_%sID_%sBKG", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart), AliPID::ParticleName(iiipart)));
+    if (!hTOFexpected[iiipart]) {
+      printf("cannot find %s\n", Form("hTOFexpected_%s_%s_%sID_%sBKG", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart), AliPID::ParticleName(iiipart)));
+      return;
+    }
+  }
+
+  /* setup centrality range */
+  if (icent < 0 || icent >= NcentralityBins) {
+    printf("WARNING: undefined centrality -> using 00-90\% range\n");
+    if (hAcceptedTracks) hAcceptedTracks->GetXaxis()->SetRange(1, NcentralityBins);
+    hTOFpid->GetXaxis()->SetRange(1, NcentralityBins);
+    hTOFmismatch->GetXaxis()->SetRange(1, NcentralityBins);
+    for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++)
+      hTOFexpected[iiipart]->GetXaxis()->SetRange(1, NcentralityBins);
+  }
+  else {
+    printf("***** FITTING CENTRALITY-BIN [%02d, %02d] %% *****\n", centralityBin[icent], centralityBin[icent + 1]);
+    if (hAcceptedTracks) hAcceptedTracks->GetXaxis()->SetRange(icent + 1, icent + 1);
+    hTOFpid->GetXaxis()->SetRange(icent + 1, icent + 1);
+    hTOFmismatch->GetXaxis()->SetRange(icent + 1, icent + 1);
+    for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++)
+      hTOFexpected[iiipart]->GetXaxis()->SetRange(icent + 1, icent + 1);
+  }
+
+  /* init flags */
+  Bool_t requestedRange = kFALSE;
+  Bool_t fitElectrons = kTRUE;
+  Bool_t fitMuons = kTRUE;
+  Bool_t fitPions = kTRUE;
+
+  /* setup pt range if requested */
+  if (ptMin > -0.001 && ptMax > -0.001 && ptMax > ptMin) {
+    printf("***** FITTING PT-BIN [%f, %f] GeV/c *****\n", ptMin, ptMax);
+    requestedRange = kTRUE;
+
+    /* check electron-fit is allowed */
+    fitElectrons = kTRUE;
+    if ((ptMin + 0.001) < FIT_ELECTRONS_PT_MIN || (ptMax - 0.001) > FIT_ELECTRONS_PT_MAX)
+      fitElectrons = kFALSE;
+    /* check muon-fit is allowed */
+    fitMuons = kTRUE;
+    if ((ptMin + 0.001) < FIT_MUONS_PT_MIN || (ptMax - 0.001) > FIT_MUONS_PT_MAX)
+      fitMuons = kFALSE;
+    /* check pion-fit is allowed */
+    fitPions = kTRUE;
+    if ((ptMin + 0.001) < FIT_PIONS_PT_MIN || (ptMax - 0.001) > FIT_PIONS_PT_MAX)
+      fitPions = kFALSE;
+
+    
+    hTOFpid->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    hTOFmismatch->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+    for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++)
+      hTOFexpected[iiipart]->GetYaxis()->SetRangeUser(ptMin + 0.001, ptMax - 0.001);
+  }
+
+  /* output */
+  Char_t outfilename[1024];
+  if (icent < 0 || icent >= NcentralityBins)
+    sprintf(outfilename, "TOFspectrum_cent0090_%s_%s_%sID.root", AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart));
+  else {
+    sprintf(outfilename, "TOFspectrum_cent%02d%02d_%s_%s_%sID.root", centralityBin[icent], centralityBin[icent + 1], AliPID::ParticleName(ipart), chargeName[icharge], AliPID::ParticleName(iipart));
+  }
+  TFile *fileout = TFile::Open(outfilename, "RECREATE");
+  TDirectory *fitDir = fileout->mkdir("FitParams");
+  /* canvas */
+  TCanvas *canvas = new TCanvas("canvas");
+  canvas->SetLogy();
+  /* histo */
+  TH1D *hFitParamHisto[kNFitParams];
+  for (Int_t iparam = 0; iparam < kNFitParams; iparam++)
+    hFitParamHisto[iparam] = new TH1D(Form("h%s", fitParamName[iparam]), fitParamTitle[iparam], NptBins, ptBin);
+
+  /* loop over ptBins */
+  for (Int_t ipt = 0; ipt < NptBins; ipt++) {
+    
+    if (!requestedRange) {
+      if ((ptBin[ipt] + 0.001) < fitPtMin[ipart] || (ptBin[ipt + 1] - 0.001) > fitPtMax[ipart]) continue;
+      printf("***** FITTING PT-BIN [%f, %f] GeV/c *****\n", ptBin[ipt], ptBin[ipt + 1]);
+
+      /* check electron-fit is allowed */
+      fitElectrons = kTRUE;
+      if ((ptBin[ipt] + 0.001) < FIT_ELECTRONS_PT_MIN || (ptBin[ipt + 1] - 0.001) > FIT_ELECTRONS_PT_MAX)
+       fitElectrons = kFALSE;
+      /* check muon-fit is allowed */
+      fitMuons = kTRUE;
+      if ((ptBin[ipt] + 0.001) < FIT_MUONS_PT_MIN || (ptBin[ipt + 1] - 0.001) > FIT_MUONS_PT_MAX)
+       fitMuons = kFALSE;
+      /* check pion-fit is allowed */
+      fitPions = kTRUE;
+      if ((ptBin[ipt] + 0.001) < FIT_PIONS_PT_MIN || (ptBin[ipt + 1] - 0.001) > FIT_PIONS_PT_MAX)
+       fitPions = kFALSE;
+
+      hTOFpid->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      hTOFmismatch->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+      for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++)
+       hTOFexpected[iiipart]->GetYaxis()->SetRange(ipt + 1, ipt + 1);
+    }
+    
+    /* nsigma projections */
+    TH1 *hSignal_py = hTOFpid->Project3D("z");
+    TH1 *hMismatch_py = hTOFmismatch->Project3D("z");
+    TH1 *hSignalExp_py[AliPID::kSPECIES];
+    TH1 *hSignalExpTail_py[AliPID::kSPECIES];
+    for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++) {
+      hSignalExp_py[iiipart] = hTOFexpected[iiipart]->Project3D("z");
+      hSignalExpTail_py[iiipart] = hTOFexpected[iiipart]->Project3D("z");
+    }
+
+    /* prepare histos for the fitter */
+    Int_t partbkg1[AliPID::kSPECIES] = {AliPID::kKaon, AliPID::kKaon, AliPID::kKaon, AliPID::kPion, AliPID::kPion};
+    Int_t partbkg2[AliPID::kSPECIES] = {AliPID::kProton, AliPID::kProton, AliPID::kProton, AliPID::kProton, AliPID::kKaon};
+    Int_t partbkg3[AliPID::kSPECIES] = {AliPID::kPion, AliPID::kPion, AliPID::kElectron, AliPID::kElectron, AliPID::kElectron};
+    Int_t partbkg4[AliPID::kSPECIES] = {AliPID::kMuon, AliPID::kElectron, AliPID::kMuon, AliPID::kMuon, AliPID::kMuon};
+    TH1 *hSigExp_py, *hBkgExp1_py, *hBkgExp2_py, *hBkgExp3_py, *hBkgExp4_py;
+    hSigExp_py = EXPECTED_SIGNAL_TAIL ? hSignalExpTail_py[iipart] : hSignalExp_py[iipart];
+    hBkgExp1_py = EXPECTED_BACKGROUND_TAIL ? hSignalExpTail_py[partbkg1[iipart]] : hSignalExp_py[partbkg1[iipart]];
+    hBkgExp2_py = EXPECTED_BACKGROUND_TAIL ? hSignalExpTail_py[partbkg2[iipart]] : hSignalExp_py[partbkg2[iipart]];
+    hBkgExp3_py = EXPECTED_BACKGROUND_TAIL ? hSignalExpTail_py[partbkg3[iipart]] : hSignalExp_py[partbkg3[iipart]];
+    hBkgExp4_py = EXPECTED_BACKGROUND_TAIL ? hSignalExpTail_py[partbkg4[iipart]] : hSignalExp_py[partbkg4[iipart]];
+
+    /* check histos if requested */
+    if (checkHistoFlag) {
+      TCanvas *cCheckHisto = new TCanvas("cCheckHisto");
+      cCheckHisto->Divide(2, 3);
+      cCheckHisto->cd(1);
+      hSignal_py->Draw();
+      cCheckHisto->cd(2);
+      hSigExp_py->Draw();
+      cCheckHisto->cd(3);
+      hBkgExp1_py->Draw();
+      cCheckHisto->cd(4);
+      hBkgExp2_py->Draw();
+      cCheckHisto->cd(5);
+      hBkgExp3_py->Draw();
+      cCheckHisto->cd(6);
+      hMismatch_py->Draw();
+      return;
+    }
+
+    Double_t rangeMin = fitSigmaMin[iipart], rangeMax = fitSigmaMax[iipart];
+    Bool_t constrainSignal = kFALSE;
+    Bool_t constrainBkg1 = kFALSE;
+    Bool_t constrainBkg2 = kFALSE;
+    Bool_t forceGaussianSignal = kFALSE;
+    Bool_t fitBkg1 = kTRUE, fitBkg2 = kTRUE, fitBkg3 = kTRUE, fitBkg4 = kTRUE;
+
+    /* check whether we can fit electrons */
+    if (!fitElectrons) {
+      printf("INHIBIT FIT ELECTRONS\n");
+      if (partbkg1[iipart] == AliPID::kElectron) fitBkg1 = kFALSE;
+      if (partbkg2[iipart] == AliPID::kElectron) fitBkg2 = kFALSE;
+      if (partbkg3[iipart] == AliPID::kElectron) fitBkg3 = kFALSE;
+      if (partbkg4[iipart] == AliPID::kElectron) fitBkg4 = kFALSE;
+    }
+    /* check whether we can fit muons */
+    if (!fitMuons) {
+      printf("INHIBIT FIT MUONS\n");
+      if (partbkg1[iipart] == AliPID::kMuon) fitBkg1 = kFALSE;
+      if (partbkg2[iipart] == AliPID::kMuon) fitBkg2 = kFALSE;
+      if (partbkg3[iipart] == AliPID::kMuon) fitBkg3 = kFALSE;
+      if (partbkg4[iipart] == AliPID::kMuon) fitBkg4 = kFALSE;
+    }
+    /* check whether we can fit pions */
+    if (!fitPions) {
+      printf("INHIBIT FIT PIONS\n");
+      if (partbkg1[iipart] == AliPID::kPion) fitBkg1 = kFALSE;
+      if (partbkg2[iipart] == AliPID::kPion) fitBkg2 = kFALSE;
+      if (partbkg3[iipart] == AliPID::kPion) fitBkg3 = kFALSE;
+      if (partbkg4[iipart] == AliPID::kPion) fitBkg4 = kFALSE;
+    }
+
+
+    /* fit */
+    Double_t param[kNFitParams];
+    Double_t param_err[kNFitParams];
+    TOFpid_fit(hSignal_py, hSigExp_py, hBkgExp1_py, hBkgExp2_py, hBkgExp3_py, hBkgExp4_py, hMismatch_py, rangeMin, rangeMax, fitBkg1, fitBkg2, fitBkg3, fitBkg4, constrainSignal, constrainBkg1, constrainBkg2, forceGaussianSignal, param, param_err, canvas);
+
+    /* check requested pt-range */
+    if (requestedRange)
+      return;
+
+    /* write canvas */
+    fitDir->cd();
+    canvas->Write(Form("fitDisplay_ptBin_%3.2f_%3.2f", ptBin[ipt], ptBin[ipt + 1]));
+
+    /* set histo */
+    for (Int_t iparam = 0; iparam < kNFitParams; iparam++) {
+      hFitParamHisto[iparam]->SetBinContent(ipt + 1, param[iparam]);
+      hFitParamHisto[iparam]->SetBinError(ipt + 1, param_err[iparam]);
+    }
+
+    /* delete */
+    delete hSignal_py;
+    delete hMismatch_py;
+    for (Int_t iiipart = 0; iiipart < AliPID::kSPECIES; iiipart++) {
+      delete hSignalExp_py[iiipart];
+      //      delete hSignalExpTail_py[iiipart];
+    }
+  }
+
+  /* check requested pt-range */
+  if (requestedRange)
+    return;
+
+  /*** POST-ANALYSIS ***/
+
+  TDirectory *postDir = fileout->mkdir("PostAnalysis");
+  /* compute overflows */
+  TH1D *hOverflowCounts = new TH1D(*hFitParamHisto[kTotalCounts]);
+  hOverflowCounts->SetNameTitle("hOverflowCounts", "Overflow counts: TotalCounts - IntegralCounts;p_{T} (GeV/c);counts");
+  hOverflowCounts->Add(hFitParamHisto[kIntegralCounts], -1.);
+  /* compute total mismatch counts */
+  TH1D *hTotalMismatchCounts = new TH1D(*hFitParamHisto[kMismatchCounts]);
+  hTotalMismatchCounts->SetNameTitle("hTotalMismatchCounts", "Total mismatch counts: MismatchCounts + OverflowCounts;p_{T} (GeV/c);counts");
+  hTotalMismatchCounts->Add(hOverflowCounts);
+  /* computed mismatch fraction */
+  TH1D *hTotalMismatchFraction = new TH1D(*hTotalMismatchCounts);
+  hTotalMismatchFraction->SetNameTitle("hTotalMismatchFraction", "Total mismatch fraction: TotalMismatchCounts / TotalCounts;p_{T} (GeV/c);");
+  hTotalMismatchFraction->Divide(hFitParamHisto[kTotalCounts]);
+  /* compute identified counts */
+  TH1D *hIdentifiedCounts = new TH1D(*hFitParamHisto[kSignalCounts]);
+  hIdentifiedCounts->SetNameTitle("hIdentifiedCounts", "Identified counts: SignalCounts + sum(BkgCounts);p_{T} (GeV/c);counts");
+  hIdentifiedCounts->Add(hFitParamHisto[kBkg1Counts]);
+  hIdentifiedCounts->Add(hFitParamHisto[kBkg2Counts]);
+  hIdentifiedCounts->Add(hFitParamHisto[kBkg3Counts]);
+  /* compute signal fraction */
+  TH1D *hSignalFraction = new TH1D(*hFitParamHisto[kSignalCounts]);
+  hSignalFraction->SetNameTitle("hSignalFraction", "Signal fraction: SignalCounts / IdentifiedCounts;p_{T} (GeV/c);");
+  hSignalFraction->Divide(hSignalFraction, hIdentifiedCounts, 1., 1., "B");
+  /* compute bkg1 fraction */
+  TH1D *hBkg1Fraction = new TH1D(*hFitParamHisto[kBkg1Counts]);
+  hBkg1Fraction->SetNameTitle("hBkg1Fraction", "Bkg1 fraction: Bkg1Counts / IdentifiedCounts;p_{T} (GeV/c);");
+  hBkg1Fraction->Divide(hBkg1Fraction, hIdentifiedCounts, 1., 1., "B");
+  /* compute bkg2 fraction */
+  TH1D *hBkg2Fraction = new TH1D(*hFitParamHisto[kBkg2Counts]);
+  hBkg2Fraction->SetNameTitle("hBkg2Fraction", "Bkg2 fraction: Bkg2Counts / IdentifiedCounts;p_{T} (GeV/c);");
+  hBkg2Fraction->Divide(hBkg2Fraction, hIdentifiedCounts, 1., 1., "B");
+  /* compute bkg3 fraction */
+  TH1D *hBkg3Fraction = new TH1D(*hFitParamHisto[kBkg3Counts]);
+  hBkg3Fraction->SetNameTitle("hBkg3Fraction", "Bkg3 fraction: Bkg3Counts / IdentifiedCounts;p_{T} (GeV/c);");
+  hBkg3Fraction->Divide(hBkg3Fraction, hIdentifiedCounts, 1., 1., "B");
+  /* compute bkg4 fraction */
+  TH1D *hBkg4Fraction = new TH1D(*hFitParamHisto[kBkg4Counts]);
+  hBkg4Fraction->SetNameTitle("hBkg4Fraction", "Bkg4 fraction: Bkg4Counts / IdentifiedCounts;p_{T} (GeV/c);");
+  hBkg4Fraction->Divide(hBkg4Fraction, hIdentifiedCounts, 1., 1., "B");
+  /* compute mismatch-correction counts */
+  TH1D *hMismatchCorrectionCounts = new TH1D(*hTotalMismatchCounts);
+  hMismatchCorrectionCounts->SetNameTitle("hMismatchCorrectionCounts", "Mismatch-correction counts: TotalMismatchCounts * SignalFraction;p_{T} (GeV/c);counts");
+  hMismatchCorrectionCounts->Multiply(hSignalFraction);
+  /* compute mismatch-corrected signal counts */
+  TH1D *hMismatchCorrectedSignalCounts = new TH1D(*hFitParamHisto[kSignalCounts]);
+  hMismatchCorrectedSignalCounts->SetNameTitle("hMismatchCorrectedSignalCounts", "Mismatch-corrected signal counts: SignalCounts + MismatchCorrectionCounts;p_{T} (GeV/c);counts");
+  hMismatchCorrectedSignalCounts->Add(hMismatchCorrectionCounts);
+
+  /* accepted tracks histo */
+  if (hAcceptedTracks) {
+    TH1D *hAcceptedTracks_py = hAcceptedTracks->ProjectionY();
+    hAcceptedTracks_py->SetNameTitle("hAcceptedTracks", "Accepted tracks;p_{T} (GeV/c);");
+    hAcceptedTracks_py->Sumw2();
+  }
+
+  /*** RAW SPECTRA ***/
+
+  TDirectory *rawDir = fileout->mkdir("RawSpectra");
+
+  /* compute normalized raw yield */
+  TH1D *hNormalizedRawYield = new TH1D(*hFitParamHisto[kSignalCounts]);
+  hNormalizedRawYield->SetNameTitle("hNormalizedRawYield", "Raw yield;p_{T} (GeV/c);#frac{1}{N_{ev}} #frac{d^{2}N}{dy dp_{T}}");
+  TOFpid_normalize(hNormalizedRawYield, nevents);
+  /* compute normalized mismatch-corrected raw yield */
+  TH1D *hNormalizedMismatchCorrectedRawYield = new TH1D(*hMismatchCorrectedSignalCounts);
+  hNormalizedMismatchCorrectedRawYield->SetNameTitle("hNormalizedMismatchCorrectedRawYield", "Mismatch-corrected raw yield;p_{T} (GeV/c);#frac{1}{N_{ev}} #frac{d^{2}N}{dy dp_{T}}");
+  TOFpid_normalize(hNormalizedMismatchCorrectedRawYield, nevents);
+
+  /*** OUTPUT ***/
+
+  /* write fir params histos */
+  fitDir->cd();
+  for (Int_t iparam = 0; iparam < kNFitParams; iparam++)
+    hFitParamHisto[iparam]->Write();
+  /* write post-analysis histos */
+  postDir->cd();
+  hOverflowCounts->Write();
+  hTotalMismatchCounts->Write();
+  hTotalMismatchFraction->Write();
+  hIdentifiedCounts->Write();
+  hSignalFraction->Write();
+  hBkg1Fraction->Write();
+  hBkg2Fraction->Write();
+  hBkg3Fraction->Write();
+  hBkg4Fraction->Write();
+  hMismatchCorrectionCounts->Write();
+  hMismatchCorrectedSignalCounts->Write();
+  if (hAcceptedTracks) hAcceptedTracks_py->Write();
+  /* write raw spectra histos */
+  rawDir->cd();
+  hNormalizedRawYield->Write();
+  hNormalizedMismatchCorrectedRawYield->Write();
+
+  /* clean up */
+  delete canvas;
+  for (Int_t iparam = 0; iparam < kNFitParams; iparam++)
+    delete hFitParamHisto[iparam];
+  delete hOverflowCounts;
+  delete hTotalMismatchCounts;
+  delete hTotalMismatchFraction;
+  delete hIdentifiedCounts;
+  delete hSignalFraction;
+  delete hBkg1Fraction;
+  delete hBkg2Fraction;
+  delete hBkg3Fraction;
+  delete hBkg4Fraction;
+  delete hMismatchCorrectionCounts;
+  delete hMismatchCorrectedSignalCounts;
+  if (hAcceptedTracks) {
+    delete hAcceptedTracks_py;
+  }
+  delete hNormalizedRawYield;
+  delete hNormalizedMismatchCorrectedRawYield;
+
+  /* close file */
+  fileout->Close();
+}
+
+//___________________________________________________________________________________
+
+Float_t 
+TOFpid_histomin(TH1 *h)
+{
+
+  for (Int_t ibin = 0; ibin < h->GetNbinsX(); ibin++)
+    if (h->GetBinContent(ibin + 1) > 0.)
+      return h->GetXaxis()->GetBinCenter(ibin + 1);
+  return kMaxInt;
+}
+
+//___________________________________________________________________________________
+
+Float_t 
+TOFpid_histomax(TH1 *h)
+{
+
+  for (Int_t ibin = h->GetNbinsX(); ibin > 0; ibin--)
+    if (h->GetBinContent(ibin) > 0.)
+      return h->GetXaxis()->GetBinCenter(ibin);
+  return -kMaxInt;
+}
+
+//___________________________________________________________________________________
+
+TOFpid_checkneg(TH1 *h)
+{
+
+  for (Int_t ibin = 0; ibin < h->GetNbinsX(); ibin++)
+    if (h->GetBinContent(ibin + 1) <= 0.) {
+      h->SetBinContent(ibin + 1, 1.e-300);
+      //      h->SetBinError(ibin + 1, 0.1);
+    }
+}
+
+//___________________________________________________________________________________
+
+Double_t
+TOFpid_fit(TH1 *hSignal, TH1 *hSigExp, TH1 *hBkgExp1, TH1 *hBkgExp2, TH1 *hBkgExp3, TH1 *hBkgExp4, TH1 *hMismatch, Double_t rangeMin, Double_t rangeMax, Bool_t fitBkg1, Bool_t fitBkg2, Bool_t fitBkg3, Bool_t fitBkg4, Bool_t constrainSignal, Bool_t constrainBkg1, Bool_t constrainBkg2, Bool_t forceGaussianSignal, Double_t *param = NULL, Double_t *param_err = NULL, TCanvas *canvas = NULL)
+{
+
+  /** ROOFIT ***/
+  gSystem->Load("libRooFit");
+  using namespace RooFit;
+ /*** LOAD GAUSSIANTAIL CLASS ***/
+  gSystem->Load("~/ALICE.2011/ANALYSIS/TOFSpectraPbPb/macros/RooFermiCutoff_cxx.so");
+  gSystem->Load("~/ALICE.2011/ANALYSIS/TOFSpectraPbPb/macros/RooGaussianTail_cxx.so");
+
+  /*** DEFINE FIT RANGE ***/
+
+  printf("***** FIT RANGE DEFINITION *****\n");
+
+  /* check mismatch histogram to define min/max fit range */
+  //  rangeMin = TMath::Max(rangeMin, TOFpid_histomin(hMismatch));
+  //  rangeMax = TMath::Min(rangeMax, TOFpid_histomax(hMismatch));
+  /* fix zeroes */
+  TOFpid_checkneg(hMismatch);
+  
+  /* define range */
+  RooRealVar x("x", "n_{#sigma}", 0., rangeMin, rangeMax, "");
+  printf("FIT RANGE DEFINED: %f -> %f\n", rangeMin, rangeMax);
+  printf("********************************\n");
+
+  /*** DEFINE HISTOGRAM DATA ***/
+  
+  /* define data to fit and background from input histogram */
+  RooDataHist hdata("hdata", "hdata", x, hSignal);
+  RooDataHist hsig("hsig", "hsig", x, hSigExp);
+  RooDataHist hbkg1("hbkg1", "hbkg1", x, hBkgExp1);
+  RooDataHist hbkg2("hbkg2", "hbkg2", x, hBkgExp2);
+  RooDataHist hbkg3("hbkg3", "hbkg3", x, hBkgExp3);
+  RooDataHist hbkg4("hbkg4", "hbkg4", x, hBkgExp4);
+  RooDataHist hmismatch("hmismatch", "hmismatch", x, hMismatch);
+
+  /*** DEFINE SIGNAL SHAPE ***/
+
+  printf("***** SIGNAL SHAPE DEFINITION *****\n");
+
+  /* variables */
+  //  if (FIX_SIGNAL_MEAN) {
+  //    RooRealVar mean("mean", "mean", DEFAULT_SIGNAL_MEAN, "");
+  //    printf("FIXED SIGNAL_MEAN = %f\n", mean.getVal());
+  //  }
+  //  else {
+  RooRealVar mean("mean", "mean", DEFAULT_SIGNAL_MEAN, MIN_SIGNAL_MEAN, MAX_SIGNAL_MEAN, "");
+  //    printf("FREE SIGNAL_MEAN = %f [%f, %f]\n", mean.getVal(), MIN_SIGNAL_MEAN, MAX_SIGNAL_MEAN);
+  //  }
+  //  if (FIX_SIGNAL_SIGMA) {
+  //    RooRealVar sigma("sigma", "sigma", DEFAULT_SIGNAL_SIGMA, "");
+  //    printf("FIXED SIGNAL_SIGMA = %f\n", sigma.getVal());
+  //  }
+  //  else {
+    RooRealVar sigma("sigma", "sigma", DEFAULT_SIGNAL_SIGMA, MIN_SIGNAL_SIGMA, MAX_SIGNAL_SIGMA), "");
+//    printf("FREE SIGNAL_SIGMA = %f\n", sigma.getVal());
+//  }
+//  if (FIX_SIGNAL_TAIL) {
+//    RooRealVar tail("tail", "tail", DEFAULT_SIGNAL_TAIL, "");
+//    printf("FIXED SIGNAL_TAIL = %f\n", tail.getVal());
+//  }
+//  else {
+    RooRealVar tail("tail", "tail", DEFAULT_SIGNAL_TAIL, MIN_SIGNAL_TAIL, MAX_SIGNAL_TAIL, "");
+//    printf("FREE SIGNAL_TAIL = %f\n", tail.getVal());
+//  }
+  RooRealVar gaussianfrac("gaussianfrac", "gaussianfrac", 1., 0., 1., "");
+  RooRealVar sigalpha("sigalpha", "sigalpha", 0., -10., 0.);
+
+  /* shapes */
+  if (GAUSSIAN_SIGNAL || forceGaussianSignal) {
+    printf("USING GAUSSIAN_SIGNAL SHAPE\n");
+    RooGaussian signal("signal", "signal", x, mean, sigma);
+  }
+  else if (GAUSSIANTAIL_SIGNAL) {
+    printf("USING GAUSSIANTAIL_SIGNAL SHAPE\n");
+    RooGaussianTail signal("signal", "signal", x, mean, sigma, tail);
+  }
+  else if (GAUSSIANTAIL2_SIGNAL) {
+    printf("USING GAUSSIANTAIL2_SIGNAL SHAPE\n");
+    RooGaussianTail signal("signal", "signal", x, mean, sigma, sigma);
+  }
+  else if (GAUSSIANPLUSGAUSSIANTAIL_SIGNAL) {
+    printf("USING GAUSSIANPLUSGAUSSIANTAIL_SIGNAL SHAPE\n");
+    RooGaussian gaussian("gaussian", "gaussian", x, mean, sigma);
+    RooGaussianTail gaussiantail("gaussiantail", "gaussiantail", x, mean, sigma, tail);
+    RooAddPdf signal("signal", "signal", RooArgList(gaussian, gaussiantail), gaussianfrac, kTRUE);
+
+  }
+  else if (GAUSSIANPLUSEXPONENTIAL_SIGNAL) {
+    printf("USING GAUSSIANPLUSEXPONENTIAL_SIGNAL SHAPE\n");
+    RooGaussian gaussian("gaussian", "gaussian", x, mean, sigma);
+    RooExponential sigexpo("sigexpo", "sigexpo", x, sigalpha);
+    RooRealVar sigcutoff("sigcutoff", "sigcutoff", 0.);
+    RooRealVar sigpower("sigpower", "sigpower", 0.1);
+    RooFermiCutoff sigfermi("sigfermi", "sigfermi", x, sigcutoff, sigpower);
+    RooProdPdf exposignal("exposignal", "exposignal", sigfermi, sigexpo, -100.);
+    RooRealVar gaussianfrac("gaussianfrac", "gaussianfrac", 0.9, 0.7, 1., "");
+    RooAddPdf signal("signal", "signal", RooArgList(gaussian, exposignal), gaussianfrac, kTRUE);
+  }
+  else if (EXPECTED_SIGNAL_TEMPLATE) {
+    printf("SHAPE OF SIGNAL FROM TEMPLATE HISTOGRAM\n");
+    RooHistPdf signal("signal", "signal", x, hsig);
+  }
+  else if (EXPECTED_SIGNAL_FIT) {
+    /* fitting bkg1 */
+    TF1 *fGaus = (TF1 *)gROOT->GetFunction("gaus");
+    hSigExp->Fit(fGaus, "0q");
+    Double_t sig_mean = fGaus->GetParameter(1);
+    Double_t sig_sigma = fGaus->GetParameter(2);
+    mean.setVal(sig_mean);
+    mean.setRange(sig_mean - 10., sig_mean + 10.);
+    sigma.setVal(sig_sigma);
+    sigma.setRange(sig_sigma * 0.5, sig_sigma * 1.5);
+    tail.setVal(1.);
+    tail.setRange(0.5, 5.);
+    RooGaussianTail signal("signal", "signal", x, mean, sigma, tail);
+    signal.fitTo(hsig, Range(sig_mean - 5. * sig_sigma, sig_mean + 10. * sig_sigma), SumW2Error(kFALSE), Verbose(kFALSE), PrintEvalErrors(10));
+#if DISPLAY
+    TCanvas *cSig_fit = new TCanvas("cSig_fit");
+    RooPlot *sig_frame = x.frame();
+    hsig.plotOn(sig_frame);
+    signal.plotOn(sig_frame, LineColor(kRed));
+    sig_frame->Draw();
+    cSig_fit->Update();
+#endif
+    printf("SIGNAL PARAMETERS AFTER FIT OF EXPECTED SIGNAL\n");
+    printf("mean  = %f +- %f\n", mean.getVal(), mean.getError());
+    printf("sigma = %f +- %f\n", sigma.getVal(), sigma.getError());
+    printf("tail  = %f +- %f\n", tail.getVal(), tail.getError());
+    /* scale parameters if requested */
+    if (SCALE_SIGNAL_SIGMA != 1.) {
+      printf("SCALE FITTED SIGNAL SIGMA BY %f\n", SCALE_SIGNAL_SIGMA);
+      sigma.setVal(sigma.getVal() * SCALE_SIGNAL_SIGMA);
+    }
+    if (SCALE_SIGNAL_TAIL != 1.) {
+      printf("SCALE FITTED SIGNAL TAIL BY %f\n", SCALE_SIGNAL_TAIL);
+      tail.setVal(tail.getVal() * SCALE_SIGNAL_TAIL);
+    }
+    /* fix/release parameters if requested */
+    if (FIX_SIGNAL_MEAN) {
+      printf("SETTING FITTED SIGNAL MEAN AS CONSTANTS\n");
+      mean.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING FITTED SIGNAL MEAN AS FREE\n");
+      //      mean.setRange(mean.getVal() - 0.25 * TMath::Abs(mean.getVal()), mean.getVal() + 0.25 * TMath::Abs(mean.getVal()));
+      //      mean.setRange(mean.getVal() - 0.5 * TMath::Abs(mean.getVal()), mean.getVal() + 0.5 * TMath::Abs(mean.getVal()));
+      mean.setRange(-0.1, 0.1);
+    }
+    if (FIX_SIGNAL_SIGMA) {
+      printf("SETTING FITTED SIGNAL SIGMA AS CONSTANTS\n");
+      sigma.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING FITTED SIGNAL SIGMA AS FREE\n");
+      sigma.setRange(sigma.getVal() * 0.75, sigma.getVal() * 1.25);
+      //      sigma.setRange(sigma.getVal() - 0.5, sigma.getVal() + 0.5);
+    }
+    if (FIX_SIGNAL_TAIL) {
+      printf("SETTING FITTED SIGNAL TAIL AS CONSTANTS\n");
+      tail.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING FITTED SIGNAL TAIL AS FREE\n");
+      tail.setRange(0.75, 2.0);
+      //      tail.setRange(tail.getVal() * 0.75, tail.getVal() * 1.25);
+      //      tail.setRange(tail.getVal() - 0.5, tail.getVal() + 0.5);
+    }
+  }
+  else {
+    printf("SHAPE OF SIGNAL NOT DEFINE: using GAUSSIAN_SIGNAL\n");
+    RooGaussian signal("signal", "signal", x, mean, sigma);
+  }
+
+
+#if 0
+  if (constrainSignal) {
+#if 0
+  /* fix expected signal and constrain parameters if requested */
+  signal.fitTo(hsig);
+#if 0
+  TCanvas *cConstrainSignal = new TCanvas("cConstrainSignal");
+  RooPlot *xfr = x.frame();
+  hsig.plotOn(xfr);
+  signal.plotOn(xfr, LineColor(kRed));
+  xfr->Draw();
+  cConstrainSignal->Update();
+#endif
+  printf("SIGNAL PARAMETERS AFTER FIT OF EXPECTED SIGNAL\n");
+  printf("mean  = %f +- %f\n", mean.getVal(), mean.getError());
+  printf("sigma = %f +- %f\n", sigma.getVal(), sigma.getError());
+  printf("tail  = %f +- %f\n", tail.getVal(), tail.getError());
+  if (constrainSignal) {
+    mean.setConstant(kTRUE);
+    sigma.setConstant(kTRUE);
+    tail.setConstant(kTRUE);
+  printf("SIGNAL PARAMETERS CONSTRAINED AFTER FIT OF EXPECTED SIGNAL\n");
+  }
+#endif
+  }
+#endif
+
+  if (constrainSignal) {
+    mean.setConstant(kTRUE);
+    sigma.setConstant(kTRUE);
+    tail.setConstant(kTRUE);
+    //    mean.setRange(-0.1, 0.1);
+    //    sigma.setRange(0.95, 1.05);
+    //    tail.setRange(0.95, 1.25);
+  }
+
+  printf("***********************************\n");
+
+  /*** DEFINE IDENTIFIED BACKGROUND SHAPES ***/
+
+  printf("***** IDENTIFIED BACKGROUND SHAPE DEFINITION *****\n");
+
+  /* shapes */
+if (EXPECTED_BACKGROUND_TEMPLATE) {
+  printf("USING EXPECTED BACKGROUND TEMPLATE SHAPES FROM HISTOGRAMS\n");
+    RooHistPdf bkg1("bkg1", "bkg1", x, hbkg1, 0);
+    RooHistPdf bkg2("bkg2", "bkg2", x, hbkg2, 0);
+      RooHistPdf bkg3("bkg3", "bkg3", x, hbkg3, 0);
+      RooHistPdf bkg4("bkg4", "bkg4", x, hbkg4, 0);
+  }
+ else if (EXPECTED_BACKGROUND_FIT) {
+    printf("USING EXPECTED BACKGROUND FITTED SHAPES FROM HISTOGRAMS\n");
+    /* fitting bkg1 */
+    TF1 *fGaus = (TF1 *)gROOT->GetFunction("gaus");
+    hBkgExp1->Fit(fGaus, "0q");
+    Double_t bkgexp1_mean = fGaus->GetParameter(1);
+    Double_t bkgexp1_sigma = fGaus->GetParameter(2);
+    RooRealVar mean_bkg1("mean_bkg1", "mean_bkg1", bkgexp1_mean, bkgexp1_mean - 10., bkgexp1_mean + 10., "");
+    RooRealVar sigma_bkg1("sigma_bkg1", "sigma_bkg1", bkgexp1_sigma, bkgexp1_sigma * 0.5, bkgexp1_sigma * 1.5, "");
+    RooRealVar tail_bkg1("tail_bkg1", "tail_bkg1", 1.0, 0.5, 5., "");
+    RooGaussianTail bkg1("bkg1", "bkg1", x, mean_bkg1, sigma_bkg1, tail_bkg1);
+    bkg1.fitTo(hbkg1, Range(bkgexp1_mean - 5. * bkgexp1_sigma, bkgexp1_mean + 10. * bkgexp1_sigma), SumW2Error(kFALSE), Verbose(kFALSE), PrintEvalErrors(10));
+#if DISPLAY
+    TCanvas *cBkg1_fit = new TCanvas("cBkg1_fit");
+    RooPlot *bkg1_frame = x.frame();
+    hbkg1.plotOn(bkg1_frame);
+    bkg1.plotOn(bkg1_frame, LineColor(kCyan+1));
+    bkg1_frame->Draw();
+    cBkg1_fit->Update();
+#endif
+    printf("BACKGROUND-1 PARAMETERS AFTER FIT OF EXPECTED BACKGROUND-1\n");
+    printf("mean_bkg1  = %f +- %f\n", mean_bkg1.getVal(), mean_bkg1.getError());
+    printf("sigma_bkg1 = %f +- %f\n", sigma_bkg1.getVal(), sigma_bkg1.getError());
+    printf("tail_bkg1  = %f +- %f\n", tail_bkg1.getVal(), tail_bkg1.getError());
+    /* scale parameters if requested */
+    if (SCALE_BACKGROUND_SIGMA != 1.) {
+      printf("SCALE FITTED BACKGROUND-1 SIGMA BY %f\n", SCALE_BACKGROUND_SIGMA);
+      sigma_bkg1.setVal(sigma_bkg1.getVal() * SCALE_BACKGROUND_SIGMA);
+    }
+    if (SCALE_BACKGROUND_TAIL != 1.) {
+      printf("SCALE FITTED BACKGROUND-1 TAIL BY %f\n", SCALE_BACKGROUND_TAIL);
+      tail_bkg1.setVal(tail_bkg1.getVal() * SCALE_BACKGROUND_TAIL);
+    }
+    /* fix/release parameters if requested */
+    if (FIX_BACKGROUND_MEAN) {
+      printf("SETTING BACKGROUND-1 FITTED MEAN AS CONSTANTS\n");
+      mean_bkg1.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-1 FITTED MEAN AS FREE\n");
+      mean_bkg1.setRange(mean_bkg1.getVal() - 0.25 * TMath::Abs(mean_bkg1.getVal()), mean_bkg1.getVal() + 0.25 * TMath::Abs(mean_bkg1.getVal()));
+    }
+    if (FIX_BACKGROUND_SIGMA) {
+      printf("SETTING BACKGROUND-1 FITTED SIGMA AS CONSTANTS\n");
+      sigma_bkg1.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-1 FITTED SIGMA AS FREE\n");
+      sigma_bkg1.setRange(sigma_bkg1.getVal() * 0.75, sigma_bkg1.getVal() * 1.25);
+    }
+    if (FIX_BACKGROUND_TAIL) {
+      printf("SETTING BACKGROUND-1 FITTED TAIL AS CONSTANTS\n");
+      tail_bkg1.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-1 FITTED TAIL AS FREE\n");
+      tail_bkg1.setRange(tail_bkg1.getVal() * 0.75, tail_bkg1.getVal() * 1.25);
+    }
+    /* fitting bkg2 */
+    TF1 *fGaus = (TF1 *)gROOT->GetFunction("gaus");
+    hBkgExp2->Fit(fGaus, "0q");
+    Double_t bkgexp2_mean = fGaus->GetParameter(1);
+    Double_t bkgexp2_sigma = fGaus->GetParameter(2);
+    RooRealVar mean_bkg2("mean_bkg2", "mean_bkg2", bkgexp2_mean, bkgexp2_mean - 10., bkgexp2_mean + 10., "");
+    RooRealVar sigma_bkg2("sigma_bkg2", "sigma_bkg2", bkgexp2_sigma, bkgexp2_sigma * 0.5, bkgexp2_sigma * 1.5, "");
+    RooRealVar tail_bkg2("tail_bkg2", "tail_bkg2", 1.0, 0.5, 5., "");
+    RooGaussianTail bkg2("bkg2", "bkg2", x, mean_bkg2, sigma_bkg2, tail_bkg2);
+    bkg2.fitTo(hbkg2, Range(bkgexp2_mean - 5. * bkgexp2_sigma, bkgexp2_mean + 10. * bkgexp2_sigma), SumW2Error(kFALSE), Verbose(kFALSE), PrintEvalErrors(10));
+#if DISPLAY
+    TCanvas *cBkg2_fit = new TCanvas("cBkg2_fit");
+    RooPlot *bkg2_frame = x.frame();
+    hbkg2.plotOn(bkg2_frame);
+    bkg2.plotOn(bkg2_frame,  LineColor(kGreen+1));
+    bkg2_frame->Draw();
+    cBkg2_fit->Update();
+#endif
+    printf("BACKGROUND-2 PARAMETERS AFTER FIT OF EXPECTED BACKGROUND-2\n");
+    printf("mean_bkg2  = %f +- %f\n", mean_bkg2.getVal(), mean_bkg2.getError());
+    printf("sigma_bkg2 = %f +- %f\n", sigma_bkg2.getVal(), sigma_bkg2.getError());
+    printf("tail_bkg2  = %f +- %f\n", tail_bkg2.getVal(), tail_bkg2.getError());
+    /* scale parameters if requested */
+    if (SCALE_BACKGROUND_SIGMA != 1.) {
+      printf("SCALE FITTED BACKGROUND-2 SIGMA BY %f\n", SCALE_BACKGROUND_SIGMA);
+      sigma_bkg2.setVal(sigma_bkg2.getVal() * SCALE_BACKGROUND_SIGMA);
+    }
+    if (SCALE_BACKGROUND_TAIL != 1.) {
+      printf("SCALE FITTED BACKGROUND-2 TAIL BY %f\n", SCALE_BACKGROUND_TAIL);
+      tail_bkg2.setVal(tail_bkg2.getVal() * SCALE_BACKGROUND_TAIL);
+    }
+    /* fix/release parameters if requested */
+    if (FIX_BACKGROUND_MEAN) {
+      printf("SETTING BACKGROUND-2 FITTED MEAN AS CONSTANTS\n");
+      mean_bkg2.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-2 FITTED MEAN AS FREE\n");
+      mean_bkg2.setRange(mean_bkg2.getVal() - 0.25 * TMath::Abs(mean_bkg2.getVal()), mean_bkg2.getVal() + 0.25 * TMath::Abs(mean_bkg2.getVal()));
+    }
+    if (FIX_BACKGROUND_SIGMA) {
+      printf("SETTING BACKGROUND-2 FITTED SIGMA AS CONSTANTS\n");
+      sigma_bkg2.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-2 FITTED SIGMA AS FREE\n");
+      sigma_bkg2.setRange(sigma_bkg2.getVal() * 0.75, sigma_bkg2.getVal() * 1.25);
+    }
+    if (FIX_BACKGROUND_TAIL) {
+      printf("SETTING BACKGROUND-2 FITTED TAIL AS CONSTANTS\n");
+      tail_bkg2.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-2 FITTED TAIL AS FREE\n");
+      tail_bkg2.setRange(tail_bkg2.getVal() * 0.75, tail_bkg2.getVal() * 1.25);
+    }
+    /* fitting bkg3 */
+    TF1 *fGaus = (TF1 *)gROOT->GetFunction("gaus");
+    hBkgExp3->Fit(fGaus, "0q");
+    Double_t bkgexp3_mean = fGaus->GetParameter(1);
+    Double_t bkgexp3_sigma = fGaus->GetParameter(2);
+    RooRealVar mean_bkg3("mean_bkg3", "mean_bkg3", bkgexp3_mean, bkgexp3_mean - 10., bkgexp3_mean + 10., "");
+    RooRealVar sigma_bkg3("sigma_bkg3", "sigma_bkg3", bkgexp3_sigma, bkgexp3_sigma * 0.5, bkgexp3_sigma * 1.5, "");
+    RooRealVar tail_bkg3("tail_bkg3", "tail_bkg3", 1., 0.5, 5., "");
+    RooGaussianTail bkg3("bkg3", "bkg3", x, mean_bkg3, sigma_bkg3, tail_bkg3);
+    bkg3.fitTo(hbkg3, Range(bkgexp3_mean - 5. * bkgexp3_sigma, bkgexp3_mean + 10. * bkgexp3_sigma), SumW2Error(kFALSE), Verbose(kFALSE), PrintEvalErrors(10));
+#if DISPLAY
+    TCanvas *cBkg3_fit = new TCanvas("cBkg3_fit");
+    RooPlot *bkg3_frame = x.frame();
+    hbkg3.plotOn(bkg3_frame);
+    bkg3.plotOn(bkg3_frame,  LineColor(kYellow+1));
+    bkg3_frame->Draw();
+    cBkg3_fit->Update();
+#endif
+    printf("BACKGROUND-3 PARAMETERS AFTER FIT OF EXPECTED BACKGROUND-3\n");
+    printf("mean_bkg3  = %f +- %f\n", mean_bkg3.getVal(), mean_bkg3.getError());
+    printf("sigma_bkg3 = %f +- %f\n", sigma_bkg3.getVal(), sigma_bkg3.getError());
+    printf("tail_bkg3  = %f +- %f\n", tail_bkg3.getVal(), tail_bkg3.getError());
+    /* scale parameters if requested */
+    if (SCALE_BACKGROUND_SIGMA != 1.) {
+      printf("SCALE FITTED BACKGROUND-3 SIGMA BY %f\n", SCALE_BACKGROUND_SIGMA);
+      sigma_bkg3.setVal(sigma_bkg3.getVal() * SCALE_BACKGROUND_SIGMA);
+    }
+    if (SCALE_BACKGROUND_TAIL != 1.) {
+      printf("SCALE FITTED BACKGROUND-3 TAIL BY %f\n", SCALE_BACKGROUND_TAIL);
+      tail_bkg3.setVal(tail_bkg3.getVal() * SCALE_BACKGROUND_TAIL);
+    }
+    /* fix/release parameters if requested */
+    if (FIX_BACKGROUND_MEAN) {
+      printf("SETTING BACKGROUND-3 FITTED MEAN AS CONSTANTS\n");
+      mean_bkg3.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-3 FITTED MEAN AS FREE\n");
+      mean_bkg3.setRange(mean_bkg3.getVal() - 0.25 * TMath::Abs(mean_bkg3.getVal()), mean_bkg3.getVal() + 0.25 * TMath::Abs(mean_bkg3.getVal()));
+    }
+    if (FIX_BACKGROUND_SIGMA) {
+      printf("SETTING BACKGROUND-3 FITTED SIGMA AS CONSTANTS\n");
+      sigma_bkg3.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-3 FITTED SIGMA AS FREE\n");
+      sigma_bkg3.setRange(sigma_bkg3.getVal() * 0.75, sigma_bkg3.getVal() * 1.25);
+    }
+    if (FIX_BACKGROUND_TAIL) {
+      printf("SETTING BACKGROUND-3 FITTED TAIL AS CONSTANTS\n");
+      tail_bkg3.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-3 FITTED TAIL AS FREE\n");
+      tail_bkg3.setRange(tail_bkg3.getVal() * 0.75, tail_bkg3.getVal() * 1.25);
+    }
+    /* fitting bkg4 */
+    TF1 *fGaus = (TF1 *)gROOT->GetFunction("gaus");
+    hBkgExp4->Fit(fGaus, "0q");
+    Double_t bkgexp4_mean = fGaus->GetParameter(1);
+    Double_t bkgexp4_sigma = fGaus->GetParameter(2);
+    RooRealVar mean_bkg4("mean_bkg4", "mean_bkg4", bkgexp4_mean, bkgexp4_mean - 10., bkgexp4_mean + 10., "");
+    RooRealVar sigma_bkg4("sigma_bkg4", "sigma_bkg4", bkgexp4_sigma, bkgexp4_sigma * 0.5, bkgexp4_sigma * 1.5, "");
+    RooRealVar tail_bkg4("tail_bkg4", "tail_bkg4", 1., 0.5, 5., "");
+    RooGaussianTail bkg4("bkg4", "bkg4", x, mean_bkg4, sigma_bkg4, tail_bkg4);
+    bkg4.fitTo(hbkg4, Range(bkgexp4_mean - 5. * bkgexp4_sigma, bkgexp4_mean + 10. * bkgexp4_sigma), SumW2Error(kFALSE), Verbose(kFALSE), PrintEvalErrors(10));
+#if DISPLAY
+    TCanvas *cBkg4_fit = new TCanvas("cBkg4_fit");
+    RooPlot *bkg4_frame = x.frame();
+    hbkg4.plotOn(bkg4_frame);
+    bkg4.plotOn(bkg4_frame,  LineColor(kYellow+2));
+    bkg4_frame->Draw();
+    cBkg4_fit->Update();
+#endif
+    printf("BACKGROUND-4 PARAMETERS AFTER FIT OF EXPECTED BACKGROUND-4\n");
+    printf("mean_bkg4  = %f +- %f\n", mean_bkg4.getVal(), mean_bkg4.getError());
+    printf("sigma_bkg4 = %f +- %f\n", sigma_bkg4.getVal(), sigma_bkg4.getError());
+    printf("tail_bkg4  = %f +- %f\n", tail_bkg4.getVal(), tail_bkg4.getError());
+    /* scale parameters if requested */
+    if (SCALE_BACKGROUND_SIGMA != 1.) {
+      printf("SCALE FITTED BACKGROUND-4 SIGMA BY %f\n", SCALE_BACKGROUND_SIGMA);
+      sigma_bkg4.setVal(sigma_bkg4.getVal() * SCALE_BACKGROUND_SIGMA);
+    }
+    if (SCALE_BACKGROUND_TAIL != 1.) {
+      printf("SCALE FITTED BACKGROUND-4 TAIL BY %f\n", SCALE_BACKGROUND_TAIL);
+      tail_bkg4.setVal(tail_bkg4.getVal() * SCALE_BACKGROUND_TAIL);
+    }
+    /* fix/release parameters if requested */
+    if (FIX_BACKGROUND_MEAN) {
+      printf("SETTING BACKGROUND-4 FITTED MEAN AS CONSTANTS\n");
+      mean_bkg4.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-4 FITTED MEAN AS FREE\n");
+      mean_bkg4.setRange(mean_bkg4.getVal() - 0.25 * TMath::Abs(mean_bkg4.getVal()), mean_bkg4.getVal() + 0.25 * TMath::Abs(mean_bkg4.getVal()));
+    }
+    if (FIX_BACKGROUND_SIGMA) {
+      printf("SETTING BACKGROUND-4 FITTED SIGMA AS CONSTANTS\n");
+      sigma_bkg4.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-4 FITTED SIGMA AS FREE\n");
+      sigma_bkg4.setRange(sigma_bkg4.getVal() * 0.75, sigma_bkg4.getVal() * 1.25);
+    }
+    if (FIX_BACKGROUND_TAIL) {
+      printf("SETTING BACKGROUND-4 FITTED TAIL AS CONSTANTS\n");
+      tail_bkg4.setConstant(kTRUE);
+    }
+    else {
+      printf("SETTING BACKGROUND-4 FITTED TAIL AS FREE\n");
+      tail_bkg4.setRange(tail_bkg4.getVal() * 0.75, tail_bkg4.getVal() * 1.25);
+    }
+  }
+  else if (GAUSSIAN_BACKGROUND) {
+    printf("USING GAUSSIAN BACKGROUND SHAPES (not reccomended)\n"); 
+    RooRealVar mean1("mean1", "mean1", hBkgExp1->GetMean(), hBkgExp1->GetMean() * 0.95, hBkgExp1->GetMean() * 1.05, "");
+    RooRealVar sigma1("sigma1", "sigma1", hBkgExp1->GetRMS(), hBkgExp1->GetRMS() * 0.5, hBkgExp1->GetRMS() * 1.5, "");
+    RooGaussian bkg1("bkg1", "bkg1", x, mean1, sigma1);
+    
+    RooRealVar mean2("mean2", "mean2", hBkgExp2->GetMean(), hBkgExp2->GetMean() * 0.95, hBkgExp2->GetMean() * 1.05, "");
+    RooRealVar sigma2("sigma2", "sigma2", hBkgExp2->GetRMS(), hBkgExp2->GetRMS() * 0.5, hBkgExp2->GetRMS() * 1.5, "");
+    RooGaussian bkg2("bkg2", "bkg2", x, mean2, sigma2);
+
+    RooRealVar mean3("mean3", "mean3", hBkgExp3->GetMean(), hBkgExp3->GetMean() * 0.95, hBkgExp3->GetMean() * 1.05, "");
+    RooRealVar sigma3("sigma3", "sigma3", hBkgExp3->GetRMS(), hBkgExp3->GetRMS() * 0.5, hBkgExp3->GetRMS() * 1.5, "");
+    RooGaussian bkg3("bkg3", "bkg3", x, mean3, sigma3);
+  }
+  else {
+    printf("SHAPE OF BACKGROUND NOT DEFINE: using EXPECTED_BACKGROUND\n");
+    RooHistPdf bkg1("bkg1", "bkg1", x, hbkg1, 0);
+    RooHistPdf bkg2("bkg2", "bkg2", x, hbkg2, 0);
+    RooHistPdf bkg3("bkg3", "bkg3", x, hbkg3, 0);
+    RooHistPdf bkg4("bkg4", "bkg4", x, hbkg4, 0);
+  }
+  printf("**************************************************\n");
+
+  /*** DEFINE MISMATCH BACKGROUND SHAPE ***/
+
+  printf("***** MISMATCH BACKGROUND SHAPE DEFINITION *****\n");
+  
+  /* variables and generic shapes */
+  Double_t expectedCutoff = hBkgExp3->GetMean();
+  Double_t expectedCutoffRMS = hBkgExp3->GetRMS();
+  //    RooRealVar cutoff("cutoff", "cutoff", -30., -50., 0., "");
+  RooRealVar cutoff("cutoff", "cutoff", expectedCutoff, expectedCutoff - 3. * expectedCutoffRMS, expectedCutoff, "");
+  //  RooRealVar cutoff("cutoff", "cutoff", expectedCutoff, "");
+  //  RooRealVar power("power", "power", 1., 0.5, 5.0, "");
+  RooRealVar power("power", "power", 1., "");
+  RooFermiCutoff fermi("fermi", "fermi", x, cutoff, power);
+  RooRealVar alpha("alpha", "alpha", 0., -10., 0., "");
+  RooExponential expo("expo", "expo", x, alpha);
+  RooUniform uniform("uniform", "uniform", x);
+
+  /* mismatch shape */
+  if (EXPECTED_MISMATCH) {
+    printf("USING EXPECTED MISMATCH SHAPE FROM HISTOGRAMS\n");
+    RooHistPdf mismatch("mismatch", "mismatch", x, hmismatch, 0);
+  }
+  else if (UNIFORM_MISMATCH) {
+    printf("USING UNIFORM BACKGROUND SHAPE WITH CUTOFF\n");
+    RooProdPdf mismatch("mismatch", "mismatch", fermi, uniform, -100.);
+  }
+  else if (EXPONENTIAL_MISMATCH) {
+    printf("USING EXPONENTIAL BACKGROUND SHAPE WITH CUTOFF\n");
+    RooProdPdf mismatch("mismatch", "mismatch", fermi, expo, -100.);
+  }
+  else if (DOUBLEEXPONENTIAL_MISMATCH) {
+    printf("USING DOUBLE-EXPONENTIAL BACKGROUND SHAPE WITH CUTOFF\n");
+    RooRealVar alpha1("alpha1", "alpha1", 0., -10., 0., "");
+    RooRealVar alpha2("alpha2", "alpha2", 0., -10., 0., "");
+    RooRealVar frac("frac", "frac", 0.5, 0., 1., "");
+    RooGenericPdf doubleexpo("doubleexpo", "TMath::Exp(alpha1 * x) + frac * TMath::Exp(alpha2 * x)", RooArgSet(x, alpha1, alpha2, frac));
+    RooProdPdf mismatch("mismatch", "mismatch", fermi, doubleexpo, -100.);
+  }
+  else if (UNIFORMPLUSEXPONENTIAL_MISMATCH) {
+    printf("USING UNIFORM-PLUS-EXPONENTIAL BACKGROUND SHAPE WITH CUTOFF\n");
+    RooRealVar funiform("funiform", "funiform", 100., 0., 100000., "");
+    RooRealVar fexpo("fexpo", "fexpo", 100., 0., 100000., "");
+    RooAddPdf uniformplusexpo("uniformplusexpo", "uniformplusexpo", RooArgList(uniform, expo), RooArgList(funiform, fexpo), kFALSE);
+    RooProdPdf mismatch("mismatch", "mismatch", fermi, uniformplusexpo, -100.);
+  }
+  else {
+    printf("SHAPE OF MISMATCH NOT DEFINE: using EXPECTED_MISMATCH\n");
+    RooHistPdf mismatch("mismatch", "mismatch", x, hmismatch, 0);
+  }
+  printf("************************************************\n");
+
+  /*** DEFINE THE MODEL ***/
+
+  printf("***** MODEL DEFINITION *****\n");
+
+  /* variables */
+  Double_t integral = hdata.sumEntries();
+  RooRealVar nsignal("nsignal", "nsignal", 0.3 * integral, 0., integral);
+  RooRealVar nbkg1("nbkg1", "nbkg1", 0.3 * integral, 0., integral);
+  RooRealVar nbkg2("nbkg2", "nbkg2", 0.3 * integral, 0., integral);
+  RooRealVar nbkg3("nbkg3", "nbkg3", 0.3 * integral, 0., integral);
+  RooRealVar nbkg4("nbkg4", "nbkg4", 0.3 * integral, 0., integral);
+  RooRealVar nmismatch("nmismatch", "nmismatch", 0.1 * integral, 0., integral);
+
+if (!fitBkg1) {
+  nbkg1.setVal(0.);
+  nbkg1.setConstant(kTRUE);  
+ }
+if (!fitBkg2) {
+  nbkg2.setVal(0.);
+  nbkg2.setConstant(kTRUE);  
+ }
+if (!fitBkg3) {
+  nbkg3.setVal(0.);
+  nbkg3.setConstant(kTRUE);  
+ }
+if (!fitBkg4) {
+  nbkg4.setVal(0.);
+  nbkg4.setConstant(kTRUE);  
+ }
+
+  RooAddPdf model("model", "model p.d.f.", RooArgList(signal, bkg1, bkg2, bkg3, bkg4, mismatch), RooArgList(nsignal, nbkg1, nbkg2, nbkg3, nbkg4, nmismatch));
+
+#if 0
+  /* the model */
+  if (USE_ELECTRON_BACKGROUND && fitElectrons && fitPions) {
+    printf("USING ELECTRON BACKGROUND\n");
+    if (NO_MISMATCH) {
+      printf("NOT USING MISMATCH BACKGROUND\n");
+      nmismatch.setVal(0.);
+      RooAddPdf model("model", "model p.d.f.", RooArgList(signal, bkg1, bkg2, bkg3/*, bkg4*/), RooArgList(nsignal, nbkg1, nbkg2, nbkg3/*, nbkg4*/));
+    }
+    else {
+      printf("USING MISMATCH BACKGROUND\n");
+      RooAddPdf model("model", "model p.d.f.", RooArgList(signal, bkg1, bkg2, bkg3/*, bkg4*/, mismatch), RooArgList(nsignal, nbkg1, nbkg2, nbkg3/*, nbkg4*/, nmismatch));
+    }
+  }
+  else if (!USE_ELECTRON_BACKGROUND || !fitElectrons) {
+    printf("NOT USING ELECTRON BACKGROUND\n");
+    nbkg3.setVal(0.);
+    nbkg4.setVal(0.);
+    if (NO_MISMATCH) {
+      printf("NOT USING MISMATCH BACKGROUND\n");
+      nmismatch.setVal(0.);
+      RooAddPdf model("model", "model p.d.f.", RooArgList(signal, bkg1, bkg2), RooArgList(nsignal, nbkg1, nbkg2));
+    }
+    else {
+      printf("USING MISMATCH BACKGROUND\n");
+      RooAddPdf model("model", "model p.d.f.", RooArgList(signal, bkg1, bkg2, mismatch), RooArgList(nsignal, nbkg1, nbkg2, nmismatch));
+    }
+  }
+  printf("****************************\n");
+#endif
+
+
+
+
+  /*** FIT ***/
+
+  printf("***** FIT *****\n");
+
+  printf("SIGNAL PARAMETERS BEFORE GLOBAL FIT\n");
+  printf("mean  = %f +- %f\n", mean.getVal(), mean.getError());
+  printf("sigma = %f +- %f\n", sigma.getVal(), sigma.getError());
+  printf("tail  = %f +- %f\n", tail.getVal(), tail.getError());
+
+  /* fit and draw */
+  if (canvas) canvas->cd();
+  //  model.chi2FitTo(hdata, Extended(kTRUE), Verbose(kFALSE), SumW2Error(kFALSE), Range(-40., 140.), Binned(kTRUE));
+//  model.fitTo(hdata, Extended(kTRUE), SumW2Error(kFALSE), Verbose(kFALSE), PrintEvalErrors(10), Range(-10., 10.));
+model.fitTo(hdata, Range(rangeMin, rangeMax), Extended(kTRUE), SumW2Error(kFALSE), Verbose(kFALSE), PrintEvalErrors(10));
+
+  printf("***************\n");
+
+  /*** DRAW ***/
+#if DISPLAY
+  RooPlot *xframe = x.frame();
+hdata.plotOn(xframe, XErrorSize(0), DrawOption("PZ"));
+model.plotOn(xframe, LineWidth(2)/*, Precision(1.e-4)*/);
+model.plotOn(xframe, Components(signal), LineWidth(2), LineColor(kRed)/*, Precision(1.e-4)*/);
+  model.plotOn(xframe, Components(bkg1), LineWidth(2), LineStyle(kDashed), LineColor(kCyan+1));
+  model.plotOn(xframe, Components(bkg2), LineWidth(2), LineStyle(kDashed), LineColor(kGreen+1));
+  if (USE_ELECTRON_BACKGROUND) {
+    model.plotOn(xframe, Components(bkg3), LineWidth(2), LineStyle(kDashed), LineColor(kYellow+1));
+    model.plotOn(xframe, Components(bkg4), LineWidth(2), LineStyle(kDashed), LineColor(kYellow+2));
+  }
+  if (!NO_MISMATCH)
+    model.plotOn(xframe, Components(mismatch), LineWidth(2), LineStyle(kDashed), LineColor(kGray+1));
+  hSignal->SetFillColor(kYellow);
+  hSignal->SetLineWidth(0);
+  hSignal->SetFillStyle(0);
+  hSignal->SetMinimum(0.1);
+  hSignal->GetXaxis()->SetRangeUser(rangeMin, rangeMax);
+//  hSignal->Draw();
+xframe->SetMinimum(0.1);
+  xframe->Draw();
+#endif
+  if (canvas) canvas->Update();
+
+  /*** COMPUTE CHI2 ***/
+  Double_t datax, datapoint, datapoint_err, modelpoint;
+  Double_t chi2 = 0.;
+  Int_t ndf = 0;
+  for (Int_t ibin = 0; ibin < hSignal->GetNbinsX(); ibin++) {
+    datax = hSignal->GetBinCenter(ibin + 1);
+    if (datax < rangeMin || datax > rangeMax) continue;
+    datapoint = hSignal->GetBinContent(ibin + 1);
+    datapoint_err = hSignal->GetBinError(ibin + 1);
+    if (datapoint_err == 0.) continue;
+    x.setVal(datax);
+    modelpoint = model.getVal();
+    chi2 += (datapoint - modelpoint) * (datapoint - modelpoint) / (datapoint_err * datapoint_err);
+    ndf++;
+  }
+
+
+/*** PRINT FIT OUTPUT ***/
+printf("***** CHI-SQUARE *****\n");
+  printf("chi-square = %f\n", chi2);
+  printf("NDF        = %d\n", ndf);
+  printf("chi2/NDF   = %f\n", ndf > 0 ? chi2 / ndf : 0.);
+  printf("***** SIGNAL-SHAPE INFO *****\n");
+  printf("mean      = %f +- %f\n", mean.getVal(), mean.getError());
+  printf("sigma     = %f +- %f\n", sigma.getVal(), sigma.getError());
+  printf("tail      = %f +- %f\n", tail.getVal(), tail.getError());
+  printf("pure gaus = %f +- %f\n", gaussianfrac.getVal(), gaussianfrac.getError());
+printf("*****************************\n");
+printf("***** COUNTS *****\n");
+printf("total     = %f\n", hSignal->Integral(-1, -1));
+  printf("integral  = %f\n", hdata.sumEntries());
+  printf("nsignal   = %f +- %f\n", nsignal.getVal(), nsignal.getError());
+  printf("nbkg1     = %f +- %f\n", nbkg1.getVal(), nbkg1.getError());
+  printf("nbkg2     = %f +- %f\n", nbkg2.getVal(), nbkg2.getError());
+  printf("nbkg3     = %f +- %f\n", nbkg3.getVal(), nbkg3.getError());
+  printf("nbkg4     = %f +- %f\n", nbkg4.getVal(), nbkg4.getError());
+  printf("nmismatch = %f +- %f\n", nmismatch.getVal(), nmismatch.getError());
+  printf("******************\n");
+
+  /*** OUTPUT FIT PARAMS ***/
+  
+  param[kMean] = mean.getVal();
+  param_err[kMean] = mean.getError();
+  param[kSigma] = sigma.getVal();
+  param_err[kSigma] = sigma.getError();
+  param[kTail] = tail.getVal();
+  param_err[kTail] = tail.getError();
+  param[kTotalCounts] = hSignal->GetEntries();
+  param_err[kTotalCounts] = sqrt(hSignal->GetEntries());
+  param[kIntegralCounts] = hdata.sumEntries();
+  param_err[kIntegralCounts] = sqrt(hdata.sumEntries());
+  param[kSignalCounts] = nsignal.getVal();
+  param_err[kSignalCounts] = nsignal.getError();
+  param[kB