Full package used for dN/dEta vs centrality analysis in PbPb
authorshahoian <shahoian@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 8 Dec 2010 12:24:40 +0000 (12:24 +0000)
committershahoian <shahoian@f7af4fe6-9843-0410-8265-dc069ae4e863>
Wed, 8 Dec 2010 12:24:40 +0000 (12:24 +0000)
21 files changed:
PWG0/multVScentPbPb/AddMultTaskRS.C [new file with mode: 0755]
PWG0/multVScentPbPb/AddMultTaskTrackletMulti.C [new file with mode: 0755]
PWG0/multVScentPbPb/AddTaskGlobVar.C [new file with mode: 0755]
PWG0/multVScentPbPb/AliITSMultRecBg.cxx [new file with mode: 0755]
PWG0/multVScentPbPb/AliITSMultRecBg.h [new file with mode: 0755]
PWG0/multVScentPbPb/AliTaskGlobVar.cxx [new file with mode: 0755]
PWG0/multVScentPbPb/AliTaskGlobVar.h [new file with mode: 0755]
PWG0/multVScentPbPb/AliTrackletTaskMulti.cxx [new file with mode: 0755]
PWG0/multVScentPbPb/AliTrackletTaskMulti.h [new file with mode: 0755]
PWG0/multVScentPbPb/AliTrackletTaskUni.cxx [new file with mode: 0755]
PWG0/multVScentPbPb/AliTrackletTaskUni.h [new file with mode: 0755]
PWG0/multVScentPbPb/AnalysisMacroGlob.C [new file with mode: 0755]
PWG0/multVScentPbPb/CorrectSpectra.C [new file with mode: 0755]
PWG0/multVScentPbPb/CorrectSpectraMulti.C [new file with mode: 0755]
PWG0/multVScentPbPb/DrawMult.C [new file with mode: 0755]
PWG0/multVScentPbPb/MyAnalysisMacro.C [new file with mode: 0755]
PWG0/multVScentPbPb/MyAnalysisMacroTrackletMulti.C [new file with mode: 0755]
PWG0/multVScentPbPb/README [new file with mode: 0644]
PWG0/multVScentPbPb/runAAF.C [new file with mode: 0755]
PWG0/multVScentPbPb/runAAFMulti.C [new file with mode: 0755]
PWG0/multVScentPbPb/runAAFglob.C [new file with mode: 0755]

diff --git a/PWG0/multVScentPbPb/AddMultTaskRS.C b/PWG0/multVScentPbPb/AddMultTaskRS.C
new file mode 100755 (executable)
index 0000000..b5c2e53
--- /dev/null
@@ -0,0 +1,19 @@
+AliTrackletTaskUni* AddMultTaskRS(const char* outName="tracklet.root")
+{
+  // create manager
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) mgr = new AliAnalysisManager("My test train");
+  // create our task
+  AliTrackletTaskUni *task = new AliTrackletTaskUni("AliTrackletTaskUni");
+  // create output container
+  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outName);
+
+  // add our task to the manager
+  mgr->AddTask(task);
+
+  // finaly connect input and output
+  mgr->ConnectInput(task, 0,  mgr->GetCommonInputContainer());
+  mgr->ConnectOutput(task,1,coutput1);
+  //
+  return task;
+}
diff --git a/PWG0/multVScentPbPb/AddMultTaskTrackletMulti.C b/PWG0/multVScentPbPb/AddMultTaskTrackletMulti.C
new file mode 100755 (executable)
index 0000000..5362030
--- /dev/null
@@ -0,0 +1,19 @@
+AliTrackletTaskMulti* AddMultTaskTrackletMulti(const char* outName="tracklet.root")
+{
+  // create manager
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) mgr = new AliAnalysisManager("My test train");
+  // create our task
+  AliTrackletTaskMulti *task = new AliTrackletTaskMulti("AliTrackletTaskMulti");
+  // create output container
+  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outName);
+
+  // add our task to the manager
+  mgr->AddTask(task);
+
+  // finaly connect input and output
+  mgr->ConnectInput(task, 0,  mgr->GetCommonInputContainer());
+  mgr->ConnectOutput(task,1,coutput1);
+  //
+  return task;
+}
diff --git a/PWG0/multVScentPbPb/AddTaskGlobVar.C b/PWG0/multVScentPbPb/AddTaskGlobVar.C
new file mode 100755 (executable)
index 0000000..5c4f148
--- /dev/null
@@ -0,0 +1,19 @@
+AliTaskGlobVar* AddTaskGlobVar(const char* outName="tt.root")
+{
+  // create manager
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) mgr = new AliAnalysisManager("My test train");
+  // create our task
+  AliTaskGlobVar *task = new AliTaskGlobVar("AliTaskGlobVar");
+  // create output container
+  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outName);
+
+  // add our task to the manager
+  mgr->AddTask(task);
+
+  // finaly connect input and output
+  mgr->ConnectInput(task, 0,  mgr->GetCommonInputContainer());
+  mgr->ConnectOutput(task,1,coutput1);
+  //
+  return task;
+}
diff --git a/PWG0/multVScentPbPb/AliITSMultRecBg.cxx b/PWG0/multVScentPbPb/AliITSMultRecBg.cxx
new file mode 100755 (executable)
index 0000000..b868ad4
--- /dev/null
@@ -0,0 +1,559 @@
+#include "AliITSMultRecBg.h"
+#include "AliGeomManager.h"
+#include "AliMultiplicity.h"
+#include "../ITS/AliITSgeomTGeo.h"
+#include <TH2F.h>
+#include <TTree.h>
+#include <TRandom.h>
+#include <TBits.h>
+#include <TClonesArray.h>
+
+ClassImp(AliITSMultRecBg)
+
+//_________________________________________________________________
+AliITSMultRecBg::AliITSMultRecBg() 
+: fRecType(kData),
+  fInjLr(0),
+  fInjStave(0),
+  fInjModule(0),
+  fInjModInStave(0),
+  fInjX(0),
+  fInjZ(0),
+  fInjHitsN(0),
+  fInjScale(1),
+  fInjCurrTrial(0),
+  fInjCluster(),
+  fInjBuffer(2*kTrNPar)
+  //
+{
+  // constructor
+  fCreateClustersCopy = kTRUE;
+  for (int i=0;i<2;i++) {
+    fAssociations[i] = 0;
+    fInjSPDOcc[i]    = 0;
+    fInjSPDPatt[i]   = 0;
+    fInjNTrials[i]   = 0;
+    fInjNSuccess[i]  = 0;    
+    for (int s=4;s--;) fInjModuleClStart[i][s] = fInjModuleClN[i][s] = 0;
+  }
+  //
+}
+
+//_________________________________________________________________
+AliITSMultRecBg::~AliITSMultRecBg()
+{
+  // destructor
+  for (int i=0;i<2;i++) {
+    delete[] fAssociations[i];
+    delete   fInjSPDOcc[i];
+    delete   fInjSPDPatt[i];
+    for (int s=4;s--;) {
+      delete[] fInjModuleClStart[i][s];
+      delete[] fInjModuleClN[i][s];
+    }
+  }
+  //
+}
+
+//____________________________________________________________________
+void AliITSMultRecBg::CreateMultiplicityObject()
+{
+  // create AliMultiplicity object
+  //
+  if (fRecType==kData || fRecType==kBgRot || fRecType==kBgMix) {
+    AliITSMultReconstructor::CreateMultiplicityObject();
+  }
+  else if (fRecType==kBgInj) {
+    if (fMult) delete fMult;
+    int ntr = GetNInjSuccsess();
+    TBits fastOrFiredMap(0);
+    fMult = new AliMultiplicity(ntr,0,fNFiredChips[0],fNFiredChips[1],fastOrFiredMap);
+    fMult->SetMultTrackRefs(kTRUE);
+    fMult->SetScaleDThetaBySin2T(fScaleDTBySin2T);
+    fMult->SetDPhiWindow2(fDPhiWindow2);
+    fMult->SetDThetaWindow2(fDThetaWindow2);
+    fMult->SetDPhiShift(fDPhiShift);
+    fMult->SetNStdDev(fNStdDev);
+    //
+    for (int itr=ntr;itr--;)  {
+      Float_t *tlInfo = fInjBuffer.GetArray() + itr*kTrNPar;
+      fMult->SetTrackletData(itr,tlInfo);
+    }
+  }
+  //
+
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::Run(TTree* tree, Float_t* vtx, TTree* treeMix)
+{
+  // reconstruct with current settings
+  if (!tree) AliFatal("The RP Tree is missing");
+  if (fRecType==kBgMix && !treeMix) AliFatal("Mixed Mode requested but 2nd RP Tree is missing")
+  if (!vtx)  return;
+  //
+  if      (fRecType==kData)  Reconstruct(tree, vtx);
+  else if (fRecType==kBgRot) Reconstruct(tree, vtx);
+  else if (fRecType==kBgMix) ReconstructMix(tree, treeMix, vtx);
+  else if (fRecType==kBgInj) GenInjBgSample(tree,vtx); // if needed, the reco will be done internally
+  else {  AliError(Form("Unknown running mode %d",fRecType)); }
+  //
+  CreateMultiplicityObject();
+}
+
+//_________________________________________________________________________
+Bool_t AliITSMultRecBg::PrepareInjBgGenerator(Float_t *vtx)
+{
+  // prepare histograms/patterns for bg generation
+  //
+  if (!fRecoDone) Reconstruct(fTreeRP,vtx);
+  //
+  float xshift = fSPDSeg.Dx()/2, zshift = fSPDSeg.Dz()/2;
+  int  maxRow1 = fSPDSeg.Npx(), maxCol1 = fSPDSeg.Npz();
+  int nChipsPerLadder = fSPDSeg.GetNumberOfChips();  
+  //
+  fInjCluster.SetLabel(kInjFakeLabel,0);
+  fInjCluster.SetLabel(-2,1);
+  fInjCluster.SetLabel(-2,2);
+  //
+  for (int ilr=0;ilr<2;ilr++) {
+    int nLadPerStave = AliITSgeomTGeo::GetNDetectors(ilr+1);
+    int nStaves = AliITSgeomTGeo::GetNLadders(ilr+1);
+    for (int ild=nLadPerStave;ild--;) {
+      fInjModuleTotClN[ilr][ild] = 0;
+      for (int is=nStaves;is--;) {
+       fInjModuleClStart[ilr][ild][is] = -1;
+       fInjModuleClN[ilr][ild][is] = 0;
+      }
+    }
+    //
+    fInjSPDOcc[ilr]->Reset();
+    fInjSPDPatt[ilr]->ResetAllBits();
+    TClonesArray* clusters = fClArr[ilr];
+    Int_t nclus = fNClustersLay[ilr];
+    //
+    for (int icl=0;icl<nclus;icl++) {
+      AliITSRecPoint* clus = (AliITSRecPoint*)clusters->UncheckedAt(icl); 
+      if (!clus) continue;
+      int ladder = clus->GetDetectorIndex();   // ladder id within the layer
+      int stave = ladder/nLadPerStave;
+      ladder = nLadPerStave-1 - ladder%nLadPerStave; // ladder id within the stave !!!! invert to get human readble histos
+      // the clusters are packed per modules, register the beginning and n.clusters of each module
+      if (fInjModuleClStart[ilr][ladder][stave]<0)  fInjModuleClStart[ilr][ladder][stave] = icl;
+      fInjModuleClN[ilr][ladder][stave]++;
+      fInjModuleTotClN[ilr][ladder]++; 
+      //
+      int chip = fSPDSeg.GetChipFromLocal(clus->GetDetLocalX(),clus->GetDetLocalZ()); // chip within the ladder
+      if (ilr==1) chip = nChipsPerLadder - 1 - chip; //!!!! invert to get human readble histos
+      chip += ladder*nChipsPerLadder; // chip within the stave
+      ladder %= nLadPerStave; // ladder id within the stave
+      fInjSPDOcc[ilr]->Fill(chip, stave);                      // register cluster for hit density profile
+      //
+      float xloc = clus->GetDetLocalX()*1e4+xshift;
+      float zloc = clus->GetDetLocalZ()*1e4+zshift;
+      int row,col;
+      fSPDSeg.GetPadIxz(xloc,zloc,row,col); // row,col here stats from 1
+      row--;
+      col--;
+      //
+      // generate bit pattern according to hit type
+      int npix = clus->GetType();
+      int nrows = clus->GetNy();
+      int ncols = clus->GetNz();
+      float cx=0,cz=0;
+      UInt_t *patt = GenClusterPattern(npix,nrows,ncols,cx,cz);
+      row = int(row - cx); if (row<0) row=0; else if (row+nrows>maxRow1) row = maxRow1-nrows;
+      col = int(col - cz); if (col<0) col=0; else if (col+ncols>maxCol1) col = maxCol1-ncols;
+      for (int icol=ncols;icol--;) {
+       UInt_t hcol = patt[icol];
+       for (int irow=nrows;irow--;) {
+         if (!(hcol&(1<<irow))) continue; // no hit here
+         int pbit = GetPixelBitL(stave,ladder,col+icol,row+irow);
+         fInjSPDPatt[ilr]->SetBitNumber( pbit );
+       }
+      }
+      //
+    } // loop over clusters of layer ilr  
+  } // loop over layers
+  //
+  if (fNClustersLay[0]==0||fNClustersLay[1]==0) {
+    AliInfo(Form("Trackleting is impossible: Ncl1=%d Ncl2=%d",fNClustersLay[0],fNClustersLay[1]));
+    return kFALSE;
+  }
+  for (int i=0;i<2;i++) {
+    if (fAssociations[i]) delete[] fAssociations[i];
+    int* tmpi = fAssociations[i] = new Int_t[ fNClustersLay[i] ];
+    for (int ic=fNClustersLay[i];ic--;) tmpi[ic] = -1;
+  }
+  for (int itr=fNTracklets;itr--;) {
+    Float_t* tracklet = GetTracklet(itr);
+    int cll1 = (int)tracklet[kClID1];
+    int cll2 = (int)tracklet[kClID2];
+    fAssociations[0][cll1] = cll2;
+    fAssociations[1][cll2] = cll1;
+  }
+  //
+  fInjBuffer.Set(fNTracklets*kTrNPar);
+  //
+  return kTRUE;
+  //
+}
+
+//_________________________________________________________________________
+Bool_t AliITSMultRecBg::GenClusterToInject()
+{
+  // generate bg cluster on layer lr
+  //
+  int nLadPerStave = AliITSgeomTGeo::GetNDetectors(fInjLr+1);
+  int nChipsPerModule = fSPDSeg.GetNumberOfChips();
+  //
+  int clID;
+  //
+  //RRR  printf("On Lr %d | %d %d\n",fInjLr,fNClustersLay[0],fNClustersLay[1]);
+  do {
+    fInjSPDOcc[fInjLr]->GetRandom2(fInjZ, fInjX); 
+    //    printf("raw: %f %f\n",fInjZ,fInjX);
+    fInjStave = int(fInjX);
+    int chipInStave  = int(fInjZ);    // chip in the stave
+    //
+    fInjX = (fInjX - fInjStave)*fSPDSeg.Dx();     // local x coordinate
+    fInjModInStave = chipInStave/nChipsPerModule;
+    fInjModInStave = nLadPerStave - 1 - fInjModInStave;  //!!! go from human readable to formal one
+    fInjModule = fInjStave*nLadPerStave + fInjModInStave; // formal module number
+    //
+    fInjZ = (fInjZ-chipInStave)*fSPDSeg.Dz();     // local z coordinate
+    //    printf("Z %e X %e | MinSt%d Mod%d\n",fInjZ, fInjX,fInjModInStave,fInjModule);
+    //
+    clID = PickClusterPrototype(fInjLr, fInjModInStave, fInjStave);    
+  } while(clID<0);
+  //
+  //  printf("clID: %d %d %d %d\n",clID,fNClustersLay[0],fNClustersLay[1],fInjLr);
+  AliITSRecPoint* rClus = (AliITSRecPoint*)fClArr[fInjLr]->UncheckedAt(clID);
+  fInjCluster.SetLayer(fInjLr);
+  fInjCluster.SetType(TMath::Min(kInjMaxNY*kInjMaxNZ,rClus->GetType()));
+  fInjCluster.SetNy(TMath::Min(kInjMaxNY,rClus->GetNy()));
+  fInjCluster.SetNz(TMath::Min(kInjMaxNZ,rClus->GetNz()));
+  fInjCluster.SetDetectorIndex(fInjModule);
+  fInjCluster.SetVolumeId(AliGeomManager::LayerToVolUID(AliGeomManager::kSPD1+fInjLr,fInjModule));
+  //
+  PlaceInjCluster();
+  return kTRUE;
+  //
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::PlaceInjCluster()
+{
+  // place the injected cluster on the selected module, 
+  // avoiding overlaps with real clusters
+  int npix = fInjCluster.GetType(), nrows = fInjCluster.GetNy(), ncols = fInjCluster.GetNz();
+  Float_t cx=0,cz=0;
+  UInt_t* pattern = GenClusterPattern(npix, nrows, ncols, cx,cz);
+  //
+  // try to embedd on top of real clusters
+  int maxRow1 = fSPDSeg.Npx(), maxCol1 = fSPDSeg.Npz();
+  int maxRow  = maxRow1-1,     maxCol  = maxCol1-1;
+  TBits &bits = *fInjSPDPatt[fInjLr];   // hits pattern of selected layer
+  int row0=0,col0=0;
+  Bool_t failed;
+  do {
+    failed = kFALSE;
+    fSPDSeg.GetPadIxz(fInjX,fInjZ,row0,col0);
+    row0--; col0--;                  // row,col here start from 1
+    if (row0+nrows > maxRow1) row0 = maxRow1-nrows;
+    if (col0+ncols > maxCol1) col0 = maxCol1-ncols;
+    //
+    //    printf("Cluster at %f %f: col:%d row:%d\n",fInjZ,fInjX,col0,row0);
+    // 
+    // check if generated pattern is mergable with data clusters
+    fInjHitsN = 0;
+    for (int ic=ncols;ic--;) {
+      int colt = col0+ic; 
+      for (int ir=nrows;ir--;) {
+       if ( !(pattern[ic]&(1<<ir)) ) continue; // not used
+       int rowt = row0+ir;
+       int bitID = GetPixelBitL(fInjStave,fInjModInStave,colt,rowt);
+       if ( bits.TestBitNumber(bitID) ||       // is pixel free?
+            (colt>0      && bits.TestBitNumber(bitID-maxRow1)) || // pixel  1 column below
+            (colt<maxCol && bits.TestBitNumber(bitID+maxRow1)) || // pixel  1 column above
+            (rowt>0      && bits.TestBitNumber(bitID-1))       || // pixel  1 row below
+            (rowt<maxRow && bits.TestBitNumber(bitID+1)))         // pixel in 1 row above
+         {failed=kTRUE; break;}
+       // ok for this pixel
+       fInjHits[fInjHitsN++] = bitID;
+      }
+      if (failed) break;
+    }
+    if (failed) { // generate new x,z
+      //      printf("Conflict found, retry\n");
+      fInjX = gRandom->Rndm()*fSPDSeg.Dx();
+      fInjZ = gRandom->Rndm()*fSPDSeg.Dz();
+      continue;
+    }
+  } while(failed);
+  //
+  // caclulate cluster coordinates
+  float x=0,z=0;
+  fInjX = fInjZ = 0;
+  for (int pix=fInjHitsN;pix--;) {
+    ExtractPixelL(fInjHits[pix], fInjStave, fInjModInStave, col0, row0);
+    fSPDSeg.GetPadCxz(row0+1,col0,x,z); // !!! Note: here row starts from 1 but col from 0!!!
+    fInjX += x;
+    fInjZ += z;
+  }
+  fInjX = (fInjX/fInjHitsN-fSPDSeg.Dx()/2)*1e-4;
+  fInjZ = (fInjZ/fInjHitsN-fSPDSeg.Dz()/2)*1e-4;
+  const TGeoHMatrix *mT2L = AliITSgeomTGeo::GetTracking2LocalMatrix(fInjLr+1,fInjStave+1,fInjModInStave+1);
+  Double_t loc[3]={fInjX,0.,fInjZ},trk[3]={0.,0.,0.};
+  mT2L->MasterToLocal(loc,trk);
+  //
+  fInjCluster.SetX(0);
+  fInjCluster.SetY(trk[1]);
+  fInjCluster.SetZ(trk[2]);
+  //
+  // printf("ClCoord: %+e %+e %+e\n",fInjCluster.GetX(),fInjCluster.GetY(),fInjCluster.GetZ());
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::InitInjBg()
+{
+  // initialize data for bg injection
+  char buff[100];
+  for (int ilr=0;ilr<2;ilr++) {
+    sprintf(buff,"occL%d",ilr);
+    int nLaddersStave = AliITSgeomTGeo::GetNDetectors(ilr+1);
+    int nChipsStave   = fSPDSeg.GetNumberOfChips()*nLaddersStave;
+    int nStaves       = AliITSgeomTGeo::GetNLadders(ilr+1);
+    int nColsStave    = fSPDSeg.Npz();
+    int nRowsStave    = fSPDSeg.Npz();
+    fInjSPDOcc[ilr]  = new TH2F(buff,buff,nChipsStave,0,nChipsStave, nStaves,0,nStaves);
+    fInjSPDPatt[ilr] = new TBits(nStaves*nLaddersStave*nColsStave*nRowsStave);
+    for (int is=0;is<nStaves;is++) {
+      for (int il=0;il<nLaddersStave;il++) {
+       fInjModuleClStart[ilr][il] = new Int_t[nStaves];
+       fInjModuleClN[ilr][il]     = new Int_t[nStaves];
+      }
+    }
+    //
+  }
+}
+
+//_________________________________________________________________________
+UInt_t* AliITSMultRecBg::GenClusterPattern(Int_t &npix, Int_t &ny, Int_t &nz, Float_t cy,Float_t &cz)
+{
+  // generate random pattern for the cluster
+  static UInt_t hitPattern[160];
+  if (ny>kInjMaxNY) ny = kInjMaxNY;
+  if (nz>kInjMaxNZ) nz = kInjMaxNZ;
+  for (int iz=nz;iz--;) hitPattern[iz]=0;
+  //
+  // handle explicitly easy cases: () is for pixels in the same column ...
+  if      (npix==1) hitPattern[0] = 0x1; // type (|)
+  else if (npix==2) {
+    if (nz==1) hitPattern[0] = 0x3;      // tpye (||)
+    else       hitPattern[0] = hitPattern[1] = 0x1; // tpye (|)(|)
+  }
+  else if (npix==3) {
+    if      (nz==1) hitPattern[0] = 0x7;      // tpye (|||)
+    else if (ny==1) hitPattern[0] = hitPattern[1] = hitPattern[2] = 0x1; // type (|)(|)(|)
+    else { hitPattern[0] = 0x3; hitPattern[1] = 0x1;}    // type (||)(|)
+  }
+  else if (npix==4) {
+    if      (nz==1) hitPattern[0] = 0xf;          // type (||||)
+    else if (ny==1) hitPattern[0] = hitPattern[1] = hitPattern[2] = hitPattern[3] = 0x1; // type (|)(|)(|)(|)
+    else if (ny==2) {
+      if (nz==2) hitPattern[0] = hitPattern[1] = 0x3; // tpye (||)(||)
+      else { 
+       hitPattern[0] = hitPattern[1] = hitPattern[2] = 0x1; // type (||)(|)(|) or (|)(||)(|)
+       hitPattern[gRandom->Rndm()>0.5 ? 0 : 1] |= 0x2; 
+      } 
+    }
+    else { 
+      hitPattern[0] = 0x7; 
+      hitPattern[1] = (gRandom->Rndm()>0.8) ? 0x1 : 0x2;  // type (|||) + (_|_) or (|||) + (|__) 
+    }
+  }
+  // more complex topologies
+  else {
+    UInt_t mask = 0xffffffff>>(32-ny);
+    for (int i=nz;i--;) hitPattern[i] = mask;
+    int toSup = ny*nz - npix;
+    int trial = toSup*5;
+    int colToTouch = nz-1; // at least 1 column should not be touched
+    while(toSup>0 && (trial--)>0) { // suppress random pixel until needed npix, ny and nz is obtained
+      int col = gRandom->Integer(nz);
+      if (hitPattern[col]==0x1) continue; // don't lose this column
+      if (hitPattern[col]==mask) {
+       if (!colToTouch) continue; // this is the only remaining column with ny rows hit
+       colToTouch--; // there are other columns of ny rows hit, may touch it
+      } 
+      hitPattern[col] >>= 1;
+      toSup--;
+    }
+    if (toSup) npix += toSup; // failed to suppress exact number of pixels 
+  }
+  //
+  cy = cz = 0; // get centroid
+  for (int col=nz;col--;) {
+    int npxr = 0;
+    for (int row=ny;row--;) if (hitPattern[col] & (0x1<<row)) {npxr++; cy+=(1+row);}
+    cz += npxr*(1+col);      
+  }
+  cz = cz/npix - 0.5;
+  cy = cy/npix - 0.5;
+  //
+  return (UInt_t*)&hitPattern[0];
+}
+
+//_________________________________________________________________________
+Int_t AliITSMultRecBg::PickClusterPrototype(Int_t lr, Int_t ladInStave, Int_t stave2avoid)
+{
+  // pick random cluster to use as a prototype for injection. It should come 
+  // from ladders at given Z belt and should not be from the stave2avoid
+  // pick random cluster to use as a prototype for injection. It should come 
+  // from ladders at given Z belt and should not be from the stave2avoid
+  static int tried = 0;
+  static int ladInStaveOrig = 0;
+  //
+  int ncl = fInjModuleTotClN[lr][ladInStave];
+  if (stave2avoid>=0) ncl -= fInjModuleClN[lr][ladInStave][stave2avoid];
+  if (ncl<1) {
+    int totLad = AliITSgeomTGeo::GetNDetectors(lr+1);
+    if (!tried) ladInStaveOrig = ladInStave; // before starting the resque solution, save the orig.ladder
+    if (++tried >= totLad) { // failed to find cluster avoiding a stave2avoid
+      tried = 0;
+      return PickClusterPrototype(lr,ladInStaveOrig,-1);
+    }
+    int useLad = ladInStave+1;
+    if (useLad>=AliITSgeomTGeo::GetNDetectors(lr+1)) useLad = 0;
+    return PickClusterPrototype(lr,useLad,stave2avoid); // look in the neigbouring ladder
+  }
+  //
+  int pick = gRandom->Integer(ncl);
+  int nst = AliITSgeomTGeo::GetNLadders(lr+1);
+  int stave = 0;
+  for (stave=0;stave<nst;stave++) {
+    if (stave==stave2avoid) continue;
+    if (pick<fInjModuleClN[lr][ladInStave][stave]) break;
+    pick -= fInjModuleClN[lr][ladInStave][stave];
+  }
+  //
+  tried = 0;
+  return fInjModuleClStart[lr][ladInStave][stave]+pick;
+}
+
+//_________________________________________________________________________
+Int_t AliITSMultRecBg::SearchInjTracklet(const Float_t *vtx)
+{
+  // reconstruct tracklets which may involve injected cluster
+  // fake arrays to be used for injected cluster in MultReco
+  Float_t clustersLayInj[kClNPar];
+  Int_t   detectorIndexClustersLayInj[1];
+  Bool_t  overlapFlagClustersLayInj[1];
+  UInt_t  usedClusLayInj[1];
+  //
+  Bool_t kUseOrig = kFALSE;//kTRUE;
+  if (kUseOrig) {
+    // to try with unused clusters
+    if ( fAssociations[fInjLr][fInjCurrTrial]>=0 ) return 0; // associated
+    float *origCl = GetClusterOfLayer(fInjLr,fInjCurrTrial);
+    for (int i=0;i<kClNPar;i++) clustersLayInj[i] = origCl[i];
+  }
+  else {
+    // >> fill cluster data: equivavlent of data fetched in AliITSMultReconstructor::LoadClusterArrays
+    detectorIndexClustersLayInj[0] = fInjCluster.GetDetectorIndex();
+    overlapFlagClustersLayInj[0]   = kFALSE;
+    usedClusLayInj[0]              = 0;
+    fInjCluster.GetGlobalXYZ( clustersLayInj );
+    for (int i=3;i--;) clustersLayInj[kClMC0+i] = fInjCluster.GetLabel(i);
+    ClusterPos2Angles(clustersLayInj, vtx); // convert to angles
+  }
+  //
+  // compare injected cluster with real ones
+  int partnerLr = 1 - fInjLr;
+
+  double bestChiUsed = fNStdDev*2, bestChiFree = fNStdDev*2;
+  int bestPartnerUsed=-1,bestPartnerFree=-1;
+  //
+  for (int icl=fNClustersLay[partnerLr];icl--;) {
+    Float_t *partnerCl = GetClusterOfLayer(partnerLr,icl);
+    Double_t dTheta = clustersLayInj[kClTh] - partnerCl[kClTh]; 
+    Double_t dPhi   = clustersLayInj[kClPh] - partnerCl[kClPh];
+    if (dPhi>TMath::Pi()) dPhi=2.*TMath::Pi()-dPhi;     // take into account boundary condition
+    Float_t d = CalcDist(dPhi,dTheta, fInjLr==0 ? clustersLayInj[kClTh]:partnerCl[kClTh]);
+    if (d>fNStdDev) continue;
+    //
+    int competitor = fAssociations[partnerLr][icl]; // is the cluster of partner layer already used by some tracklet?
+    if (competitor>=0) { if (d<bestChiUsed && d < fMinDists[ partnerLr==1 ? icl : competitor ]) { bestChiUsed = d; bestPartnerUsed = icl; } }
+    else               { if (d<bestChiFree) { bestChiFree = d; bestPartnerFree = icl; } }
+  }
+  //
+  int winner = -1;
+  //
+  if (bestPartnerUsed>=0) {
+    if (bestPartnerFree>=0) { winner = bestChiFree<bestChiUsed ? bestPartnerFree : bestPartnerUsed;}  // shall we subtract old real tracklet if the winner cluster is used one?
+    else { winner = bestPartnerUsed; }
+  }
+  else winner = bestPartnerFree;
+
+  //  printf("%d\n",winner);
+
+  if (winner<0) return 0;
+  //
+  int nCurrTr = GetNInjSuccsess();
+  if (nCurrTr >= fInjBuffer.GetSize()/kTrNPar) 
+    fInjBuffer.Set(nCurrTr*2*kTrNPar);
+  //
+  Float_t *tracklet = fInjBuffer.GetArray() + nCurrTr*kTrNPar;
+  Float_t *clPar1=0,*clPar2=0;
+  if (fInjLr) {
+    clPar1 = GetClusterOfLayer(partnerLr,winner);
+    clPar2 = clustersLayInj;
+    tracklet[kClID1] = winner;
+    tracklet[kClID2] = -1;
+  }
+  else {
+    clPar2 = GetClusterOfLayer(partnerLr,winner);
+    clPar1 = clustersLayInj;
+    tracklet[kClID1] = -1;
+    tracklet[kClID2] =  winner;
+  }
+  tracklet[kTrTheta] = clPar1[kClTh];    // use the theta from the clusters in the first layer
+  tracklet[kTrPhi]   = clPar1[kClPh];    // use the phi from the clusters in the first layer
+  tracklet[kTrDPhi]  = clPar1[kClPh] - clPar2[kClPh];  // store the difference between phi1 and phi2 
+  //
+  // define dphi in the range [0,pi] with proper sign (track charge correlated)
+  if (tracklet[kTrDPhi] > TMath::Pi())   tracklet[kTrDPhi] = tracklet[kTrDPhi]-2.*TMath::Pi();
+  if (tracklet[kTrDPhi] < -TMath::Pi())  tracklet[kTrDPhi] = tracklet[kTrDPhi]+2.*TMath::Pi();
+  tracklet[kTrDTheta] = clPar1[kClTh] - clPar2[kClTh]; // store the theta1-theta2
+  tracklet[kTrLab1] = clPar1[kClMC0];
+  tracklet[kTrLab2] = clPar2[kClMC0];
+  //
+  //  printf("Got Tracklet from lr%d: %f %f\n",fInjLr,fInjNSuccess[0],fInjNSuccess[1]);
+  //
+  return 1;
+  // 
+}
+
+//_________________________________________________________________________
+void AliITSMultRecBg::GenInjBgSample(TTree* treeRP, Float_t *vtx)
+{
+  // generate a sample of tracklets from injected bg
+  //
+  SetTreeRP(treeRP);
+  InitInjBg();
+  if (!PrepareInjBgGenerator(vtx)) return;
+  //
+  fInjNSuccess[0] = fInjNSuccess[1] = 0;
+  for (int i=0;i<2;i++) {
+    fInjLr = i;
+    fInjNTrials[i] = TMath::Max(1,int(fInjScale*fNClustersLay[i]));
+    for (fInjCurrTrial=0;fInjCurrTrial<fInjNTrials[i];fInjCurrTrial++) {
+      if (!GenClusterToInject()) break;
+      fInjNSuccess[i] += SearchInjTracklet(vtx);
+    }
+  }
+  printf("Successes/Trials: %d/%d %d/%d\n",fInjNSuccess[0],fInjNTrials[0],fInjNSuccess[1],fInjNTrials[1]);
+  //  
+}
+
diff --git a/PWG0/multVScentPbPb/AliITSMultRecBg.h b/PWG0/multVScentPbPb/AliITSMultRecBg.h
new file mode 100755 (executable)
index 0000000..0b48e93
--- /dev/null
@@ -0,0 +1,97 @@
+#ifndef ALIITSMULTRECBG_H
+#define ALIITSMULTRECBG_H
+
+class TH2F;
+class TTree;
+#include <TArrayF.h>
+#include "../ITS/AliITSMultReconstructor.h"
+#include "../ITS/AliITSRecPoint.h"
+
+
+class AliITSMultRecBg : public AliITSMultReconstructor 
+{
+ public:
+  enum {kData,  // normal reconstruction
+       kBgRot, // bg with rotation
+       kBgInj, // bg with injection
+       kBgMix  // bg with mixing
+  };
+  //
+  AliITSMultRecBg();
+  virtual ~AliITSMultRecBg();
+  //
+  void    Run(TTree* tree, Float_t* vtx, TTree* treeMix=0);
+  //
+  void    SetRecType(UInt_t m=kData)                                  {fRecType = m;}
+  Int_t   GetRecType()                                          const {return fRecType;}
+  //
+  void    SetInjScale(Float_t s=1.)                  {fInjScale = s>0? s:1.;}
+  Int_t   GetNInjTrials(Int_t lr=-1)           const {return lr<0 ? fInjNTrials[0]+fInjNTrials[1] : fInjNTrials[lr];}
+  Int_t   GetNInjSuccsess(Int_t lr=-1)         const {return lr<0 ? fInjNSuccess[0]+fInjNSuccess[1] : fInjNSuccess[lr];}
+  //
+  void    Print(Option_t *opt=0)               const {AliITSMultReconstructor::Print(opt);}
+  //
+ protected:
+  virtual void CreateMultiplicityObject();
+  //
+  //     Injection stuff
+  void    GenInjBgSample(TTree* treeRP, Float_t *vtx);
+  Bool_t  PrepareInjBgGenerator(Float_t *vtx);
+  void    InitInjBg();
+  Bool_t  GenClusterToInject();
+  void    PlaceInjCluster();
+  Int_t   PickClusterPrototype(Int_t lr, Int_t ladInStave, Int_t stave2avoid);
+  UInt_t* GenClusterPattern(Int_t &npix, Int_t &ny, Int_t &nz, Float_t cy,Float_t &cz);
+  Int_t   SearchInjTracklet(const Float_t *vtx);
+  Int_t   GetPixelBitC(int stave, int chip,  int col, int row) const {return row+((col+((chip+stave*20)<<5))<<8);} // row + (col+ (chip + stave*20)*32)*256;
+  Int_t   GetPixelBitL(int stave, int ladder,int col, int row) const {return row+((col+(ladder+(stave<<2))*32*5)<<8);} // row + (col + (ladder + stave*4)*32*5)*256
+  void    ExtractPixelL(int id, int &stave, int &ladder, int &col, int &row);
+
+
+ protected:
+  enum {kInjFakeLabel=-999};
+  enum {kInjMaxNY=10, kInjMaxNZ=8};
+  //
+  Int_t fRecType;
+  //
+  // method specific members
+  //
+  // injection
+  Int_t    fInjLr;                            // injection layer
+  Int_t    fInjStave;                         // injection stave (counted from layer)
+  Int_t    fInjModule;                        // injection module (counted from layer)
+  Int_t    fInjModInStave;                    // injection module (counted from stave)
+  Double_t fInjX;                             // injection local X
+  Double_t fInjZ;                             // injection local Z
+  Int_t    fInjHitsN;                         // number of injected pixels
+  Int_t    fInjHits[256];                     // bit ids of injected pixels (GetPixelBitL/ExtractPixelL)
+  Int_t*   fAssociations[2];                  //! associations [0]: from L1 to L2, [1]: L2 to L1
+  Float_t  fInjScale;                         // scaling factor for generation
+  Int_t    fInjCurrTrial;                     // current trial id
+  Int_t    fInjNTrials[2];                    // number of injections per event for each layer
+  Int_t    fInjNSuccess[2];                   // number of successful injected tracklet generation
+  AliITSRecPoint fInjCluster;                 // fake cluster to inject
+  TH2F*    fInjSPDOcc[2];                     // occupancy in 2 SPD layers
+  TBits*   fInjSPDPatt[2];                    // occupancy pattern accounting for cluster types
+  Int_t*   fInjModuleClStart[2][4];           //! start of clusters for modules in given Z belt of each stave
+  Int_t*   fInjModuleClN[2][4];               //! number of clusters for modules in given Z belt of each stave
+  Int_t    fInjModuleTotClN[2][4];            // total number of clusters for modules in given Z belt
+  TArrayF  fInjBuffer;                        //! buffer for bg tracklets
+  //
+  ClassDef(AliITSMultRecBg,0)
+};
+
+
+inline void AliITSMultRecBg::ExtractPixelL(int id, int &stave, int &ladder, int &col, int &row) 
+{
+  enum {kNRow=256,kNCol=32*5,kNLadd=4};
+  row = id%kNRow;
+  id /= kNRow;
+  col = id%kNCol;
+  id /= kNCol;
+  ladder = id%kNLadd;
+  stave = id/kNLadd;
+}
+
+
+#endif
diff --git a/PWG0/multVScentPbPb/AliTaskGlobVar.cxx b/PWG0/multVScentPbPb/AliTaskGlobVar.cxx
new file mode 100755 (executable)
index 0000000..5d11e91
--- /dev/null
@@ -0,0 +1,1970 @@
+/*************************************************************************
+* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  * 
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Analysis task to extract global variables to the tree                 //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TChain.h>
+#include <TFile.h>
+#include <TString.h>
+#include <TTree.h>
+#include <TList.h>
+#include <TObjArray.h>
+#include "AliAnalysisManager.h"
+#include "AliMultiplicity.h"
+#include "AliESDEvent.h"  
+#include "AliESDInputHandler.h"
+#include "AliESDVZERO.h"
+#include "AliESDZDC.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "AliLog.h"
+#include "AliPhysicsSelection.h"
+#include "AliESDCentrality.h" 
+#include "AliESDtrackCuts.h"
+#include "AliTaskGlobVar.h"
+#include "AliGenEventHeader.h"
+#include "AliGenHijingEventHeader.h"
+#include "AliGenDPMjetEventHeader.h"
+
+
+ClassImp(AliTaskGlobVar)
+
+
+GloVars_t globVars;
+
+//________________________________________________________________________
+AliTaskGlobVar::AliTaskGlobVar(const char *name) 
+  : AliAnalysisTaskSE(name), 
+    //
+    fUseMC(kFALSE),
+    fOutput(0), 
+    fOutTree(0),
+    fTrackCuts(0),
+    fTrackCuts1(0)
+{
+  // Constructor
+  DefineOutput(1, TList::Class());
+  //
+}
+
+//________________________________________________________________________
+AliTaskGlobVar::~AliTaskGlobVar()
+{
+  // Destructor
+  // histograms are in the output list and deleted when the output
+  // list is deleted by the TSelector dtor
+  if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {  //RRR
+    printf("Deleteing output\n");
+    delete fOutput;
+    fOutput = 0;
+  }
+  //
+}
+
+//________________________________________________________________________
+void AliTaskGlobVar::UserCreateOutputObjects() 
+{
+  //
+  fOutput = new TList();
+  fOutput->SetOwner(); 
+  //
+  fOutTree = new TTree("globTree","globTree");
+  fOutTree->Branch("g",&globVars,"runID/I:timeStamp/i:zdcNA/F:zdcPA/F:zdcNC/F:zdcPC/F:zem1/F:zem2/F:zvSPD/F:zvTPC/F:chunk/S:flags/S"
+                  ":spd1/S:spd2/S:ncontSPDV/S:ncontTPCV/S:nTrTPC/S:nTrTPCITS/S:nTracklets/S:v0A/S:v0C/S:v0Corr/S", 16777216);
+
+  if (fUseMC) {
+    fOutTree->Branch("gmc",&globVars.mcZV,"mcZV/F:mcdNdEta/S:mcNPart/S:mcNBColl/S", 16777216);
+  }
+  fOutput->Add(fOutTree);
+  //
+  //  fTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+  fTrackCuts  = CreatedNdPtTrackCuts(23);
+  fTrackCuts->SetEtaRange(-0.8,0.8);
+  fTrackCuts1 = CreatedNdPtTrackCuts(72);
+  fTrackCuts1->SetEtaRange(-0.8,0.8);
+  //
+  PostData(1, fOutput);
+  printf("CreatingXXX\n");
+  //
+}
+
+//________________________________________________________________________
+void AliTaskGlobVar::UserExec(Option_t *) 
+{
+  // Main loop
+  //
+  AliAnalysisManager* anMan = AliAnalysisManager::GetAnalysisManager();
+  AliESDInputHandler *hand = (AliESDInputHandler*)anMan->GetInputEventHandler();
+  if (!hand) { printf("No ESD handler\n"); return; }
+  AliESDEvent *esd  = hand->GetEvent();
+  if (!esd) { printf("No AliESDEvent\n"); return; }
+  //
+  if (!fUseMC && !ZDCTimeTrigger(esd)) return;
+  //
+  const AliESDVertex* vtxESD = esd->GetPrimaryVertexSPD();
+  Bool_t vtxOK = kTRUE;
+  if (vtxESD->GetNContributors()<1) vtxOK = kFALSE; //return;
+  if (vtxESD->GetDispersion()>0.04) vtxOK = kFALSE; //return;
+  if (vtxESD->GetZRes()>0.25) vtxOK = kFALSE; //return;
+  const AliMultiplicity* multESD  = esd->GetMultiplicity();
+  const AliESDVertex*   vtxESDTPC = esd->GetPrimaryVertexTPC();
+  //  if (vtxESDTPC->GetNContributors()<1) return;
+  //  if (vtxESDTPC->GetNContributors()<(-10.+0.25*multESD->GetNumberOfITSClusters(0))) return;
+  //
+  globVars.runID = esd->GetRunNumber();
+  TString rid = "";
+  rid +=  globVars.runID;
+  TString flname        = hand->GetTree()->GetCurrentFile()->GetName();
+  globVars.chunk        = 0;
+  int id = 0;
+  while ( (id=flname.Index(rid))>=0 ) flname = flname.Data()+id+rid.Length();
+  id = flname.First('.');
+  if (id>=0) {
+    flname = flname.Data() + id+1;
+    globVars.chunk = (Short_t)flname.Atoi();
+  }
+  //  printf("%d %s\n",globVars.chunk,hand->GetTree()->GetCurrentFile()->GetName());
+  //
+  globVars.timeStamp    = esd->GetTimeStamp();
+  globVars.timeStamp    = esd->GetTimeStamp();
+  globVars.zvSPD        = vtxESD->GetZ(); 
+  globVars.zvTPC        = vtxESDTPC->GetZ(); 
+  globVars.ncontSPDV = (Short_t)vtxESD->GetNContributors();
+  globVars.ncontTPCV = (Short_t)vtxESDTPC->GetNContributors();
+  //  globVars.nTrTPC     = fTrackCuts ? (Short_t)fTrackCuts->GetReferenceMultiplicity(esd,kTRUE):-1;
+  globVars.nTrTPC       = fTrackCuts  ? (Short_t)fTrackCuts->CountAcceptedTracks(esd):-1;
+  globVars.nTrTPCITS    = fTrackCuts1 ? (Short_t)fTrackCuts1->CountAcceptedTracks(esd):-1;
+  globVars.nTracklets = multESD->GetNumberOfTracklets();
+  //
+  AliESDVZERO* esdV0 = esd->GetVZEROData();
+  if (esdV0) {
+    globVars.v0A = (Short_t)esdV0->GetMTotV0A();
+    globVars.v0C = (Short_t)esdV0->GetMTotV0C();
+  }
+  else globVars.v0A = globVars.v0C = 0;
+  //
+  globVars.spd1 = (Short_t)multESD->GetNumberOfITSClusters(0);
+  globVars.spd2 = (Short_t)multESD->GetNumberOfITSClusters(1);
+  //
+  float v0Corr,v0CorrR;
+  v0Corr = GetCorrV0(esd,v0CorrR);
+  globVars.v0Corr = (Short_t)v0Corr;
+  //  globVars.v0CorrResc = (Short_t)v0CorrR;
+
+  //---------------------------------------------
+  AliESDZDC *esdZDC = esd->GetESDZDC();
+  // --- ZDC offline trigger ---
+  // Returns if ZDC triggered, based on TDC information
+  Bool_t tdc[32] = {kFALSE};
+  for(Int_t itdc=0; itdc<32; itdc++){
+    for(Int_t i=0; i<4; i++){
+      if (0.025*esdZDC->GetZDCTDCData(itdc, i) != 0){
+       tdc[itdc] = kTRUE;
+      }
+    }
+  }
+  globVars.flags = 0;
+  if ( tdc[12] ) globVars.flags |= GloVars_t::kTDCNA; //  Bool_t zdcNA = tdc[12];
+  if ( tdc[10] ) globVars.flags |= GloVars_t::kTDCNC; //  Bool_t zdcNC = tdc[10];
+  if ( tdc[13] ) globVars.flags |= GloVars_t::kTDCPA; //  Bool_t zdcPA = tdc[13];
+  if ( tdc[11] ) globVars.flags |= GloVars_t::kTDCPC; //  Bool_t zdcPC = tdc[11];
+  if ( vtxOK   ) globVars.flags |= GloVars_t::kSPDVTXOK;
+  //
+  globVars.zdcNC = (Float_t) (esdZDC->GetZDCN1Energy()) /8.;
+  globVars.zdcPC = (Float_t) (esdZDC->GetZDCP1Energy()) /8.;
+  globVars.zdcNA = (Float_t) (esdZDC->GetZDCN2Energy()) /8.;
+  globVars.zdcPA = (Float_t) (esdZDC->GetZDCP2Energy()) /8.;
+  globVars.zem1  = (Float_t) (esdZDC->GetZDCEMEnergy(0)) /8.;
+  globVars.zem2  = (Float_t) (esdZDC->GetZDCEMEnergy(1)) /8.;
+  //-----------------------------------------------
+  //
+  // ---------------------- MC ONLY -------------------------------
+  AliMCEventHandler* eventHandler = (AliMCEventHandler*)anMan->GetMCtruthEventHandler();
+  AliStack*    stack=0;
+  AliMCEvent*  mcEvent=0;
+  globVars.mcdNdEta = 0;
+  globVars.mcNPart  = 0;
+  globVars.mcNBColl = 0;
+  if (fUseMC && eventHandler && (mcEvent=eventHandler->MCEvent()) && (stack=mcEvent->Stack())) {
+    int ntr = stack->GetNtrack();
+    for (int itr=ntr;itr--;) {
+      if (!stack->IsPhysicalPrimary(itr)) continue;
+      AliMCParticle *part  = (AliMCParticle*)mcEvent->GetTrack(itr);
+      if (!part || !part->Charge()) continue;
+      Float_t eta = part->Eta();
+      if (TMath::Abs(eta)>0.5) continue;
+      globVars.mcdNdEta++;
+    }
+    //
+    AliGenEventHeader* mcGenH = mcEvent->GenEventHeader();
+    if (mcGenH->InheritsFrom(AliGenHijingEventHeader::Class())) {
+      AliGenHijingEventHeader* hHijing = (AliGenHijingEventHeader*)mcGenH;
+      globVars.mcNPart  = (hHijing->ProjectileParticipants()+hHijing->TargetParticipants())/2.;
+      globVars.mcNBColl = hHijing->NN()+hHijing->NNw()+hHijing->NwN()+hHijing->NwNw();
+    }
+    else if (mcGenH->InheritsFrom(AliGenDPMjetEventHeader::Class())) {
+      AliGenDPMjetEventHeader* hDpmJet = (AliGenDPMjetEventHeader*)mcGenH;
+      globVars.mcNPart  = (hDpmJet->ProjectileParticipants()+hDpmJet->TargetParticipants())/2.;
+      globVars.mcNBColl = hDpmJet->NN()+hDpmJet->NNw()+hDpmJet->NwN()+hDpmJet->NwNw();
+    }
+    else {} // unknown generator
+    //
+    TArrayF vtxMC;
+    mcGenH->PrimaryVertex(vtxMC);
+    globVars.mcZV = vtxMC[2];
+  }
+  //
+  fOutTree->Fill();
+  //
+}      
+//________________________________________________________________________
+void AliTaskGlobVar::Terminate(Option_t *) 
+{
+  Printf("Terminating...");
+  //  AliAnalysisTaskSE::Terminate();
+}
+
+
+//________________________________________________________________________
+Float_t AliTaskGlobVar::GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const
+{
+  // correct V0 non-linearity, prepare a version rescaled to SPD2 corr
+  const Double_t par0[64] = { 6.71e-02 , 6.86e-02 , 7.06e-02 , 6.32e-02 , 
+                             5.91e-02 , 6.07e-02 , 5.78e-02 , 5.73e-02 , 5.91e-02 , 6.22e-02 , 
+                             5.90e-02 , 6.11e-02 , 5.55e-02 , 5.29e-02 , 5.19e-02 , 5.56e-02 , 
+                             6.25e-02 , 7.03e-02 , 5.64e-02 , 5.81e-02 , 4.57e-02 , 5.30e-02 , 
+                             5.13e-02 , 6.43e-02 , 6.27e-02 , 6.48e-02 , 6.07e-02 , 1.01e-01 , 
+                             6.68e-02 , 7.16e-02 , 6.36e-02 , 5.95e-02 , 2.52e-02 , 2.82e-02 , 
+                             2.56e-02 , 2.86e-02 , 2.82e-02 , 2.10e-02 , 2.13e-02 , 2.32e-02 , 
+                             2.75e-02 , 4.34e-02 , 3.78e-02 , 4.52e-02 , 4.11e-02 , 3.89e-02 , 
+                             4.10e-02 , 3.73e-02 , 4.51e-02 , 5.07e-02 , 5.42e-02 , 4.74e-02 , 
+                             4.33e-02 , 4.44e-02 , 4.64e-02 , 3.01e-02 , 6.38e-02 , 5.26e-02 , 
+                             4.99e-02 , 5.26e-02 , 5.47e-02 , 3.84e-02 , 5.00e-02 , 5.20e-02 };
+  const Double_t par1[64] = { -6.68e-05 , -7.78e-05 , -6.88e-05 , -5.92e-05 , 
+                             -2.43e-05 , -3.54e-05 , -2.91e-05 , -1.99e-05 , -1.40e-05 , -4.01e-05 , 
+                             -2.29e-05 , -3.68e-05 , -2.53e-05 , -2.44e-06 , -9.22e-06 , -1.51e-05 , 
+                             -2.80e-05 , -2.34e-05 , -1.72e-05 , -1.81e-05 , -1.29e-05 , -2.65e-05 , 
+                             -1.61e-05 , -2.86e-05 , -1.74e-05 , -4.23e-05 , -3.41e-05 , -1.05e-04 , 
+                             -2.76e-05 , -4.71e-05 , -3.06e-05 , -2.32e-05 , -1.55e-06 , 2.15e-05 , 
+                             1.40e-05 , 2.16e-05 , 1.21e-05 , 3.05e-06 , 1.67e-05 , -3.84e-06 , 
+                             3.09e-06 , 1.50e-05 , 3.47e-06 , 4.87e-06 , -3.71e-07 , -1.75e-06 , 
+                             -1.80e-06 , 9.99e-06 , -6.46e-06 , -4.91e-06 , 1.33e-05 , -2.52e-07 , 
+                             -3.85e-06 , 4.94e-06 , -2.48e-07 , -1.20e-05 , 2.07e-06 , 6.12e-06 , 
+                             -1.18e-06 , 4.54e-06 , -1.54e-05 , -1.25e-05 , 1.46e-06 , -6.67e-06 };
+  const Double_t par2[64] = { 1.29e-08 , 1.51e-08 , 1.43e-08 , 1.11e-08 , 
+                             5.04e-09 , 6.99e-09 , 5.58e-09 , 4.15e-09 , 4.00e-09 , 8.22e-09 , 
+                             4.97e-09 , 7.66e-09 , 4.91e-09 , 1.10e-09 , 2.64e-09 , 3.64e-09 , 
+                             5.76e-09 , 5.46e-09 , 3.38e-09 , 3.47e-09 , 2.43e-09 , 4.13e-09 , 
+                             2.80e-09 , 5.80e-09 , 3.86e-09 , 7.46e-09 , 5.98e-09 , 2.58e-08 , 
+                             5.50e-09 , 8.72e-09 , 5.23e-09 , 4.37e-09 , 2.33e-09 , -6.01e-10 , 
+                             3.99e-11 , -2.02e-10 , 7.67e-10 , 2.03e-09 , 1.17e-10 , 2.56e-09 , 
+                             1.16e-09 , -4.75e-10 , 1.28e-09 , 1.23e-09 , 1.62e-09 , 1.61e-09 , 
+                             1.93e-09 , 2.97e-10 , 2.21e-09 , 2.16e-09 , 5.22e-10 , 1.03e-09 , 
+                             1.56e-09 , 5.00e-10 , 1.01e-09 , 2.93e-09 , 1.05e-09 , 9.96e-11 , 
+                             1.21e-09 , 7.45e-10 , 3.07e-09 , 2.31e-09 , 6.70e-10 , 1.89e-09 };
+  //
+  Float_t multCorr = 0;
+  Float_t multCorr2 = 0;
+  Float_t multChCorr[64];
+  AliESDVZERO* esdV0 = esd->GetVZEROData();
+  for(Int_t i = 0; i < 64; ++i) {
+    Double_t b = (esdV0->GetMultiplicity(i)*par1[i]-par0[i]);
+    Double_t s = (b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i));
+    Double_t n;
+    if (s<0) {
+      printf("FPE %d %.2f %.2f %.2e\n",i,esdV0->GetMultiplicity(i),b,(b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i)));
+      n = -b;
+    }
+    else {
+      n = (-b + TMath::Sqrt(s));
+    }
+    multChCorr[i] = 2.*esdV0->GetMultiplicity(i)/n*par0[i];
+    multCorr += multChCorr[i];
+    multCorr2 += (multChCorr[i]/par0[i]/64.);
+  }
+  v0CorrResc =  multCorr2;
+  return multCorr;
+}
+
+//_________________________________________________________________
+Bool_t AliTaskGlobVar::ZDCTimeTrigger(const AliESDEvent *aEsd) const
+{
+  // This method implements a selection
+  // based on the timing in both sides of zdcN
+  // It can be used in order to eliminate
+  // parasitic collisions
+  Bool_t zdcAccept = kFALSE;
+
+  AliESDZDC *esdZDC = aEsd->GetESDZDC();
+
+  const Float_t refSum = -568.5;
+  const Float_t refDelta = -2.1;
+  const Float_t sigmaSum = 3.25;
+  const Float_t sigmaDelta = 2.25;
+  for(Int_t i = 0; i < 4; ++i) {
+    if (esdZDC->GetZDCTDCData(10,i) != 0) {
+      Float_t tdcC = 0.025*(esdZDC->GetZDCTDCData(10,i)-esdZDC->GetZDCTDCData(14,i)); 
+      for(Int_t j = 0; j < 4; ++j) {
+       if (esdZDC->GetZDCTDCData(12,j) != 0) {
+         Float_t tdcA = 0.025*(esdZDC->GetZDCTDCData(12,j)-esdZDC->GetZDCTDCData(14,j));
+         if (((tdcC-tdcA-refDelta)*(tdcC-tdcA-refDelta)/(sigmaDelta*sigmaDelta) +
+              (tdcC+tdcA-refSum)*(tdcC+tdcA-refSum)/(sigmaSum*sigmaSum))< 1.0)
+           zdcAccept = kTRUE;
+       }
+      }
+    }
+  }
+  return zdcAccept;
+}
+
+
+AliESDtrackCuts* AliTaskGlobVar::CreatedNdPtTrackCuts(Int_t cutMode, Bool_t fieldOn)
+{
+  // copy of PWG0/dNdPt/macros/CreatedNdPtTrackCuts.C
+  //
+  AliESDtrackCuts* esdTrackCuts = new AliESDtrackCuts("AliESDtrackCuts");
+
+
+  Double_t cov1, cov2, cov3, cov4, cov5;
+  Double_t nSigma;
+  Double_t maxDCAtoVertex, maxDCAtoVertexXY, maxDCAtoVertexZ;
+  Int_t minNClustersTPC;
+  Double_t maxChi2PerClusterTPC;
+  Double_t minPt, maxPt;
+  TString tag;
+
+  // default cuts for ITS+TPC
+  if (cutMode == 0) 
+  {
+    cov1 = 2;
+    cov2 = 2;
+    cov3 = 0.5;
+    cov4 = 0.5;
+    cov5 = 2;
+    nSigma = 3;
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.5;
+
+    esdTrackCuts->SetMaxCovDiagonalElements(cov1, cov2, cov3, cov4, cov5);
+    //    esdTrackCuts->SetMinNsigmaToVertex(nSigma);
+    esdTrackCuts->SetRequireSigmaToVertex(kTRUE);
+    esdTrackCuts->SetRequireTPCRefit(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "Global tracking";
+  }
+
+  // TPC-only cuts (vertex n sigma cut)
+  if (cutMode == 1) 
+  {
+    // beta cuts (still under investigation)
+    //cov1 = 4;
+    //cov2 = 4;
+    cov1 = 2;
+    cov2 = 2;
+    cov3 = 0.5;
+    cov4 = 0.5;
+    cov5 = 2;
+    nSigma = 4;
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.5;
+
+    esdTrackCuts->SetMaxCovDiagonalElements(cov1, cov2, cov3, cov4, cov5);
+    //    esdTrackCuts->SetMinNsigmaToVertex(nSigma);
+    esdTrackCuts->SetRequireSigmaToVertex(kTRUE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only cuts (vertex maxDCAtoVertex cut)
+  if (cutMode == 2) 
+  {
+    // beta cuts (still under investigation)
+    maxDCAtoVertex = 3.0; // cm
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.5;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);    
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);    
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only no vertex cuts
+  if (cutMode == 3) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.5;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only no cuts at all 
+  if (cutMode == 4) 
+  {
+
+    // beta cuts (still under investigation)
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only no kink removal no chi2 
+  if (cutMode == 5) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    //maxChi2PerClusterTPC = 3.5;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    //esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only no kink removal 
+  if (cutMode == 6) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.5;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only no kink removal no minNClustersTPC 
+  if (cutMode == 7) 
+  {
+    // beta cuts (still under investigation)
+    //minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.5;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+  // TPC-only no kink removal no minNClustersTPC 
+  if (cutMode == 8) 
+  {
+    // beta cuts (still under investigation)
+    //minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.5;
+    maxDCAtoVertex = 3.0; // cm
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);    
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);    
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only no kink removal no minNClustersTPC no maxChi2PerClusterTPC
+  if (cutMode == 9) 
+  {
+    // beta cuts (still under investigation)
+    //minNClustersTPC = 50;
+    //maxChi2PerClusterTPC = 3.5;
+    maxDCAtoVertex = 3.0; // cm
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);    
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);    
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    //esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (loose cuts, absolute DCA cut) 
+  if (cutMode == 10) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertex = 2.8; // cm
+    minPt=0.15;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertex);    
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertex);    
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+
+  // TPC-only (loose cuts, no DCA cut) 
+  if (cutMode == 11) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 1.e10; // cm
+    maxDCAtoVertexZ  = 1.e10; // cm
+    minPt=0.15;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (standard cuts, no DCA cut) 
+  if (cutMode == 12) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 96;
+    maxChi2PerClusterTPC = 3.5;
+    maxDCAtoVertexXY = 1.e10; // cm
+    maxDCAtoVertexZ  = 1.e10; // cm
+    minPt=0.2;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (tight cuts, no DCA cut) 
+  if (cutMode == 13) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 120;
+    maxChi2PerClusterTPC = 3.5;
+    maxDCAtoVertexXY = 1.e10; // cm
+    maxDCAtoVertexZ  = 1.e10; // cm
+    minPt=0.3;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (loose cuts, no pt cut) 
+  if (cutMode == 14) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 1.e10; // cm
+    maxDCAtoVertexZ  = 1.e10; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (standard cuts, no pt cut) 
+  if (cutMode == 15) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 96;
+    maxChi2PerClusterTPC = 3.5;
+    maxDCAtoVertexXY = 1.e10; // cm
+    maxDCAtoVertexZ  = 1.e10; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (tight cuts, no pt cuts) 
+  if (cutMode == 16) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 120;
+    maxChi2PerClusterTPC = 3.5;
+    maxDCAtoVertexXY = 1.e10; // cm
+    maxDCAtoVertexZ  = 1.e10; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+  // TPC-only (loose cuts)
+  if (cutMode == 17) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    //maxDCAtoVertexXY = 2.4; // cm
+    //maxDCAtoVertexZ  = 3.2; // cm
+    maxDCAtoVertexXY = 1.6; // cm
+    maxDCAtoVertexZ  = 2.1; // cm
+    minPt=0.15;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (standard cuts)
+  if (cutMode == 18) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 96;
+    maxChi2PerClusterTPC = 3.5;
+    //maxDCAtoVertexXY = 2.4; // cm
+    //maxDCAtoVertexZ  = 3.2; // cm
+    maxDCAtoVertexXY = 1.4; // cm
+    maxDCAtoVertexZ  = 1.8; // cm
+    minPt=0.2;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+ // TPC-only (tight cuts)
+  if (cutMode == 19) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 120;
+    maxChi2PerClusterTPC = 3.0;
+    //maxDCAtoVertexXY = 2.4; // cm
+    //maxDCAtoVertexZ  = 3.2; // cm
+    maxDCAtoVertexXY = 1.4; // cm
+    maxDCAtoVertexZ  = 1.8; // cm
+    minPt=0.3;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (arb. cuts, kink cuts included)
+  if (cutMode == 20) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 1.e10;
+    maxDCAtoVertexXY = 3.0; // cm
+    maxDCAtoVertexZ  = 3.0; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (arb. cuts, kink cuts excluded)
+  if (cutMode == 21) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 1.e10;
+    maxDCAtoVertexXY = 3.0; // cm
+    maxDCAtoVertexZ  = 3.0; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (arb. cuts, kink cuts excluded, no chi2, no DCA)
+  if (cutMode == 22) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 1.e10;
+    maxDCAtoVertexXY = 1.e10; // cm
+    maxDCAtoVertexZ  = 1.e10; // cm
+    minPt=0.15;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only 
+  if (cutMode == 23) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 70;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetRequireITSRefit(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    //esdTrackCuts->SetPtRange(minPt,maxPt);
+    //esdTrackCuts->SetEtaRange(minEta,maxEta);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only (no pt cut, no eta cut)
+  if (cutMode == 24) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  //
+  // systematic errors DCA cut studies
+  //
+  // TPC-only
+  if (cutMode == 25) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 1.4; // cm
+    maxDCAtoVertexZ  = 2.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 26) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 1.6; // cm
+    maxDCAtoVertexZ  = 2.4; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  //
+  // systematic errors cut studies
+  //
+  // TPC-only
+  if (cutMode == 27) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 1.8; // cm
+    maxDCAtoVertexZ  = 2.6; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 28) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.0; // cm
+    maxDCAtoVertexZ  = 2.8; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 29) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.2; // cm
+    maxDCAtoVertexZ  = 3.0; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 30) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 31) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.6; // cm
+    maxDCAtoVertexZ  = 3.4; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+
+  if (cutMode == 32) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.8; // cm
+    maxDCAtoVertexZ  = 3.6; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 33) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 3.0; // cm
+    maxDCAtoVertexZ  = 3.8; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 34) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 3.2; // cm
+    maxDCAtoVertexZ  = 4.0; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 35) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 3.4; // cm
+    maxDCAtoVertexZ  = 4.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+//
+// cut stability systematics
+//
+
+  if (cutMode == 36) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 70;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+ if (cutMode == 37) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 90;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 38) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 3.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 39) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 5.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 40) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 1.4; // cm
+    maxDCAtoVertexZ  = 2.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 41) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 3.4; // cm
+    maxDCAtoVertexZ  = 4.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+
+  if (cutMode == 42) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    minPt=0.0;
+    maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    //esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    esdTrackCuts->SetPtRange(minPt,maxPt);
+
+    tag = "TPC-only tracking";
+  }
+  // test
+  if (cutMode == 43) 
+  {
+    // beta cuts (still under investigation)
+    minNClustersTPC = 50;
+    maxChi2PerClusterTPC = 4.0;
+    //maxDCAtoVertexXY = 2.4; // cm
+    //maxDCAtoVertexZ  = 3.2; // cm
+    //minPt=0.15;
+    //maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    //esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    //esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    //esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    //esdTrackCuts->SetPtRange(minPt,maxPt);
+    //esdTrackCuts->SetEtaRange(minEta,maxEta);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-only + pt cut + eta cut 
+  if (cutMode == 45) 
+  {
+    // beta cuts (still under investigation)
+    //minNClustersTPC = 50;
+    //maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 2.4; // cm
+    maxDCAtoVertexZ  = 3.2; // cm
+    //minPt=0.15;
+    //maxPt=1.e10;
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    //esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    //esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+    //esdTrackCuts->SetPtRange(minPt,maxPt);
+    //esdTrackCuts->SetEtaRange(minEta,maxEta);
+
+    tag = "TPC-only tracking";
+  }
+
+  // TPC-tracks + SPD point + ITS refit
+  if (cutMode == 50) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    //Double_t maxEtaInAcc=0.8;
+    Double_t maxdcaxyITSTPC=0.2;
+    Double_t maxdcazITSTPC=1.e9;
+
+    esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //esdTrackCuts->SetEtaRange(-maxEtaInAcc,maxEtaInAcc);
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster";
+  }
+
+  // TPC-tracks + SPD point + ITS refit
+  if (cutMode == 60) 
+  {
+    Int_t    minclsITS=4;
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcaxyITSTPC=0.2;
+    Double_t maxdcazITSTPC=1.e9;
+
+    esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetMinNClustersITS(minclsITS);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetRequireTPCRefit(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+
+    tag = "Global tracking: TPC refit + ITS refit + >3 ITS clusters + >=1 SPD cluster";
+  }
+
+  /*
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt)
+  if (cutMode == 70) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcaxyITSTPC=1.e9;
+    Double_t maxdcazITSTPC=1.e9;
+
+    esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt)";
+  }
+  */
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt)
+  if (cutMode == 70) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt)";
+  }
+
+  // TPC+ITS combine tracking + DCAr(pt) + DCAz(pt)
+  if (cutMode == 71) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCRefit(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // DCArphi parametrization (LHC10c pass2)
+    // 7*(0.0026+0.0050/pt^1.01)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
+
+    // DCArphi parametrization (LHC10c pass2)
+    // 7*(0.01+0.011/pt^0.72)
+    esdTrackCuts->SetMaxDCAToVertexZPtDep("0.07+0.077/pt^0.72");
+
+    tag = "TPC+ITS combine tracking + DCAr(pt) + DCAz(pt)";
+  }
+
+  // TPC+ITS combine tracking + DCAr(pt) (2010)
+  if (cutMode == 72) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=2.0;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCRefit(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // DCArphi parametrization (LHC10c pass2)
+    // 7*(0.0026+0.0050/pt^1.01)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0182+0.0350/pt^1.01");
+
+    tag = "TPC+ITS combine tracking + DCAr(pt) (2010)";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) 4-sigma
+  if (cutMode == 75) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 4*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.02+0.024/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) 4-sigma";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) 10-sigma
+  if (cutMode == 80) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 10*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.05+0.06/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) 10 sigma";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 60 TPCclust
+  if (cutMode == 85) 
+  {
+    Int_t    minclsTPC=60;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 80 clusters
+  if (cutMode == 90) 
+  {
+    Int_t    minclsTPC=80;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 80 TPCclust";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) + TPCchi2=3.5
+  if (cutMode == 95) 
+  {
+    Int_t    minclsTPC=80;
+    Double_t maxchi2perTPCcl=3.5;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + TPCchi2 3.5";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) + TPCchi2=4.5
+  if (cutMode == 100) 
+  {
+    Int_t    minclsTPC=80;
+    Double_t maxchi2perTPCcl=4.5;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + TPCchi2 4.5";
+  }
+
+  // TPC-tracks
+  if (cutMode == 110) 
+  {
+
+    minNClustersTPC = 70;
+    maxChi2PerClusterTPC = 4.0;
+    maxDCAtoVertexXY = 1.e9; // cm
+    maxDCAtoVertexZ  = 1.e9; // cm
+
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minNClustersTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxChi2PerClusterTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxDCAtoVertexXY);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxDCAtoVertexZ);
+    esdTrackCuts->SetDCAToVertex2D(kTRUE);
+
+    tag = "TPC-tracks loose criteria";
+  }
+
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 50 TPCclust
+  if (cutMode == 120) 
+  {
+    Int_t    minclsTPC=50;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 70 TPCclust + accept kink daughters
+  if (cutMode == 130) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+  }
+
+  // TPC-tracks + SPD point + ITS refit + DCAr(pt) + 30 TPCclust + accept kink daughters
+  if (cutMode == 140) 
+  {
+    Int_t    minclsTPC=30;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=1.e9;
+
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kTRUE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "TPC-tracks + ITS refit + >1 SPD cluster + DCAr(Pt) + 60 TPCclust";
+  }
+
+  // Adam Kisiel track selectiion
+  if (cutMode == 150) 
+  {
+    Int_t    minclsTPC=70;
+    Double_t maxchi2perTPCcl=4.;
+    Double_t maxdcazITSTPC=0.25;
+    Double_t maxdcaxyITSTPC=0.2;
+
+    //
+    // TPC
+    //
+    //esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    esdTrackCuts->SetMinNClustersTPC(minclsTPC);
+    esdTrackCuts->SetMaxChi2PerClusterTPC(maxchi2perTPCcl);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    // primary selection
+    //
+    //esdTrackCuts->SetDCAToVertex2D(kFALSE);
+    esdTrackCuts->SetRequireSigmaToVertex(kFALSE);
+    esdTrackCuts->SetMaxDCAToVertexZ(maxdcazITSTPC);
+    esdTrackCuts->SetMaxDCAToVertexXY(maxdcaxyITSTPC);
+
+    // 7*(0.0050+0.0060/pt^0.9)
+    //esdTrackCuts->SetMaxDCAToVertexXYPtDep("0.0350+0.0420/pt^0.9");
+
+    tag = "Adam Kisiel track selection";
+  }
+
+  // TPC+ITS refit
+  // for cut studies
+  if (cutMode == 151) 
+  {
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCRefit(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    //
+    // ITS
+    //
+    esdTrackCuts->SetRequireITSRefit(kTRUE);
+    esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+
+    tag = "TPC+ITS refit required - for cut studies";
+  }
+
+  // TPC+ITS
+  // for cut studies
+  if (cutMode == 152) 
+  {
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCRefit(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    //
+    // ITS
+    //
+    //esdTrackCuts->SetRequireITSRefit(kTRUE);
+    //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    
+    tag = "TPC refit required - for cut studies";
+  }
+
+  // TPC
+  // for cut studies
+  if (cutMode == 153) 
+  {
+    //
+    // TPC
+    //
+    esdTrackCuts->SetRequireTPCRefit(kFALSE);
+    esdTrackCuts->SetRequireITSRefit(kFALSE);
+    esdTrackCuts->SetRequireTPCStandAlone(kTRUE);
+    esdTrackCuts->SetAcceptKinkDaughters(kFALSE);
+    //
+    // ITS
+    //
+    //esdTrackCuts->SetRequireITSRefit(kTRUE);
+    //esdTrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+    //
+    
+    tag = "TPC stand alone - for cut studies";
+  }
+
+
+
+
+
+
+  // cuts for data without field
+  if (!fieldOn)
+  {
+    cov5 = 1e10;
+    tag += " without field";
+  }
+
+  Printf("Created track cuts for: %s", tag.Data());
+
+  return esdTrackCuts;
+}
diff --git a/PWG0/multVScentPbPb/AliTaskGlobVar.h b/PWG0/multVScentPbPb/AliTaskGlobVar.h
new file mode 100755 (executable)
index 0000000..de286fb
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef ALIGLOBVAR_H
+#define ALIGLOBVAR_H
+
+///////////////////////////////////////////////////////////////////////////
+// Analysis task to extract global variables to the tree                 //
+///////////////////////////////////////////////////////////////////////////
+
+class AliESDEvent;
+class TList;
+class AliESDtrackCuts;
+#include "AliAnalysisTaskSE.h"
+#include "AliTriggerAnalysis.h" 
+
+class AliTaskGlobVar : public AliAnalysisTaskSE {
+  //
+ public:
+  AliTaskGlobVar(const char *name = "AliTaskGlobVar");
+  virtual ~AliTaskGlobVar(); 
+  virtual void  UserCreateOutputObjects();
+  virtual void  UserExec(Option_t *option);
+  virtual void  Terminate(Option_t *);
+  //
+  void    SetUseMC(Bool_t mc=kTRUE)                                   {fUseMC = mc;}
+  Float_t GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const;
+  Bool_t  ZDCTimeTrigger(const AliESDEvent *aEsd) const;
+  AliESDtrackCuts* CreatedNdPtTrackCuts(Int_t cutMode, Bool_t fieldOn=kTRUE);
+  //
+ protected:
+  Bool_t       fUseMC;                    // do we use MC info
+  TList*       fOutput;                   // output list send on output slot 1 
+  //
+  TTree*       fOutTree;                   // output tree
+  AliESDtrackCuts* fTrackCuts;             //! optional track cuts
+  AliESDtrackCuts* fTrackCuts1;            //! optional track cuts
+  //
+ private:    
+  AliTaskGlobVar(const AliTaskGlobVar&); // not implemented
+  AliTaskGlobVar& operator=(const AliTaskGlobVar&); // not implemented 
+  
+  ClassDef(AliTaskGlobVar, 1);  
+};
+
+
+typedef struct {
+  enum {kTDCNA=0x1,kTDCPA=0x1<<1,kTDCNC=0x1<<2,kTDCPC=0x1<<3,kSPDVTXOK=0x1<<4};
+  Int_t   runID;
+  UInt_t  timeStamp;
+  Float_t zdcNA;
+  Float_t zdcPA;
+  Float_t zdcNC;
+  Float_t zdcPC;
+  Float_t zem1;
+  Float_t zem2;
+  //
+  Float_t zvSPD;
+  Float_t zvTPC;
+  Short_t chunk;
+  Short_t flags;
+  Short_t spd1;
+  Short_t spd2;
+  Short_t ncontSPDV;
+  Short_t ncontTPCV;
+  Short_t nTrTPC;
+  Short_t nTrTPCITS;
+  Short_t nTracklets;
+  Short_t v0A;
+  Short_t v0C;
+  Short_t v0Corr;
+  //  Short_t v0CorrResc;
+  Float_t mcZV;
+  Short_t mcdNdEta;
+  Short_t mcNPart;
+  Short_t mcNBColl;
+} GloVars_t;
+
+#endif
diff --git a/PWG0/multVScentPbPb/AliTrackletTaskMulti.cxx b/PWG0/multVScentPbPb/AliTrackletTaskMulti.cxx
new file mode 100755 (executable)
index 0000000..2d2e6f1
--- /dev/null
@@ -0,0 +1,1690 @@
+/*************************************************************************
+* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  * 
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTaskMulti                                            //
+// Analysis task to produce data and MC histos needed for tracklets      //
+// dNdEta extraction in multiple bins in one go                          //
+// Author:  ruben.shahoyan@cern.ch                                       //
+///////////////////////////////////////////////////////////////////////////
+/*
+  Important parameters to set:
+  1) make sure to initialize correct geometry in UserCreateOutputObjects
+  2) The cut on signal selection variable (delta, dphi ...) should be decided beforehand
+...
+*/
+
+#include "TChain.h"
+#include "TTree.h"
+#include "TRandom.h"
+#include "TH1F.h"
+#include "TH2F.h" 
+#include "TH3F.h"
+#include "THnSparse.h"
+#include "TList.h"
+#include "TNtuple.h"
+#include "TObjArray.h"
+#include "TGeoGlobalMagField.h"
+
+#include "AliAnalysisManager.h"
+
+#include "AliMultiplicity.h"
+#include "AliESDEvent.h"  
+#include "AliESDInputHandler.h"
+#include "AliESDInputHandlerRP.h"
+#include "../ANALYSIS/EventMixing/AliMixEventInputHandler.h"
+#include "AliCDBPath.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliCDBStorage.h"
+#include "AliGeomManager.h"
+#include "AliMagF.h"
+#include "AliESDVZERO.h"
+#include "AliESDZDC.h"
+#include "AliRunLoader.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "../ITS/AliITSRecPoint.h"
+#include "../ITS/AliITSgeomTGeo.h"
+#include "../ITS/AliITSMultReconstructor.h" 
+
+#include "AliLog.h"
+
+#include "AliPhysicsSelection.h"
+#include "AliESDCentrality.h" 
+#include "AliTrackletTaskMulti.h"
+#include "AliITSMultRecBg.h"
+#include "AliGenEventHeader.h"
+#include "AliGenHijingEventHeader.h"
+#include "AliGenDPMjetEventHeader.h"
+#include "AliESDtrackCuts.h"
+
+ClassImp(AliTrackletTaskMulti)
+
+// centrality definition with SPD2corr
+const Float_t  AliTrackletTaskMulti::fgkCentBinDefSPD2[] = 
+{0,21,69,165,345,637,1069,1683,2511,3721,4585,6500}; // Alberica 2010-11-21 at 22:17 
+//corresponding npart: {379.973,328.414,259.244,185.094,128.309,84.9333,52.7138,29.9245,15.3195,6.98915,3.16337};
+
+// special test with splitting upper 10% to 4 equidistant bins
+//  {3721,4125,4584,5102,6500};
+
+
+//  {0,29,85,191,385,687,1133,1743,2567,3765,4611,6500}; // before 21/11/10 
+//corresponding npart: {3.14467,6.876,15.0519,29.0842,52.7315,84.8281,128.265,185.004,259.304,328.651,379.393};
+
+
+// centrality definition with V0 Rescaled
+const Float_t AliTrackletTaskMulti::fgkCentBinDefV0CR[] = 
+{0,32.5,89.5,198.5,396.5,700.5,1140.5,1744.5,2562.5,3767.5,4647.5,6500.};
+// on V0 corrected and rescaled
+// corresponding npart:  {3.23659,7.28226,15.9883,31.4739,54.7531,87.0497,130.454,185.996,260.318,329.655,379.114}
+
+
+const Float_t AliTrackletTaskMulti::fgkCentBinDefV0[] = 
+  {12191,13529,15079,16815,21000}; // special test with splitting upper 10% to 4 equidistant bins for new baseline with ZDC timing cleanup, 11/29/2010 01:10:37 PM
+
+//  {0,79,239,559,1165,2135,3555,5525,8213,12191,15079,21000}; // new baseline with ZDC timing cleanup, 11/29/2010 01:10:37 PM
+
+  //  {12165,13527,15079,16801,21000}; // special test with splitting upper 10% to 4 equidistant bins for Alberica 2010-11-21 at 22:17 
+//  {0,79,247,577,1185,2155,3565,5527,8203,12167,15073,21000}; // Alberica 2010-11-21 at 22:17 
+// corresponding npart: {379.112,323.171,253.417,183.054,129.116,86.9088,54.2474,30.2884,15.1553,6.7094,2.95315}
+
+//  {0,107,297,659,1305,2301,3747,5715,8361,12307,15153,21000}; // before 21/11/10 on V0 corrected for non-linearity
+// corresponding npart: {2.93958,6.67109,15.0721,29.7634,52.6495,84.8531,128.160,185.197,259.314,328.781,381.040};
+
+//{0,105,291,644,1280,2269,3728,5704,8366,12111,14706,19540}; // after  18/11/10, V0 not corrected
+//{0,124.5,274.5,574.5,1224.5,2174.5,3624.5,5574.5,8274.5,12024.5,14674.5,20000}; // before 18/11/10
+
+
+// centrality selection with TPC tracls only
+const Float_t AliTrackletTaskMulti::fgkCentBinDefTrTPC[] = 
+  {0,13,37,85,171,307,507,783,1157,1685,2055,2900};
+//corresponding npart:  {3.22604,6.98597,15.1032,29.7764,52.6338,84.7075,128.221,185.129,259.17,329.234,378.667};
+
+//------------------------- 2D boundaries ---------------------------------------
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0X[] =
+  {0.,150.0,310.0,610.0,1190.0,2170.0,3570.0,5530.0,8210.0,12150.0,15070.0,21000.};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0Y[] =
+  {0.0,1224.6,1999.4,2665.2,3106.0,3312.4,3343.0,3238.1,2758.1,1697.8,978.7,0.00};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0S[] =
+  {-1.,-0.1225,-0.3001,-0.9252,-2.0376,-10.1909,62.0849,9.1496,4.1895,3.6557,4.7364,1.};
+
+/*
+// 80% of ZDC&V0 set to 247 as 80% of 1D V0
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0X[] =
+  {0.,130.,247.,490.,1010.0,1950.,3310.,5270.,7930.,11930.,14930.,21000.};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0Y[] =
+  {0.00,1061.35,1732.80,2459.06,3017.64,3288.97,3346.46,3264.99,2822.64,1758.14,1008.61,0.00};
+const Float_t AliTrackletTaskMulti::fgkCentBinDefZDCV0S[] =
+  {-1.,0.1225,-0.3001,-0.5631,-2.0376,-7.3697,125.8992,10.2539,4.4412,3.6288,4.6181,1.};
+*/
+
+const Float_t *fkCentBinDef    = 0;
+const Float_t *fkCentBinDef2DY = 0;
+const Float_t *fkCentBinDef2DS = 0;
+
+const char*  AliTrackletTaskMulti::fgkPDGNames[] = {
+"#pi^{+}",
+"p",
+"K^{+}",
+"K^{*+}",
+"e^{-}",
+"#mu^{-}",
+"#rho^{+}",
+"D^{+}",
+"D^{*+}",
+"D_{s}^{+}",
+"D_{s}^{*+}",
+"#Delta^{-}",
+"#Delta^{+}",
+"#Delta^{++}",
+"#Sigma^{-}",
+"#Sigma^{+}",
+"#Sigma^{*-}",
+"#Sigma^{*+}",
+"#Sigma^{*+}_{c}",
+"#Sigma^{*++}_{c}",
+"#Xi^{-}",
+"#Xi^{*-}",
+"#Lambda^{+}_{c}",
+"n",
+"#Delta^{0}",
+"#gamma",
+"K^{0}_{S}",
+"K^{0}_{L}",
+"K^{0}",
+"K^{*}",
+"#eta",
+"#pi^{0}",
+"#rho^{0}",
+"#varphi",
+"#eta'",
+"#omega",
+"#Lambda",
+"#Sigma^{0}",
+"#Sigma^{*0}_{c}",
+"#Sigma^{*0}",
+"D^{0}",
+"D^{*0}",
+"#Xi_{0}",
+"#Xi^{*0}",
+"#Xi^{0}_{c}",
+"#Xi^{*0}_{c}",
+"Nuclei",
+"Others"
+};
+
+const int AliTrackletTaskMulti::fgkPDGCodes[] = {
+  211,
+ 2212, 
+  321, 
+  323, 
+   11, 
+   13, 
+  213, 
+  411, 
+  413, 
+  431, 
+  433, 
+ 1114, 
+ 2214, 
+ 2224, 
+ 3112, 
+ 3222, 
+ 3114, 
+ 3224, 
+ 4214, 
+ 4224, 
+ 3312, 
+ 3314, 
+ 4122, 
+ 2112, 
+ 2114, 
+   22, 
+  310, 
+  130, 
+  311, 
+  313, 
+  221, 
+  111, 
+  113, 
+  333, 
+  331, 
+  223, 
+ 3122, 
+ 3212, 
+ 4114, 
+ 3214, 
+  421, 
+  423, 
+ 3322, 
+ 3324, 
+ 4132, 
+ 4314
+// nuclei
+// unknown
+};
+
+//________________________________________________________________________
+/*//Default constructor
+AliTrackletTaskMulti::AliTrackletTaskMulti(const char *name)
+  : AliAnalysisTaskSE(name),
+*/  
+//________________________________________________________________________
+AliTrackletTaskMulti::AliTrackletTaskMulti(const char *name) 
+  : AliAnalysisTaskSE(name), 
+//
+  fOutput(0), 
+//
+  fDoNormalReco(kFALSE),
+  fDoInjection(kFALSE),
+  fDoRotation(kFALSE),
+  fDoMixing(kFALSE),
+  //
+  fUseMC(kFALSE),
+  fCheckReconstructables(kFALSE),
+//
+  fHistosTrData(0),
+  fHistosTrInj(0),
+  fHistosTrRot(0),
+  fHistosTrMix(0),
+//
+  fHistosTrPrim(0),
+  fHistosTrSec(0),
+  fHistosTrComb(0),
+  fHistosTrCombU(0),
+//
+  fHistosTrRcblPrim(0),
+  fHistosTrRcblSec(0),
+  fHistosCustom(0),
+//
+  fEtaCut(3.0),
+  fZVertexMin(-20),
+  fZVertexMax( 20),
+//
+  fScaleDTBySin2T(kFALSE),
+  fCutOnDThetaX(kFALSE),
+  fNStdDev(1.),
+  fDPhiWindow(0.08),
+  fDThetaWindow(0.025),
+  fDPhiShift(0.0045),
+  fPhiOverlapCut(0.005),
+  fZetaOverlap(0.05),
+  fPhiRot(0.),
+  fInjScale(1.),
+  fRemoveOverlaps(kFALSE),
+//
+  fDPhiSCut(0.06),
+  fNStdCut(1.),
+  fMCV0Scale(0.7520),
+//
+  fMultReco(0),
+  fRPTree(0),
+  fRPTreeMix(0),
+  fStack(0),
+  fMCEvent(0),
+  fTrackCuts(0),  
+  //
+  fNPart(0),
+  fNBColl(0),
+  fCurrCentBin(-1),
+  fNCentBins(0),
+  fUseCentralityVar(kCentV0)
+  /*
+  ,
+  fTrigger(AliTriggerAnalysis::kAcceptAll),
+  fMCCentralityBin(AliAnalysisTaskSPDdNdEta::kall),
+  fCentrLowLim(0),
+  fCentrUpLim(0),
+  fCentrEst("")
+  */
+{
+  // Constructor
+
+  DefineOutput(1, TList::Class());
+  //
+  SetScaleDThetaBySin2T();
+  SetNStdDev();
+  SetPhiWindow();
+  SetThetaWindow();
+  SetPhiShift();
+  SetPhiOverlapCut();
+  SetZetaOverlapCut();
+  SetPhiRot();
+  SetRemoveOverlaps();
+  //
+}
+
+//________________________________________________________________________
+AliTrackletTaskMulti::~AliTrackletTaskMulti()
+{
+  // Destructor
+  // histograms are in the output list and deleted when the output
+  // list is deleted by the TSelector dtor
+  if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {  //RRR
+    printf("Deleteing output\n");
+    delete fOutput;
+    fOutput = 0;
+  }
+  //
+  delete fMultReco;
+  delete fTrackCuts;
+  //
+  delete fHistosTrData;
+  delete fHistosTrPrim;
+  delete fHistosTrSec;
+  delete fHistosTrComb;
+  delete fHistosTrCombU;
+  delete fHistosTrInj;
+  delete fHistosTrRot;
+  delete fHistosTrMix;
+  delete fHistosTrRcblPrim;
+  delete fHistosTrRcblSec;
+  delete fHistosCustom;
+  //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskMulti::UserCreateOutputObjects() 
+{
+  //
+  fOutput = new TList();
+  fOutput->SetOwner(); 
+  //
+  if      (fUseCentralityVar == kCentV0)   {
+    fNCentBins = sizeof(fgkCentBinDefV0)/sizeof(Float_t) - 1;
+    fkCentBinDef = fgkCentBinDefV0;
+  }
+  else if (fUseCentralityVar == kCentV0CR)   {
+    fNCentBins = sizeof(fgkCentBinDefV0CR)/sizeof(Float_t) - 1;
+    fkCentBinDef = fgkCentBinDefV0CR;
+  }
+  else if (fUseCentralityVar == kCentSPD2) {
+    fNCentBins = sizeof(fgkCentBinDefSPD2)/sizeof(Float_t) - 1;
+    fkCentBinDef = fgkCentBinDefSPD2;
+  }
+  else if (fUseCentralityVar == kCentTrTPC) {
+    fNCentBins = sizeof(fgkCentBinDefTrTPC)/sizeof(Float_t) - 1;
+    fkCentBinDef = fgkCentBinDefTrTPC;
+  }
+  else if (fUseCentralityVar == kCentZDCV0) {
+    fNCentBins = sizeof(fgkCentBinDefZDCV0X)/sizeof(Float_t) - 1;
+    fkCentBinDef    = fgkCentBinDefZDCV0X;
+    fkCentBinDef2DY = fgkCentBinDefZDCV0Y;
+    fkCentBinDef2DS = fgkCentBinDefZDCV0S;    
+  }
+  else {
+    AliFatal(Form("Unknown cenrality parameter %d",fUseCentralityVar));
+  }  
+  //
+  AliCDBManager *man = AliCDBManager::Instance();
+  if (fUseMC) {
+    Bool_t newGeom = kTRUE;
+    man->SetDefaultStorage("alien://Folder=/alice/simulation/2008/v4-15-Release/Residual");
+    if (newGeom) {
+      // new geom
+      AliCDBEntry*  obj = man->Get("GRP/Geometry/Data",130844,8);
+      AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+      if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130844,6,-1)) AliFatal("Failed to misalign geometry");
+    }
+    else {
+      // old geom
+      AliCDBEntry*  obj = man->Get("GRP/Geometry/Data",130845,7);
+      AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+      if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130845,5,-1)) AliFatal("Failed to misalign geometry");
+    }
+  }
+  else {
+    man->SetDefaultStorage("raw://"); man->SetRun(137045);
+    AliCDBEntry*  obj = man->Get("GRP/Geometry/Data",137045,3);
+    AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+    if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",137045,8,-1)) AliFatal("Failed to misalign geometry");
+  }
+  //
+  fTrackCuts = AliESDtrackCuts::GetStandardTPCOnlyTrackCuts();
+  //
+  // Create histograms
+  //---------------------------------------------Standard histos per tracklet type--->>
+  UInt_t hPattern = 0xffffffff;
+  fHistosTrData                      = BookHistosSet("TrData",hPattern);
+  if (GetDoInjection()) fHistosTrInj = BookHistosSet("TrInj",hPattern);
+  if (GetDoRotation())  fHistosTrRot = BookHistosSet("TrRot",hPattern);
+  if (GetDoMixing())    fHistosTrMix = BookHistosSet("TrMix",hPattern);
+  if (fUseMC) {
+    fHistosTrPrim  = BookHistosSet("TrPrim",hPattern);
+    fHistosTrSec   = BookHistosSet("TrSec",hPattern);
+    fHistosTrComb  = BookHistosSet("TrComb",hPattern);
+    fHistosTrCombU = BookHistosSet("TrCombU",hPattern);
+    if (fCheckReconstructables) {
+      fHistosTrRcblPrim = BookHistosSet("TrRcblPrim",hPattern);
+      fHistosTrRcblSec  = BookHistosSet("TrRcblSec",hPattern);
+    }
+  }
+  //---------------------------------------------Standard histos per tracklet type---<<
+  //
+  //---------------------------------------------Custom Histos----------------------->>
+  // put here any non standard histos
+  fHistosCustom = BookCustomHistos();
+  //
+  //---------------------------------------------Custom Histos-----------------------<<
+  int nhist = fOutput->GetEntries();
+  for (int i=0;i<nhist;i++) {
+    TObject* hst = fOutput->At(i);
+    if (!hst || !(hst->InheritsFrom(TH1::Class()))) continue;
+    ((TH1*)hst)->Sumw2();
+  }
+  //
+  PostData(1, fOutput);
+  //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskMulti::UserExec(Option_t *) 
+{
+  // Main loop
+  //
+  AliAnalysisManager* anMan = AliAnalysisManager::GetAnalysisManager();
+  fRPTree = fRPTreeMix = 0;
+  AliESDInputHandlerRP *handRP = (AliESDInputHandlerRP*)anMan->GetInputEventHandler();
+  if (!handRP) { printf("No RP handler\n"); return; }
+  AliESDEvent *esd  = handRP->GetEvent();
+  if (!esd) { printf("No AliESDEvent\n"); return; }
+  //
+  // do we need to initialize the field?
+  AliMagF* field = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+  if (!field && !esd->InitMagneticField()) {printf("Failed to initialize the B field\n");return;}
+  //
+  /* // RS to be clarified
+  // Trigger selection
+  static AliTriggerAnalysis* triggerAnalysis = 0; 
+  Bool_t eventTriggered = triggerAnalysis->IsTriggerFired(esd, fTrigger);
+  if (!eventTriggered) {printf("No trigger\n"); return;}
+  //
+  // Centrality selection 
+  Bool_t eventInCentralityBin = kFALSE;
+  // Centrality selection
+  AliESDCentrality *centrality = esd->GetCentrality();
+  if (fCentrEst=="") eventInCentralityBin = kTRUE;
+  else {
+    if(!centrality) {
+      AliError("Centrality object not available"); 
+    }  else {
+      if (centrality->IsEventInCentralityClass(fCentrLowLim,fCentrUpLim,fCentrEst.Data())) eventInCentralityBin = kTRUE;
+    }
+  }
+  */
+  //  if (!fUseMC && !ZDCTimeTrigger(esd)) return;
+  //
+  const AliESDVertex* vtxESD = esd->GetPrimaryVertexSPD();
+  if (vtxESD->GetNContributors()<1) return;
+  if (vtxESD->GetDispersion()>0.04) return;
+  if (vtxESD->GetZRes()>0.25) return;
+  const AliMultiplicity* multESD = esd->GetMultiplicity();
+  const AliESDVertex* vtxESDTPC = esd->GetPrimaryVertexTPC();
+  float nSPD1 = multESD->GetNumberOfITSClusters(0);
+  float nSPD2 = multESD->GetNumberOfITSClusters(1);
+  //
+    /*
+  if (vtxESDTPC->GetNContributors()<1 ||
+      vtxESDTPC->GetNContributors()<(-10.+0.25*nSPD1)) return;
+    */
+  //
+  TH1* hstat = (TH1*)fHistosCustom->UncheckedAt(kHStat);
+  //
+  hstat->Fill(kEvTot); // RS
+  //
+  Double_t esdvtx[3];
+  vtxESD->GetXYZ(esdvtx);
+  for (int i=3;i--;) fESDVtx[i] = esdvtx[i];
+  //
+  float vtxf[3] = {vtxESD->GetX(),vtxESD->GetY(),vtxESD->GetZ()};
+  //
+  //------------------------------------------------------
+  // ZDC cut
+  AliESDZDC *esdZDC = esd->GetESDZDC();
+  // --- ZDC offline trigger ---
+  // Returns if ZDC triggered, based on TDC information
+  Bool_t tdc[32] = {kFALSE};
+  for(Int_t itdc=0; itdc<32; itdc++){
+    for(Int_t i=0; i<4; i++){
+      if (0.025*esdZDC->GetZDCTDCData(itdc, i) != 0){
+       tdc[itdc] = kTRUE;
+      }
+    }
+  }
+  Bool_t zdcNA = tdc[12];
+  Bool_t zdcNC = tdc[10];
+  Bool_t zdcPA = tdc[13];
+  Bool_t zdcPC = tdc[11];
+  //
+  Bool_t zdcA= ((zdcPA) || (zdcNA));
+  Bool_t zdcC= ((zdcPC) || (zdcNC));
+  //  if (!fUseMC && !(zdcA&&zdcC)) return;
+  if (!fUseMC && !(zdcNA&&zdcNC)) return;
+  float zdcEnergy = esdZDC->GetZDCN1Energy() + esdZDC->GetZDCP1Energy() + esdZDC->GetZDCN2Energy()+ esdZDC->GetZDCP2Energy();
+  zdcEnergy /= 8.;
+  //
+  //-----------------------------------------------------
+  Float_t multV0A=0,multV0C=0,multV0=0,multV0Corr=0,multV0CorrResc=0;
+  AliESDVZERO* esdV0 = esd->GetVZEROData();
+  if (esdV0) {
+    multV0A = esdV0->GetMTotV0A();
+    multV0C = esdV0->GetMTotV0C();
+  }
+  if (fUseMC) {
+    multV0A *= fMCV0Scale;
+    multV0C *= fMCV0Scale;    
+  }
+  multV0   = multV0A + multV0C;
+  if (!fUseMC) multV0Corr = GetCorrV0(esd, multV0CorrResc);
+  else {
+    multV0Corr = multV0;
+    multV0CorrResc = multV0;
+  }
+  //
+  // correct nSPD2 for Zv dependence
+  float nSPD2Corr = GetCorrSPD2(nSPD2,esdvtx[2]);
+  //
+  float multTPC = fTrackCuts->GetReferenceMultiplicity(esd,kTRUE);
+  //
+  // registed Ntracklets and ZVertex of the event
+  ((TH1*)fHistosCustom->UncheckedAt(kHZVtxNoSel))->Fill(esdvtx[2]);
+  ((TH1*)fHistosCustom->UncheckedAt(kHNTrackletsNoSel))->Fill(multESD->GetNumberOfTracklets());      
+  ((TH1*)fHistosCustom->UncheckedAt(kHNClSPD1NoSel))->Fill(nSPD1);
+  ((TH1*)fHistosCustom->UncheckedAt(kHNClSPD2NoSel))->Fill(nSPD2);
+  ((TH1*)fHistosCustom->UncheckedAt(kHV0NoSel))->Fill(multV0Corr);
+  ((TH1*)fHistosCustom->UncheckedAt(kHV0CCNoSel))->Fill(multV0CorrResc);
+  ((TH1*)fHistosCustom->UncheckedAt(kHMultTPCNoSel))->Fill(multTPC);
+  //
+  //  ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0A+multV0C,multESD->GetNumberOfITSClusters(1));
+  //
+  //  printf("ESD vertex! %f %f %f, %d contributors\n",esdvtx[0],esdvtx[1],esdvtx[2],vtxESD->GetNContributors());
+
+  if(vtxf[2] < fZVertexMin || vtxf[2] > fZVertexMax) return;
+  ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0Corr,nSPD2);
+  ((TH2F*)fHistosCustom->UncheckedAt(kHV0CCNClSPD2NoSel))->Fill(multV0CorrResc,nSPD2);
+  //
+  ///  double mltTst = fUseMC ?  multESD->GetNumberOfITSClusters(1) : multV0A+multV0C;  
+  //  double mltTst = multESD->GetNumberOfITSClusters(1); //RRR
+  float mltTst = -1;
+  float mltTst2 = -1;
+  if      (fUseCentralityVar == kCentSPD2) mltTst = nSPD2Corr;
+  else if (fUseCentralityVar == kCentV0)   mltTst = multV0Corr; // Cvetan's corrected V0
+  else if (fUseCentralityVar == kCentV0CR) mltTst = multV0CorrResc; // Cvetan's rescaled V0
+  else if (fUseCentralityVar == kCentTrTPC)   mltTst = multTPC; // TPC Mult
+  else if (fUseCentralityVar == kCentZDCV0) {
+    mltTst = multV0Corr;
+    mltTst2 = zdcEnergy;
+  }
+  else AliFatal(Form("Unknown cenrality parameter %d",fUseCentralityVar));
+  //
+  fCurrCentBin = GetCentralityBin(mltTst,mltTst2);
+  if (fCurrCentBin<0) {
+    printf("Reject: %.1f : V0:%.1f V0Cor:%.1f V0CR:%.1f SPD2c:%.1f\n",mltTst, multV0,multV0Corr,multV0CorrResc,nSPD2Corr);
+    return;
+  }
+  //
+  ((TH1*)fHistosCustom->UncheckedAt(kHStatCent))->Fill(mltTst);
+  ((TH1*)fHistosCustom->UncheckedAt(kHStatCentBin))->Fill(fCurrCentBin);
+  printf("Bin %d (mlt=%f) Multiplicity from ESD:\n",fCurrCentBin,mltTst);
+  //  multESD->Print();
+  //
+  AliMCEventHandler* eventHandler = 0;
+  fMCEvent = 0;
+  fStack = 0;
+  //
+  if (fUseMC) {
+    eventHandler = (AliMCEventHandler*)anMan->GetMCtruthEventHandler();
+    if (!eventHandler) { printf("ERROR: Could not retrieve MC event handler\n"); return; }
+    fMCEvent = eventHandler->MCEvent();
+    if (!fMCEvent) { printf("ERROR: Could not retrieve MC event\n"); return; }
+    fStack = fMCEvent->Stack();
+    if (!fStack) { printf("Stack not available\n"); return; }
+  }
+  //
+  fRPTree = handRP->GetTreeR("ITS");
+  if (!fRPTree) { AliError(" Invalid ITS cluster tree !\n"); return; }
+  //
+  // =============================================================================>>>
+  // MC Generator info
+  AliGenEventHeader* mcGenH = 0;
+  fNPart  = 0;
+  fNBColl = 0;
+  if (fUseMC) {
+    mcGenH = fMCEvent->GenEventHeader();
+    if (mcGenH->InheritsFrom(AliGenHijingEventHeader::Class())) {
+      AliGenHijingEventHeader* hHijing = (AliGenHijingEventHeader*)mcGenH;
+      fNPart  = (hHijing->ProjectileParticipants()+hHijing->TargetParticipants())/2.;
+      fNBColl = hHijing->NN()+hHijing->NNw()+hHijing->NwN()+hHijing->NwNw();
+    }
+    else if (mcGenH->InheritsFrom(AliGenDPMjetEventHeader::Class())) {
+      AliGenDPMjetEventHeader* hDpmJet = (AliGenDPMjetEventHeader*)mcGenH;
+      fNPart  = (hDpmJet->ProjectileParticipants()+hDpmJet->TargetParticipants())/2.;
+      fNBColl = hDpmJet->NN()+hDpmJet->NNw()+hDpmJet->NwN()+hDpmJet->NwNw();
+    }
+    else {} // unknown generator
+  }
+  //
+  // register Ntracklets and ZVertex of the event
+  ((TH2*)fHistosCustom->UncheckedAt(kHZVtx))->Fill(esdvtx[2],fCurrCentBin);
+  ((TH2*)fHistosCustom->UncheckedAt(kHNTracklets))->Fill(multESD->GetNumberOfTracklets(),fCurrCentBin);
+  //
+  if (fUseMC) FillMCPrimaries();
+  // fill N clusters
+  ((TH2*)fHistosCustom->UncheckedAt(kHNClSPD1))->Fill(nSPD1,fCurrCentBin);
+  ((TH2*)fHistosCustom->UncheckedAt(kHNClSPD2))->Fill(nSPD2,fCurrCentBin);
+  ((TH2*)fHistosCustom->UncheckedAt(kHV0))->Fill(multV0Corr,fCurrCentBin);
+  ((TH2*)fHistosCustom->UncheckedAt(kHV0CC))->Fill(multV0CorrResc,fCurrCentBin);
+  ((TH2*)fHistosCustom->UncheckedAt(kHMultTPC))->Fill(multTPC,fCurrCentBin);
+  //
+  // normal reconstruction
+  hstat->Fill(kBinEntries+kEvProcData + kEntriesPerBin*fCurrCentBin);
+  //
+  if (GetDoNormalReco() || GetDoInjection()) { // for the injection the normal reco should be done
+    InitMultReco();
+    fMultReco->Run(fRPTree, vtxf);
+    printf("Multiplicity Reconstructed:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    if (GetDoNormalReco()) FillHistos(kData,mlt);
+    FillClusterInfo();
+    //
+  }
+  if (!GetDoNormalReco()) FillHistos(kData,multESD); // fill data histos from ESD
+  //
+  // Injection: it must come right after the normal reco since needs its results
+  if (GetDoInjection()) {
+    if (!fMultReco) InitMultReco(); // in principle, not needed, the reco is created above
+    fMultReco->SetRecType(AliITSMultRecBg::kBgInj);
+    fMultReco->Run(fRPTree, vtxf);
+    printf("Multiplicity from Injection:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    hstat->Fill(kBinEntries + kEvProcInj + kEntriesPerBin*fCurrCentBin);
+    FillHistos(kBgInj,mlt);
+  }
+  //
+  // Rotation
+  if (GetDoRotation()) {
+    InitMultReco();
+    fMultReco->SetRecType(AliITSMultRecBg::kBgRot);
+    fMultReco->SetPhiRotationAngle(fPhiRot);
+    fMultReco->Run(fRPTree, vtxf);
+    printf("Multiplicity from Rotation:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    hstat->Fill(kBinEntries + kEvProcRot + kEntriesPerBin*fCurrCentBin);
+    FillHistos(kBgRot,mlt);
+  }
+  //
+  if (GetDoMixing()) {
+    AliMixEventInputHandler* handToMix = (AliMixEventInputHandler*)handRP->MixingHandler();
+    if (!handToMix) { printf("No Mixing handler\n"); return; }
+    handToMix->GetEntry();
+    if(handToMix->MixedEventNumber()<1) {printf("Mixing: No enough events in pool\n"); return;}
+    AliESDInputHandlerRP* handRPMix = (AliESDInputHandlerRP*) handToMix->InputEventHandler(0);
+
+    if (!handRPMix) { printf("No Mixing RP handler\n"); return; }
+    fRPTreeMix = handRPMix->GetTreeR("ITS");
+    if (!fRPTreeMix) { AliError(" Invalid ITS cluster tree of the 2nd event!\n"); return; }
+    //
+    AliESDEvent *esdMix = handRPMix->GetEvent();
+    const AliESDVertex* vtxESDmix = esdMix->GetVertex();
+    ((TH2*)fHistosCustom->UncheckedAt(kHZVtxMixDiff))->Fill(vtxESDmix->GetZ()-esdvtx[2],fCurrCentBin);
+    ((TH2*)fHistosCustom->UncheckedAt(kHNTrMixDiff) )->
+      Fill(esdMix->GetMultiplicity()->GetNumberOfTracklets() - multESD->GetNumberOfTracklets(),fCurrCentBin);
+    //
+    InitMultReco();
+    fMultReco->SetRecType(AliITSMultRecBg::kBgMix);
+    fMultReco->Run(fRPTree, vtxf,fRPTreeMix);
+    printf("Multiplicity from Mixing:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    hstat->Fill(kBinEntries + kEvProcMix + kEntriesPerBin*fCurrCentBin);
+    FillHistos(kBgMix,mlt);
+    //
+  }
+  // =============================================================================<<<
+  //
+  delete fMultReco; 
+  fMultReco = 0;
+  //
+}      
+
+//________________________________________________________________________
+Float_t AliTrackletTaskMulti::GetCorrSPD2(Float_t spd2raw,Float_t zv) const
+{
+  //renormalize N spd2 clusters at given Zv to acceptance at Zv=0
+  const double pars[] = {8.10030e-01,-2.80364e-03,-7.19504e-04};
+  zv -= pars[0];
+  float corr = 1 + zv*(pars[1] + zv*pars[2]);
+  return corr>0 ? spd2raw/corr : -1;
+}
+
+//________________________________________________________________________
+Float_t AliTrackletTaskMulti::GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const
+{
+  // correct V0 non-linearity, prepare a version rescaled to SPD2 corr
+  const Double_t par0[64] = { 6.71e-02 , 6.86e-02 , 7.06e-02 , 6.32e-02 , 
+                             5.91e-02 , 6.07e-02 , 5.78e-02 , 5.73e-02 , 5.91e-02 , 6.22e-02 , 
+                             5.90e-02 , 6.11e-02 , 5.55e-02 , 5.29e-02 , 5.19e-02 , 5.56e-02 , 
+                             6.25e-02 , 7.03e-02 , 5.64e-02 , 5.81e-02 , 4.57e-02 , 5.30e-02 , 
+                             5.13e-02 , 6.43e-02 , 6.27e-02 , 6.48e-02 , 6.07e-02 , 1.01e-01 , 
+                             6.68e-02 , 7.16e-02 , 6.36e-02 , 5.95e-02 , 2.52e-02 , 2.82e-02 , 
+                             2.56e-02 , 2.86e-02 , 2.82e-02 , 2.10e-02 , 2.13e-02 , 2.32e-02 , 
+                             2.75e-02 , 4.34e-02 , 3.78e-02 , 4.52e-02 , 4.11e-02 , 3.89e-02 , 
+                             4.10e-02 , 3.73e-02 , 4.51e-02 , 5.07e-02 , 5.42e-02 , 4.74e-02 , 
+                             4.33e-02 , 4.44e-02 , 4.64e-02 , 3.01e-02 , 6.38e-02 , 5.26e-02 , 
+                             4.99e-02 , 5.26e-02 , 5.47e-02 , 3.84e-02 , 5.00e-02 , 5.20e-02 };
+  const Double_t par1[64] = { -6.68e-05 , -7.78e-05 , -6.88e-05 , -5.92e-05 , 
+                             -2.43e-05 , -3.54e-05 , -2.91e-05 , -1.99e-05 , -1.40e-05 , -4.01e-05 , 
+                             -2.29e-05 , -3.68e-05 , -2.53e-05 , -2.44e-06 , -9.22e-06 , -1.51e-05 , 
+                             -2.80e-05 , -2.34e-05 , -1.72e-05 , -1.81e-05 , -1.29e-05 , -2.65e-05 , 
+                             -1.61e-05 , -2.86e-05 , -1.74e-05 , -4.23e-05 , -3.41e-05 , -1.05e-04 , 
+                             -2.76e-05 , -4.71e-05 , -3.06e-05 , -2.32e-05 , -1.55e-06 , 2.15e-05 , 
+                             1.40e-05 , 2.16e-05 , 1.21e-05 , 3.05e-06 , 1.67e-05 , -3.84e-06 , 
+                             3.09e-06 , 1.50e-05 , 3.47e-06 , 4.87e-06 , -3.71e-07 , -1.75e-06 , 
+                             -1.80e-06 , 9.99e-06 , -6.46e-06 , -4.91e-06 , 1.33e-05 , -2.52e-07 , 
+                             -3.85e-06 , 4.94e-06 , -2.48e-07 , -1.20e-05 , 2.07e-06 , 6.12e-06 , 
+                             -1.18e-06 , 4.54e-06 , -1.54e-05 , -1.25e-05 , 1.46e-06 , -6.67e-06 };
+  const Double_t par2[64] = { 1.29e-08 , 1.51e-08 , 1.43e-08 , 1.11e-08 , 
+                             5.04e-09 , 6.99e-09 , 5.58e-09 , 4.15e-09 , 4.00e-09 , 8.22e-09 , 
+                             4.97e-09 , 7.66e-09 , 4.91e-09 , 1.10e-09 , 2.64e-09 , 3.64e-09 , 
+                             5.76e-09 , 5.46e-09 , 3.38e-09 , 3.47e-09 , 2.43e-09 , 4.13e-09 , 
+                             2.80e-09 , 5.80e-09 , 3.86e-09 , 7.46e-09 , 5.98e-09 , 2.58e-08 , 
+                             5.50e-09 , 8.72e-09 , 5.23e-09 , 4.37e-09 , 2.33e-09 , -6.01e-10 , 
+                             3.99e-11 , -2.02e-10 , 7.67e-10 , 2.03e-09 , 1.17e-10 , 2.56e-09 , 
+                             1.16e-09 , -4.75e-10 , 1.28e-09 , 1.23e-09 , 1.62e-09 , 1.61e-09 , 
+                             1.93e-09 , 2.97e-10 , 2.21e-09 , 2.16e-09 , 5.22e-10 , 1.03e-09 , 
+                             1.56e-09 , 5.00e-10 , 1.01e-09 , 2.93e-09 , 1.05e-09 , 9.96e-11 , 
+                             1.21e-09 , 7.45e-10 , 3.07e-09 , 2.31e-09 , 6.70e-10 , 1.89e-09 };
+  //
+  Float_t multCorr = 0;
+  Float_t multCorr2 = 0;
+  Float_t multChCorr[64];
+  AliESDVZERO* esdV0 = esd->GetVZEROData();
+  for(Int_t i = 0; i < 64; ++i) {
+    Double_t b = (esdV0->GetMultiplicity(i)*par1[i]-par0[i]);
+    Double_t s = (b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i));
+    Double_t n;
+    if (s<0) {
+      printf("FPE %d %.2f %.2f %.2e\n",i,esdV0->GetMultiplicity(i),b,(b*b-4.*par2[i]*esdV0->GetMultiplicity(i)*esdV0->GetMultiplicity(i)));
+      n = -b;
+    }
+    else {
+      n = (-b + TMath::Sqrt(s));
+    }
+    multChCorr[i] = 2.*esdV0->GetMultiplicity(i)/n*par0[i];
+    multCorr += multChCorr[i];
+    multCorr2 += (multChCorr[i]/par0[i]/64.);
+  }
+  v0CorrResc =  multCorr2;
+  return multCorr;
+}
+
+
+//________________________________________________________________________
+void AliTrackletTaskMulti::Terminate(Option_t *) 
+{
+  Printf("Terminating...");
+  TH1* hstat;
+  TList *lst = dynamic_cast<TList*>(GetOutputData(1));
+  printf("Term: %p %p %p\n",fOutput,lst,fHistosCustom);
+  if (lst && (hstat=(TH1*)lst->FindObject("hStat"))) {
+    Info("Terminate","Registering used settings");
+    // fill used settings
+    hstat->Fill(kOneUnit,1.);    
+    hstat->Fill(kDPhi,fDPhiWindow);
+    hstat->Fill(kDTht,fDThetaWindow);
+    hstat->Fill(kNStd,fNStdDev);
+    hstat->Fill(kPhiShift,fDPhiShift);
+    hstat->Fill(kThtS2,fScaleDTBySin2T);  
+    hstat->Fill(kThtCW,fCutOnDThetaX);  
+    hstat->Fill(kPhiOvl,fPhiOverlapCut);
+    hstat->Fill(kZEtaOvl,fZetaOverlap);
+    hstat->Fill(kNoOvl,fRemoveOverlaps);
+    //
+    hstat->Fill(kPhiRot,fPhiRot);
+    hstat->Fill(kInjScl,fInjScale);
+    hstat->Fill(kEtaCut,fEtaCut);
+    hstat->Fill(kZVMin,fZVertexMin);
+    hstat->Fill(kZVMax,fZVertexMax);
+    //
+    hstat->Fill(kDPiSCut,fDPhiSCut);
+    hstat->Fill(kNStdCut,fNStdCut);    
+    hstat->Fill(kMCV0Scale, fMCV0Scale);
+    //
+  }
+  //
+  //  AliAnalysisTaskSE::Terminate();
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::InitMultReco()
+{
+  // create mult reconstructor
+  if (fMultReco) delete fMultReco;
+  fMultReco = new AliITSMultRecBg();
+  fMultReco->SetCreateClustersCopy(kTRUE);
+  fMultReco->SetScaleDThetaBySin2T(fScaleDTBySin2T);
+  fMultReco->SetNStdDev(fNStdDev);
+  fMultReco->SetPhiWindow( fDPhiWindow );
+  fMultReco->SetThetaWindow( fDThetaWindow );
+  fMultReco->SetPhiShift( fDPhiShift );
+  fMultReco->SetRemoveClustersFromOverlaps(fRemoveOverlaps);
+  fMultReco->SetPhiOverlapCut(fPhiOverlapCut);
+  fMultReco->SetZetaOverlapCut(fZetaOverlap);
+  fMultReco->SetHistOn(kFALSE); 
+  fMultReco->SetRecType( AliITSMultRecBg::kData );
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskMulti::BookCustomHistos()
+{
+  // book custom histos, not related to specific tracklet type
+  TObjArray* histos = new TObjArray();
+  TH1F* hstat;
+  //
+  // ------------ job parameters, statistics ------------------------------>>>
+  int nbs = kBinEntries + fNCentBins*kEntriesPerBin;
+  hstat = new TH1F("hStat","Run statistics",nbs,0.5,nbs+0.5);
+  //
+  hstat->GetXaxis()->SetBinLabel(kEvTot, "Ev.Tot");
+  hstat->GetXaxis()->SetBinLabel(kOneUnit,"ScaleMerge");
+  hstat->GetXaxis()->SetBinLabel(kNWorkers,"Workers");
+  //
+  hstat->GetXaxis()->SetBinLabel(kDPhi,  "#Delta#varphi");
+  hstat->GetXaxis()->SetBinLabel(kDTht,  "#Delta#theta");
+  hstat->GetXaxis()->SetBinLabel(kNStd,  "N.std");
+  hstat->GetXaxis()->SetBinLabel(kPhiShift,"#delta#varphi");
+  hstat->GetXaxis()->SetBinLabel(kThtS2,"scale #Delta#theta");
+  hstat->GetXaxis()->SetBinLabel(kPhiOvl,"#varpho_{Ovl}");
+  hstat->GetXaxis()->SetBinLabel(kZEtaOvl,"#z_{Ovl}");
+  hstat->GetXaxis()->SetBinLabel(kNoOvl, "rem.ovl");
+  //
+  hstat->GetXaxis()->SetBinLabel(kPhiRot,"#varphi_{rot}");
+  hstat->GetXaxis()->SetBinLabel(kInjScl,"inj");
+  hstat->GetXaxis()->SetBinLabel(kEtaCut,"#eta cut");
+  hstat->GetXaxis()->SetBinLabel(kZVMin,"ZV_{min} cut");
+  hstat->GetXaxis()->SetBinLabel(kZVMax,"ZV_{max} cut");
+  //
+  hstat->GetXaxis()->SetBinLabel(kDPiSCut,"#Delta#varphi-#delta_{#phi} cut");
+  hstat->GetXaxis()->SetBinLabel(kNStdCut,"#Delta cut");
+  //
+  hstat->GetXaxis()->SetBinLabel(kMCV0Scale,"MC V0 scale");
+  //
+  for (int i=0;i<fNCentBins;i++) {
+    TString bnt = "b"; bnt+= i;
+    int offs = kBinEntries + i*kEntriesPerBin;
+    hstat->GetXaxis()->SetBinLabel(offs + kEvProcData, bnt+" Ev.ProcData");
+    hstat->GetXaxis()->SetBinLabel(offs + kEvProcInj,  bnt+" Ev.ProcInj");
+    hstat->GetXaxis()->SetBinLabel(offs + kEvProcRot,  bnt+" Ev.ProcRot");
+    hstat->GetXaxis()->SetBinLabel(offs + kEvProcMix,  bnt+" Ev.ProcMix");
+    //
+  }
+  //
+  hstat->Fill(kNWorkers);
+  //  
+  AddHisto(histos,hstat,kHStat);
+  //
+  // ------------------------ events per centrality bin ----------------------
+  TH1D* hCentAx = new TH1D("EvCentr","Events per centrality",fNCentBins,fkCentBinDef);
+  hCentAx->GetXaxis()->SetTitle("Centrality parameter");
+  AddHisto(histos,hCentAx,kHStatCent);
+  //
+  TH1D* hCentBin = new TH1D("EvCentrBin","Events per centrality bin",fNCentBins,-0.5,fNCentBins-0.5);
+  hCentBin->GetXaxis()->SetTitle("Centrality Bin");
+  AddHisto(histos,hCentBin,kHStatCentBin);
+  //  
+  // ------------ job parameters, statistics ------------------------------<<<
+  //
+  double etaMn=-3,etaMx=3;
+  double zMn=-30, zMx=30;  
+  int nEtaBins = int((etaMx-etaMn)/0.1);
+  if (nEtaBins<1) nEtaBins = 1;
+  //
+  int nZVBins = int(zMx-zMn);
+  if (nZVBins<1) nZVBins = 1;
+  //
+  // Z vertex distribution for events before selection
+  TH1F* hzvns = new  TH1F("zvNoSel","Z vertex before selection",nZVBins,zMn,zMx);
+  hzvns->GetXaxis()->SetTitle("Zvertex");
+  AddHisto(histos,hzvns,kHZVtxNoSel);
+  //
+  int nbmltSPD2 = 700;
+  double maxmltSPD2 = 7000;
+  int nbmltV0 = 1000;
+  double maxmltV0 = 20000;
+  // N tracklets for processed events
+  TH1F* hntns = new  TH1F("NtrackletsNoSel","N Tracklets Before Selection",nbmltSPD2,0,maxmltSPD2);
+  hntns->GetXaxis()->SetTitle("N tracklets");
+  AddHisto(histos,hntns,kHNTrackletsNoSel);
+  //
+  // N SPD1 clusters
+  TH1F* hncl1ns = new  TH1F("NClustersSPD1NoSel","N Clusters on SPD1 Before Selection",nbmltSPD2,0,maxmltSPD2);
+  hncl1ns->GetXaxis()->SetTitle("N Clus SPD1");
+  AddHisto(histos,hncl1ns,kHNClSPD1NoSel);
+  //
+  // N SPD2 clusters
+  TH1F* hncl2ns = new  TH1F("NClustersSPD2NoSel","N Clusters on SPD2 Before Selection",nbmltSPD2,0,maxmltSPD2);
+  hncl2ns->GetXaxis()->SetTitle("N Clus SPD2");
+  AddHisto(histos,hncl2ns,kHNClSPD2NoSel);
+  //
+  // V0 
+  TH1F* hnV0ns = new  TH1F("V0NoSel","V0 signal Before Selection",nbmltV0,0,maxmltV0);
+  hnV0ns->GetXaxis()->SetTitle("V0 signal");
+  AddHisto(histos,hnV0ns,kHV0NoSel);
+  //
+  // V0 Corr
+  TH1F* hnV0CCns = new  TH1F("V0CorrNoSel","V0 Corr signal Before Selection",nbmltSPD2,0,maxmltSPD2); //!!! Same scale as SPD2
+  hnV0ns->GetXaxis()->SetTitle("V0 Corr signal");
+  AddHisto(histos,hnV0CCns,kHV0CCNoSel);
+  //
+  // V0 
+  //TH2F* hnV0SPD2ns = new  TH2F("V0NDP2NoSel","NSPD2 vs V0 signal Before Selection",2500,0,20000,1400,0,maxmltSPD2);
+  TH2F* hnV0SPD2ns = new  TH2F("V0NDP2NoMltSel","NSPD2 vs V0 signal Before Mlt Selection",100,0,maxmltV0,100,0,maxmltSPD2);
+  hnV0SPD2ns->GetXaxis()->SetTitle("V0 signal");
+  hnV0SPD2ns->GetYaxis()->SetTitle("N Clus SPD2 ");
+  AddHisto(histos,hnV0SPD2ns,kHV0NClSPD2NoSel);
+  //
+  // V0 corr
+  //TH2F* hnV0SPD2ns = new  TH2F("V0SPD2NoSel","NSPD2 vs V0 signal Before Selection",2500,0,20000,1400,0,maxmltSPD2);
+  TH2F* hnV0CCSPD2ns = new  TH2F("V0CCSPD2NoMltSel","NSPD2 vs V0 Corr signal Before Mlt Selection",100,0,maxmltV0,100,0,maxmltSPD2);
+  hnV0CCSPD2ns->GetXaxis()->SetTitle("V0 Corr signal");
+  hnV0CCSPD2ns->GetYaxis()->SetTitle("N Clus SPD2 ");
+  AddHisto(histos,hnV0CCSPD2ns,kHV0CCNClSPD2NoSel);
+  //
+  // TPC ref mult before selection
+  TH1F* hntpc = new  TH1F("TPCMultNoSel","TPC Multipliplicity Before Selection",300,0,3000);
+  hntpc->GetXaxis()->SetTitle("N TPC tracks");
+  AddHisto(histos,hntpc,kHMultTPCNoSel);
+  //
+
+  TH2F* hzv = new  TH2F("zv","Z vertex after Selection per Cent.Bin",nZVBins,zMn,zMx, fNCentBins, -0.5,fNCentBins-0.5);
+  hzv->GetXaxis()->SetTitle("Zvertex");
+  hzv->GetYaxis()->SetTitle("Cent.Bin ID");
+  AddHisto(histos,hzv,kHZVtx);
+  //
+  // N tracklets for processed events
+  TH2F* hnt = new  TH2F("Ntracklets","N Tracklets per Cent.Bin",nbmltSPD2,0,maxmltSPD2,  fNCentBins, -0.5,fNCentBins-0.5);
+  hnt->GetXaxis()->SetTitle("N tracklets");
+  hnt->GetYaxis()->SetTitle("Cent.Bin ID");
+  AddHisto(histos,hnt,kHNTracklets);
+  //
+  // N SPD1 clusters
+  TH2F* hncl1 = new  TH2F("NClustersSPD1","N Clusters on SPD1 per Cent.Bin",nbmltSPD2,0,maxmltSPD2,  fNCentBins, -0.5,fNCentBins-0.5);
+  hncl1->GetXaxis()->SetTitle("N Clus SPD1");
+  hncl1->GetYaxis()->SetTitle("Cent.Bin ID");
+  AddHisto(histos,hncl1,kHNClSPD1);
+  //
+  // N SPD2 clusters
+  TH2F* hncl2 = new  TH2F("NClustersSPD2","N Clusters on SPD2 per Cent.Bin",nbmltSPD2,0,maxmltSPD2, fNCentBins, -0.5,fNCentBins-0.5);
+  hncl2->GetXaxis()->SetTitle("N Clus SPD2");
+  hncl2->GetYaxis()->SetTitle("Cent.Bin ID");
+  AddHisto(histos,hncl2,kHNClSPD2);
+  //
+  // V0 
+  TH2F* hnV0 = new  TH2F("V0","V0 signalper Cent.Bin ",nbmltV0,0,maxmltV0, fNCentBins, -0.5,fNCentBins-0.5);
+  hnV0->GetXaxis()->SetTitle("V0 signal");
+  hnV0->GetYaxis()->SetTitle("Cent.Bin ID");
+  AddHisto(histos,hnV0,kHV0);
+  //
+  // V0 corr 
+  TH2F* hnV0CC = new  TH2F("V0Corr","V0 Corr signal per Cent.Bin ",nbmltSPD2,0,maxmltSPD2, fNCentBins, -0.5,fNCentBins-0.5);
+  hnV0CC->GetXaxis()->SetTitle("V0 Corr signal");
+  hnV0CC->GetYaxis()->SetTitle("Cent.Bin ID");
+  AddHisto(histos,hnV0CC,kHV0CC);
+  //
+  // TPC 
+  TH2F* hnTPC = new  TH2F("TPCMult","TPC Mult Cent.Bin ",300,0,3000, fNCentBins, -0.5,fNCentBins-0.5);
+  hnTPC->GetXaxis()->SetTitle("TPC Mult");
+  hnTPC->GetYaxis()->SetTitle("Cent.Bin ID");
+  AddHisto(histos,hnTPC,kHMultTPC);
+  //
+  //----------------------------------------------------------------------
+  int nEtaBinsS = int(2*fEtaCut/0.1);
+  if (nEtaBinsS<1) nEtaBins = 1;
+  //
+  int nZVBinsS = int(fZVertexMax-fZVertexMin);
+  if (nZVBinsS<1) nZVBinsS = 1;
+
+  if (fUseMC) {
+    // Z vertex vs Eta distribution for primaries
+    char buffn[100],bufft[500];
+    for (int ib=0;ib<fNCentBins;ib++) {
+      sprintf(buffn,"b%d_zvEtaPrimMC",ib);
+      sprintf(bufft,"bin%d Zvertex vs #eta PrimMC",ib);
+      TH2F* hzvetap = new  TH2F(buffn,bufft, nEtaBinsS,-fEtaCut,fEtaCut,nZVBinsS,fZVertexMin,fZVertexMax);
+      hzvetap->GetXaxis()->SetTitle("#eta");
+      hzvetap->GetYaxis()->SetTitle("Zvertex");
+      AddHisto(histos,hzvetap,kHZVEtaPrimMC+ib);
+    }
+    //
+    // <n> primaries according to MC generator
+    TH1F* hnprimM = new  TH1F("nPrimMean","<N> primaries",fNCentBins, -0.5,fNCentBins-0.5);
+    hnprimM->GetXaxis()->SetTitle("Cent.Bin ID");
+    AddHisto(histos,hnprimM,kHNPrimMeanMC);
+    //
+    // <n> primaries per part.pair according to MC generator
+    TH1F* hnprim2partM = new  TH1F("nPrim2Part","<N> primaries per part.pair",fNCentBins, -0.5,fNCentBins-0.5);
+    hnprim2partM->GetXaxis()->SetTitle("Cent.Bin ID");
+    AddHisto(histos,hnprim2partM,kHNPrim2PartMC);
+    //
+    // <n> primaries per part.pair vs npart.pair according to MC generator
+    TH2F* hnprim2partNp = new  TH2F("nPrim2Part_vs_NPart","<N> primaries per part.pair vs N part.pairs",105,0,210,200,0,40);
+    hnprim2partNp->GetXaxis()->SetTitle("N.part.pairs");
+    hnprim2partNp->GetYaxis()->SetTitle("N.prim/N.part.pairs");
+    AddHisto(histos,hnprim2partNp,kHNPrim2PartNpMC);
+    //
+    // <n> primaries per b.coll vs npart.pair according to MC generator
+    TH2F* hnprim2BCollNp = new  TH2F("nPrim2BColl_vs_NPart","<N> primaries per bin.coll vs N part.pairs",105,0,210,200,0,40);
+    hnprim2BCollNp->GetXaxis()->SetTitle("N.part.pairs");
+    hnprim2BCollNp->GetYaxis()->SetTitle("N.prim/N.bin.coll.");
+    AddHisto(histos,hnprim2BCollNp,kHNPrim2BCollNpMC);
+    //
+    // <n> primaries per bin.coll. according to MC generator
+    TH1F* hnprim2BCollM = new  TH1F("nPrim2BColl","<N> primaries per bin.coll",fNCentBins, -0.5,fNCentBins-0.5);
+    hnprim2BCollM->GetXaxis()->SetTitle("Cent.Bin ID");
+    AddHisto(histos,hnprim2BCollM,kHNPrim2BCollMC);
+    //
+    // n participants according to MC generator
+    TH2F* hnpart = new  TH2F("nPart","N participant pairs",210,0,210,fNCentBins, -0.5,fNCentBins-0.5);
+    hnpart->GetXaxis()->SetTitle("N part. pairs");
+    hnpart->GetYaxis()->SetTitle("Cent.Bin ID");
+    AddHisto(histos,hnpart,kHNPartMC);
+    //
+    // <n> participants according to MC generator
+    TH1F* hnpartM = new  TH1F("nPartMean","<N> participant pairs",fNCentBins, -0.5,fNCentBins-0.5);
+    hnpartM->GetXaxis()->SetTitle("Cent.Bin ID");
+    AddHisto(histos,hnpartM,kHNPartMeanMC);
+    //
+    // n bin coll. according to MC generator
+    TH2F* hnbcoll = new  TH2F("nBColl","N bin. coll",2000,0,2000,fNCentBins, -0.5,fNCentBins-0.5);
+    hnbcoll->GetXaxis()->SetTitle("N bin. coll");
+    hnbcoll->GetYaxis()->SetTitle("Cent.Bin ID");
+    AddHisto(histos,hnbcoll,kHNBCollMC);
+    //
+    // <n> bin col according to MC generator
+    TH1F* hnbcollM = new  TH1F("nBCollMean","<N> bin.colls",fNCentBins, -0.5,fNCentBins-0.5);
+    hnbcollM->GetXaxis()->SetTitle("Cent.Bin ID");
+    AddHisto(histos,hnbcollM,kHNBCollMeanMC);
+    //    
+  }
+  //
+  if (GetDoMixing()) {
+    //
+    // Difference in Z vertex for mixed events
+    TH2F* hzdiff = new TH2F("MixSPDVertexDiff","SPD #Delta Z Vertex distribution per mult bin ",100,-5,5, fNCentBins, -0.5,fNCentBins-0.5);
+    hzdiff->GetXaxis()->SetTitle("#Delta Z Vertex [cm]");
+    hzdiff->GetYaxis()->SetTitle(Form("Entries / %1.2f [cm] per mult bin",10./100.));
+    AddHisto(histos,hzdiff,kHZVtxMixDiff);
+    //
+    // Difference in N tracklets for mixed events
+    TH2F* hntdiff = new TH2F("MixNTrackletsDiff"," SPD tracklets Diff ",200,-1000,1000, fNCentBins, -0.5,fNCentBins-0.5);
+    hntdiff->GetXaxis()->SetTitle("# tracklet diff");
+    AddHisto(histos,hntdiff,kHNTrMixDiff);
+  }
+  // 
+  // --------------------------------------------------
+  if (fUseMC) {
+    int npdg = sizeof(fgkPDGNames)/sizeof(char*);
+    TH2F* hpdgP = new TH2F("pdgPrim","primary PDG",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+    AddHisto(histos,hpdgP,kHPrimPDG);
+    TH2F* hpdgS = new TH2F("pdgSec","secondary PDG",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+    AddHisto(histos,hpdgS,kHSecPDG);
+    TH2F* hpdgPP = new TH2F("pdgPrimPar","primary parent PDG ",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+    AddHisto(histos,hpdgPP,kHPrimParPDG);
+    TH2F* hpdgSP = new TH2F("pdgSecPar","secondary parent PDG",npdg,0,npdg,fNCentBins, -0.5,fNCentBins-0.5);
+    AddHisto(histos,hpdgSP,kHSecParPDG);
+    for (int i=0;i<npdg;i++) {
+      hpdgP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+      hpdgS->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+      hpdgPP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+      hpdgSP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+    }
+  }
+  //
+  // -------------------------------------------------
+  TH2F* hclinf=0;
+  hclinf = new TH2F("cl0InfoUsed","#phi vs Z of used clusters, Lr0",60,-15,15, 80,0,2*TMath::Pi());
+  AddHisto(histos,hclinf,kHClUsedInfoL0);
+  hclinf = new TH2F("cl1InfoUsed","#phi vs Z of used clusters, Lr1",60,-15,15, 2*80,0,2*TMath::Pi());
+  AddHisto(histos,hclinf,kHClUsedInfoL1);
+  hclinf = new TH2F("cl0InfoAll","#phi vs Z of all clusters, Lr0",60,-15,15, 80,0,2*TMath::Pi());
+  AddHisto(histos,hclinf,kHClAllInfoL0);
+  hclinf = new TH2F("cl1InfoAll","#phi vs Z of all clusters, Lr1",60,-15,15, 2*80,0,2*TMath::Pi());
+  AddHisto(histos,hclinf,kHClAllInfoL1);
+  //
+  // -------------------------------------------------
+  histos->SetOwner(kFALSE);
+  //
+  return histos;
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskMulti::BookHistosSet(const char* pref, UInt_t selHistos) 
+{
+  // book standard set of histos attaching the pref in front of the name/title
+  //
+  const int kNDPhiBins = 100;
+  const int kNDThtBins = 100;
+  int nDistBins = int(fNStdDev)*5;
+  //
+  int nEtaBins = int(2*fEtaCut/0.1);
+  if (nEtaBins<1) nEtaBins = 1;
+  //
+  int nZVBins = int(fZVertexMax-fZVertexMin);
+  if (nZVBins<1) nZVBins = 1;
+  float dphir = fDPhiWindow*TMath::Sqrt(fNStdDev);
+  float dthtr = fDThetaWindow*TMath::Sqrt(fNStdDev);
+  //
+  TObjArray* histos = new TObjArray();
+  TH2F* h2;
+  TH1F* h1;
+  char buffn[100],bufft[500];
+  //
+  for (int ib=0;ib<fNCentBins;ib++) {
+    //
+    int offs = ib*kNStandardH;
+    if (selHistos & (0x1<<kHEtaZvCut) ) {
+      sprintf(buffn,"b%d_%s_ZvEtaCutT",ib,pref);
+      sprintf(bufft,"bin%d (%s) Zv vs Eta with tracklet cut",ib,pref);
+      h2 = new TH2F(buffn,bufft,nEtaBins,-fEtaCut,fEtaCut, nZVBins, fZVertexMin,fZVertexMax);
+      h2->GetXaxis()->SetTitle("#eta");
+      h2->GetYaxis()->SetTitle("Zv");
+      AddHisto(histos,h2,offs+kHEtaZvCut);
+    }
+    //
+    if (selHistos & (0x1<<kHDPhiDTheta) ) {
+      sprintf(buffn,"b%d_%s_dPhidTheta",ib,pref);
+      sprintf(bufft,"bin%d (%s) #Delta#theta vs #Delta#varphi",ib,pref);
+      h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+      h2->GetXaxis()->SetTitle("#Delta#varphi [rad]");
+      h2->GetYaxis()->SetTitle("#Delta#theta [rad]");
+      AddHisto(histos,h2,offs+kHDPhiDTheta);
+    }
+    //
+    if (selHistos & (0x1<<kHDPhiSDThetaX) ) {
+      sprintf(buffn,"b%d_%s_dPhiSdThetaX",ib,pref);
+      sprintf(bufft,"bin%d (%s) #Delta#theta%s vs #Delta#varphi-#delta_{#varphi}",ib,pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+      h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+      h2->GetXaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+      sprintf(bufft,"#Delta#theta%s",fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+      h2->GetYaxis()->SetTitle(bufft);
+      AddHisto(histos,h2,offs+kHDPhiSDThetaX);
+    }
+    //
+    if (selHistos & (0x1<<kHWDist) ) {
+      sprintf(buffn,"b%d_%s_WDist",ib,pref);
+      sprintf(bufft,"bin%d #Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+             "[#Delta#theta%s/#sigma#theta]^{2}",ib,fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+      h1 = new TH1F(buffn,bufft,nDistBins,0,fNStdDev);
+      sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+             "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+      h1->GetXaxis()->SetTitle(bufft);
+      AddHisto(histos,h1,offs+kHWDist);
+    }
+    //
+  }
+  //
+  histos->SetOwner(kFALSE);
+  return histos;
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::AddHisto(TObjArray* histos, TObject* h, Int_t at)
+{
+  // add single histo to the set
+  if (at>=0) histos->AddAtAndExpand(h,at);
+  else       histos->Add(h);
+  fOutput->Add(h);
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::FillHistos(Int_t type, const AliMultiplicity* mlt)
+{
+  // fill histos of given type
+  if (!mlt) return;
+  //
+  TObjArray* histos = 0;
+  if      (type == kData)  histos = fHistosTrData;
+  else if (type == kBgInj) histos = fHistosTrInj;
+  else if (type == kBgRot) histos = fHistosTrRot;
+  else if (type == kBgMix) histos = fHistosTrMix;
+  //
+  Bool_t fillMC = (type==kData) && fUseMC && fStack;
+  //
+  //
+  //---------------------------------------- CHECK ------------------------------>>>
+  TArrayF vtxMC;
+  AliGenHijingEventHeader* pyHeader = 0;
+  //
+  if (fUseMC) {
+    pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+    pyHeader->PrimaryVertex(vtxMC);
+  }
+  //---------------------------------------- CHECK ------------------------------<<<
+  //
+  if (!histos) return;
+  int ntr = mlt->GetNumberOfTracklets();
+  for (int itr=ntr;itr--;) {
+    //
+    //---------------------------------------- CHECK ------------------------------>>>
+    /*
+    if (fUseMC) {
+      Bool_t reject = kFALSE;
+      while(1) {
+       int lab0 = mlt->GetLabel(itr,0);
+       int lab1 = mlt->GetLabel(itr,1);
+       if (lab0!=lab1) break;
+       if (!fStack->IsPhysicalPrimary(lab0)) break;
+       //
+       TParticle* part = fStack->Particle(lab0);
+       Float_t dz = part->Vz() - vtxMC[2];
+       if (TMath::Abs(dz)<1e-6) break;
+       reject = kTRUE; 
+       break;
+      }
+      if (reject) continue;
+    }
+    */
+    //---------------------------------------- CHECK ------------------------------<<<
+    //
+    double theta  = mlt->GetTheta(itr);
+    double eta    = -TMath::Log(TMath::Tan(theta/2));
+    if (TMath::Abs(eta)>fEtaCut) continue;
+    //
+    double dtheta = mlt->GetDeltaTheta(itr);
+    double dThetaX = dtheta;
+    if (fScaleDTBySin2T) {
+      double sint   =  TMath::Sin(theta);
+      dThetaX /= (sint*sint);
+    }
+    if (fCutOnDThetaX && TMath::Abs(dThetaX)>fDThetaWindow) continue;
+    //    double phi    = mlt->GetPhi(itr);
+    double dphi   = mlt->GetDeltaPhi(itr);
+    double dist   = mlt->CalcDist(itr);
+    //
+    FillHistosSet(histos,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist);
+    // special handling for mc info
+    if (fillMC && fStack) {
+      int lab0 = mlt->GetLabel(itr,0);
+      int lab1 = mlt->GetLabel(itr,1);
+      int typeMC = 2; // comb.bg.
+      if (lab0 == lab1)        typeMC = fStack->IsPhysicalPrimary(lab0) ? 0:1; // prim or sec
+      if      (typeMC==0) FillHistosSet(fHistosTrPrim,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist); // primary
+      else if (typeMC==1) FillHistosSet(fHistosTrSec, eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist); // secondary
+      else {
+       FillHistosSet(fHistosTrComb,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist); // comb
+       // for combinatorals fill also the uncorrelated part
+       if (fMultReco) {
+         float *trl = fMultReco->GetTracklet(itr);
+         int clId0 = (int)trl[AliITSMultReconstructor::kClID1];
+         int clId1 = (int)trl[AliITSMultReconstructor::kClID2];
+         float *clLabs0 = fMultReco->GetClusterOfLayer(0,clId0) + AliITSMultReconstructor::kClMC0;
+         float *clLabs1 = fMultReco->GetClusterOfLayer(1,clId1) + AliITSMultReconstructor::kClMC0;
+         if (!HaveCommonParent(clLabs0,clLabs1)) 
+           FillHistosSet(fHistosTrCombU,eta,/*phi,theta,*/dphi,dtheta,dThetaX,dist);
+       }
+      } // combinatorials
+      
+      if (dist<fNStdCut) {
+       double dphiS  = TMath::Abs(dphi) - fDPhiShift; if (dphi<0) dphiS = -dphiS;
+       if (dphiS<fDPhiSCut) FillSpecies(typeMC, lab0);
+      }
+      if (fCheckReconstructables) CheckReconstructables();
+    }
+  }
+  //
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::FillMCPrimaries()
+{
+  // fill all MC primaries Zv vs Eta
+  if (!fStack || !fMCEvent) return;
+
+  //---------------------------------------- CHECK ------------------------------>>>
+  TArrayF vtxMC;
+  AliGenHijingEventHeader* pyHeader = 0;
+  //
+  if (fUseMC) {
+    pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+    pyHeader->PrimaryVertex(vtxMC);
+  }
+  //---------------------------------------- CHECK ------------------------------<<<
+  //
+  int ntr = fStack->GetNtrack();
+  TH2* hprimEtaZ = (TH2F*)fHistosCustom->UncheckedAt(kHZVEtaPrimMC+fCurrCentBin);
+  int nprim = 0;
+  for (int itr=ntr;itr--;) {
+    if (!fStack->IsPhysicalPrimary(itr)) continue;
+    AliMCParticle *part  = (AliMCParticle*)fMCEvent->GetTrack(itr);
+    if (!part->Charge()) continue;
+    //
+    //---------------------------------------- CHECK ------------------------------>>>
+    /*
+    Float_t dz = part->Zv() - vtxMC[2];
+    if (TMath::Abs(dz)>1e-6) continue; // reject
+    */
+    //---------------------------------------- CHECK ------------------------------<<<
+    //
+    Float_t theta = part->Theta();
+    if (theta<1e-6 || theta>TMath::Pi()-1e-6) continue;
+    Float_t eta = part->Eta();
+    if (TMath::Abs(eta)>fEtaCut) continue;
+    hprimEtaZ->Fill(eta, fESDVtx[2]);
+    nprim++;
+  }
+  //
+  ((TH1*)fHistosCustom->UncheckedAt(kHNPrimMeanMC))->Fill(fCurrCentBin,nprim);
+  if (fNPart>0) {
+    ((TH1*)fHistosCustom->UncheckedAt(kHNPrim2PartMC))->Fill(fCurrCentBin,nprim/fNPart);
+    ((TH2*)fHistosCustom->UncheckedAt(kHNPrim2PartNpMC))->Fill(fNPart,nprim/fNPart);
+    ((TH2*)fHistosCustom->UncheckedAt(kHNPartMC))->Fill(fNPart,fCurrCentBin);
+    ((TH1*)fHistosCustom->UncheckedAt(kHNPartMeanMC))->Fill(fCurrCentBin,fNPart);
+  }
+  if (fNBColl>0) {
+    ((TH1*)fHistosCustom->UncheckedAt(kHNPrim2BCollMC))->Fill(fCurrCentBin,nprim/fNBColl);
+    ((TH2*)fHistosCustom->UncheckedAt(kHNPrim2BCollNpMC))->Fill(fNPart,nprim/fNBColl);
+    ((TH2*)fHistosCustom->UncheckedAt(kHNBCollMC))->Fill(fNBColl,fCurrCentBin);
+    ((TH1*)fHistosCustom->UncheckedAt(kHNBCollMeanMC))->Fill(fCurrCentBin,fNBColl);
+  }
+  //
+}
+
+//_________________________________________________________________________
+ void AliTrackletTaskMulti::FillHistosSet(TObjArray* histos, double eta,
+                                         //double /*phi*/,double /*theta*/,
+                                         double dphi,double dtheta,double dThetaX,
+                                         double dist) 
+{
+  // fill standard set of histos
+  if (dist>fNStdDev) return;
+  //
+  double dphiS  = TMath::Abs(dphi) - fDPhiShift;
+  if (dphi<0) dphiS = -dphiS;
+  //
+  int offs = fCurrCentBin*kNStandardH;
+  //
+  if (histos->UncheckedAt(offs+kHDPhiSDThetaX)) 
+    ((TH2*)histos->UncheckedAt(offs+kHDPhiSDThetaX))->Fill(dphiS,dThetaX);
+  //
+  if (histos->UncheckedAt(offs+kHDPhiDTheta)) 
+    ((TH2*)histos->UncheckedAt(offs+kHDPhiDTheta))->Fill(dphi,dtheta);
+  //
+  if (histos->UncheckedAt(kHWDist))
+    ((TH2*)histos->UncheckedAt(offs+kHWDist))->Fill(dist);
+  //
+  if (dist<fNStdCut && dphiS<fDPhiSCut && histos->UncheckedAt(offs+kHEtaZvCut))
+    ((TH2*)histos->UncheckedAt(offs+kHEtaZvCut))->Fill(eta,fESDVtx[2]);
+  //
+}
+//__________________________________________________________________
+void AliTrackletTaskMulti::FillSpecies(Int_t primsec, Int_t id)
+{
+  // fill PDGcode 
+  TH1 *hPart=0,*hParent=0;
+  if (primsec==0) {
+    hPart   = (TH1*)fHistosCustom->UncheckedAt(kHPrimPDG);
+    hParent = (TH1*)fHistosCustom->UncheckedAt(kHPrimParPDG);
+  } 
+  else if (primsec==1) {
+    hPart   = (TH1*)fHistosCustom->UncheckedAt(kHSecPDG);
+    hParent = (TH1*)fHistosCustom->UncheckedAt(kHSecParPDG);    
+  }
+  else return;
+  int ntr = fStack->GetNtrack();
+  TParticle* part = fStack->Particle(id);
+  int pdgCode = TMath::Abs(part->GetPdgCode());
+  int pdgBin = GetPdgBin(pdgCode);
+  int parID = part->GetFirstMother();
+  int pdgCodePar = -1;
+  int pdgBinPar = -1;
+  while (parID>=0 && parID<ntr) {
+    part = fStack->Particle(parID);
+    pdgCodePar = TMath::Abs(part->GetPdgCode());
+    parID = part->GetFirstMother();
+  }
+  if (pdgCodePar>0) pdgBinPar = GetPdgBin(pdgCodePar);
+  //
+  hPart->Fill(pdgBin,fCurrCentBin);
+  hParent->Fill(pdgBinPar,fCurrCentBin);
+  //
+}
+
+//_________________________________________________________________________
+Int_t AliTrackletTaskMulti::GetCentralityBin(Float_t multX, Float_t multY)
+{
+  // calculate centrality bin
+  if (fUseCentralityVar<kCent2D) { // 1D bins
+    for (int i=0;i<fNCentBins;i++) if (multX>=fkCentBinDef[i] && multX<fkCentBinDef[i+1]) return i;
+  }
+  else {
+    for (int i=fNCentBins;i--;) {
+      // X on boundary corresponding to multY
+      float xOnLineUp = (multY-fkCentBinDef2DY[i+1])/fkCentBinDef2DS[i+1] + fkCentBinDef[i+1];
+      float xOnLineLw = (multY-fkCentBinDef2DY[i]) / fkCentBinDef2DS[i]   + fkCentBinDef[i];
+      if (multX>=xOnLineLw && multX<xOnLineUp) return i;
+    }
+  }
+  return -1;
+}
+
+//_________________________________________________________________________
+Int_t AliTrackletTaskMulti::GetPdgBin(Int_t pdgCode)
+{
+  // return my pdg bin
+  int ncodes = sizeof(fgkPDGCodes)/sizeof(int);
+  int pdgBin=0;
+  for (pdgBin=0;pdgBin<ncodes;pdgBin++) if (pdgCode==fgkPDGCodes[pdgBin]) break;
+  if (pdgBin>=ncodes) {
+    if (float(pdgCode)>1e9) pdgBin = ncodes; // nuclei
+    else pdgBin = ncodes+1; // unknown
+  }
+  return pdgBin;
+}
+
+//_________________________________________________________________________
+Bool_t AliTrackletTaskMulti::HaveCommonParent(const float* clLabs0,const float* clLabs1)
+{
+  // do 2 clusters have common parrent
+  const int kMaxPar = 50;
+  static int pars[2][50];
+  int npars[2]={0,0};
+  const float *labs[2] = {clLabs0,clLabs1};
+  int ntr = fStack->GetNtrack();
+  for (int il=0;il<2;il++) {
+    for (int ilb=0;ilb<3;ilb++) {
+      int lbl = (int)labs[il][ilb];
+      if (lbl<0 || lbl>=ntr) continue;
+      //
+      while (npars[il]<kMaxPar-1) {
+       pars[il][ npars[il]++ ] = lbl;
+       TParticle* part = fStack->Particle(lbl);
+       if (!part) break;
+       lbl = part->GetFirstMother();
+       if (lbl<1 || lbl>=ntr) break;
+      }
+    }
+  }
+  // compare array of parents
+  for (int i0=npars[0];i0--;) for (int i1=npars[1];i1--;) if (pars[0][i0]==pars[1][i1]) return kTRUE;
+  return kFALSE;
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::CheckReconstructables()
+{
+  // fill reconstructable tracklets hitsos
+  static TArrayI trInd;
+  static TBits   isPrimArr;
+  //
+  if (!fMultReco || !fMultReco->IsRecoDone()) {AliInfo("To check reconstructables the reco had to be requested"); return;}
+  if (!fStack) {AliInfo("MC Stack is not availalble"); return;}
+  const double kPtMin = 0.05;
+  //
+  TClonesArray *clArr[2];
+  for (int ilr=0;ilr<2;ilr++) {
+    clArr[ilr] = fMultReco->GetClustersOfLayer(ilr);
+    if (!clArr[ilr]) {AliInfo("Clusters are not available"); return;}
+  }
+  //
+  int ntr = fStack->GetNtrack();
+  if (!ntr) return;
+  trInd.Reset();
+  if (trInd.GetSize()<ntr) trInd.Set(ntr);
+  isPrimArr.ResetAllBits();
+  // count track wich may be reconstructable
+  //
+  int ntrStore=0,ntrStorePrim=0; 
+  Int_t *trIndArr = trInd.GetArray();
+  for (Int_t it=0; it<ntr; it++) {
+    TParticle* part = fStack->Particle(it);
+    if (TMath::Abs(part->Eta())>2.2)       continue;
+    if (TMath::Abs(part->Pt())<kPtMin)      continue;
+    if (fStack->IsPhysicalPrimary(it)) {
+      isPrimArr.SetBitNumber(it);
+      ntrStorePrim++;
+    }
+    else { // check if secondary is worth cheking
+      TParticlePDG* pdgPart = part->GetPDG();
+      if (TMath::Abs(pdgPart->Charge())!=3)  continue;
+      if (part->R()>5.)                      continue;
+    }
+    trIndArr[it] = ++ntrStore;
+  }
+  //
+  AliInfo(Form("Selected %d MC particles (%d prim) out of %d in the stack\n",ntrStore,ntrStorePrim,ntr));
+  //
+  const int kMaxCl=3;
+  AliITSRecPoint **clIndL[2];
+  clIndL[0] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+  clIndL[1] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+  memset(clIndL[0],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+  memset(clIndL[1],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+  //
+  for (int ilr=0;ilr<2;ilr++) {
+    TClonesArray *clusters = clArr[ilr];
+    int ncl = clusters->GetEntriesFast();
+    for (int icl=ncl;icl--;) {
+      AliITSRecPoint *cl = (AliITSRecPoint*)clusters->UncheckedAt(icl);
+      for (int ilb=3;ilb--;) {
+       int lbl = cl->GetLabel(ilb); if (lbl<0 || lbl>=ntr) continue;
+       int lblI = trIndArr[lbl];
+       if (--lblI<0) continue;    // not kept
+       for (int icc=0;icc<kMaxCl;icc++) if (!clIndL[ilr][lblI+icc*ntrStore]) {clIndL[ilr][lblI+ntrStore*icc] = cl; break;} // first empty one
+      }
+    }
+  }
+  //
+  Float_t clusterLay[2][AliITSMultReconstructor::kClNPar];
+  double trComp[6][kMaxCl*kMaxCl];
+  int indQual[kMaxCl*kMaxCl];
+  //
+  for (int itr=ntr;itr--;) {
+    int lblI = trIndArr[itr];
+    if (--lblI<0) continue; // discarded
+    int ntrCand = 0;        // number of tracklet candidates (including overlaps)
+    for (int icl0=0;icl0<kMaxCl;icl0++) {
+      AliITSRecPoint *cl0 = clIndL[0][lblI+icl0*ntrStore];
+      if (!cl0 || !clIndL[1][lblI]) break;
+      cl0->GetGlobalXYZ( clusterLay[0] );
+      fMultReco->ClusterPos2Angles(clusterLay[0], fESDVtx);
+      for (int icl1=0;icl1<kMaxCl;icl1++) {
+       AliITSRecPoint *cl1 = clIndL[1][lblI+icl1*ntrStore];
+       if (!cl1) break;
+       cl1->GetGlobalXYZ( clusterLay[1] );
+       fMultReco->ClusterPos2Angles(clusterLay[1], fESDVtx);
+       trComp[AliITSMultReconstructor::kTrPhi][ntrCand]    = clusterLay[0][AliITSMultReconstructor::kClPh];
+       trComp[AliITSMultReconstructor::kTrTheta][ntrCand]  = clusterLay[0][AliITSMultReconstructor::kClTh];      
+       trComp[AliITSMultReconstructor::kTrDTheta][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClTh] - clusterLay[1][AliITSMultReconstructor::kClTh]; 
+       trComp[AliITSMultReconstructor::kTrDPhi][ntrCand]   = clusterLay[0][AliITSMultReconstructor::kClPh] - clusterLay[1][AliITSMultReconstructor::kClPh];
+       trComp[AliITSMultReconstructor::kTrLab1][ntrCand]   = icl1*10 + icl0;
+       double &dphi = trComp[ntrCand][3];
+       if (dphi>TMath::Pi()) dphi=2.*TMath::Pi()-dphi;     // take into account boundary condition
+       trComp[5][ntrCand] = fMultReco->CalcDist(trComp[AliITSMultReconstructor::kTrDPhi][ntrCand], 
+                                                trComp[AliITSMultReconstructor::kTrDTheta][ntrCand], 
+                                                trComp[AliITSMultReconstructor::kTrTheta][ntrCand]);
+       ntrCand++;
+      }
+    }
+    if (!ntrCand) continue; // no tracklets
+    if (ntrCand>1) TMath::Sort(ntrCand,trComp[5],indQual,kFALSE); else indQual[0] = 0; // sort in weighted distance
+    if (fRemoveOverlaps) ntrCand = 1; // select the best
+    //
+    // disable worst tracklet with shared cluster
+    for (int itc=0;itc<ntrCand;itc++) {
+      int ind = indQual[itc];
+      if (trComp[AliITSMultReconstructor::kTrLab1][ind]<0) continue; // already disabled
+      for (int jtc=itc+1;jtc<ntrCand;jtc++) {
+       int jnd = indQual[jtc];
+       if (trComp[AliITSMultReconstructor::kTrLab1][jnd]<0) continue; // already disabled
+       if ( int(trComp[AliITSMultReconstructor::kTrLab1][ind])/10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])/10 ||
+            int(trComp[AliITSMultReconstructor::kTrLab1][ind])%10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])%10) trComp[AliITSMultReconstructor::kTrLab1][jnd] = -1;
+      }
+    }
+    //
+    // store, but forbid cluster reusing
+    TObjArray* histos = isPrimArr.TestBitNumber(itr) ? fHistosTrRcblPrim : fHistosTrRcblSec;
+    for (int itc=0;itc<ntrCand;itc++) {
+      int ind = indQual[itc];
+      if (trComp[4][ind]<0) continue; // discarded
+      double eta    = -TMath::Log(TMath::Tan(trComp[AliITSMultReconstructor::kTrTheta][ind]/2));
+      if (TMath::Abs(eta)>fEtaCut) continue;
+      double dThetaX = trComp[AliITSMultReconstructor::kTrTheta][ind];
+      if (fScaleDTBySin2T) {
+       double sint   =  TMath::Sin(trComp[AliITSMultReconstructor::kTrTheta][ind]);
+       dThetaX /= (sint*sint);
+      }
+      FillHistosSet(histos,eta,
+                   //trComp[AliITSMultReconstructor::kTrPhi][ind],trComp[AliITSMultReconstructor::kTrTheta][ind],
+                   trComp[AliITSMultReconstructor::kTrDPhi][ind],trComp[AliITSMultReconstructor::kTrDTheta][ind],
+                   dThetaX,trComp[5][ind]);
+    }
+  }
+  //
+  delete[] clIndL[0];
+  delete[] clIndL[1];
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskMulti::FillClusterInfo()
+{
+  // fill info on clusters associated to good tracklets
+  if (!fMultReco) return;
+  int ntr = fMultReco->GetNTracklets();
+  int clID[2];
+  TH2F *hclU[2] = {(TH2F*)fHistosCustom->UncheckedAt(kHClUsedInfoL0),(TH2F*)fHistosCustom->UncheckedAt(kHClUsedInfoL1)};
+  TH2F *hclA[2] = {(TH2F*)fHistosCustom->UncheckedAt(kHClAllInfoL0),(TH2F*)fHistosCustom->UncheckedAt(kHClAllInfoL1)};
+  for (int itr=ntr;itr--;) {
+    Float_t *trc = fMultReco->GetTracklet(itr);
+    if (TMath::Abs(TMath::Abs(trc[AliITSMultReconstructor::kTrDPhi])-fDPhiShift)>fDPhiSCut) continue;
+    if (fMultReco->CalcDist(trc[AliITSMultReconstructor::kTrDPhi],
+                           trc[AliITSMultReconstructor::kTrDTheta],
+                           trc[AliITSMultReconstructor::kTrTheta]) > fNStdCut) continue;
+    clID[0] = (int)trc[AliITSMultReconstructor::kClID1];
+    clID[1] = (int)trc[AliITSMultReconstructor::kClID2];
+    for (int il=0;il<2;il++) {
+      Float_t *clinf = fMultReco->GetClusterOfLayer(il,clID[il]);
+      hclU[il]->Fill( clinf[AliITSMultReconstructor::kClZ], clinf[AliITSMultReconstructor::kClPh]);
+    }
+  }
+  //
+  for (int il=0;il<2;il++) for (int ic=fMultReco->GetNClustersLayer(il);ic--;) {
+      Float_t *clinf = fMultReco->GetClusterOfLayer(il,ic);
+      hclA[il]->Fill( clinf[AliITSMultReconstructor::kClZ], clinf[AliITSMultReconstructor::kClPh]);
+    }
+  //
+}
+
+
+//_________________________________________________________________
+Bool_t AliTrackletTaskMulti::ZDCTimeTrigger(const AliESDEvent *aEsd) const
+{
+  // This method implements a selection
+  // based on the timing in both sides of zdcN
+  // It can be used in order to eliminate
+  // parasitic collisions
+  Bool_t zdcAccept = kFALSE;
+
+  AliESDZDC *esdZDC = aEsd->GetESDZDC();
+
+  const Float_t refSum = -568.5;
+  const Float_t refDelta = -2.1;
+  const Float_t sigmaSum = 3.25;
+  const Float_t sigmaDelta = 2.25;
+  for(Int_t i = 0; i < 4; ++i) {
+    if (esdZDC->GetZDCTDCData(10,i) != 0) {
+      Float_t tdcC = 0.025*(esdZDC->GetZDCTDCData(10,i)-esdZDC->GetZDCTDCData(14,i)); 
+      for(Int_t j = 0; j < 4; ++j) {
+       if (esdZDC->GetZDCTDCData(12,j) != 0) {
+         Float_t tdcA = 0.025*(esdZDC->GetZDCTDCData(12,j)-esdZDC->GetZDCTDCData(14,j));
+         if (((tdcC-tdcA-refDelta)*(tdcC-tdcA-refDelta)/(sigmaDelta*sigmaDelta) +
+              (tdcC+tdcA-refSum)*(tdcC+tdcA-refSum)/(sigmaSum*sigmaSum))< 1.0)
+           zdcAccept = kTRUE;
+       }
+      }
+    }
+  }
+  return zdcAccept;
+}
diff --git a/PWG0/multVScentPbPb/AliTrackletTaskMulti.h b/PWG0/multVScentPbPb/AliTrackletTaskMulti.h
new file mode 100755 (executable)
index 0000000..b2d7fa6
--- /dev/null
@@ -0,0 +1,285 @@
+#ifndef ALITRACKLETTASKMULTI_H
+#define ALITRACKLETTASKMULTI_H
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTaskMulti                                            //
+// Analysis task to produce data and MC histos needed for tracklets      //
+// dNdEta extraction in multiple bins in one go                          //
+// Author:  ruben.shahoyan@cern.ch                                       //
+///////////////////////////////////////////////////////////////////////////
+
+class TH1F; 
+class TH2F;
+class AliESDEvent;
+class TList;
+class TNtuple;
+
+class AliMCParticle;
+class AliITSMultRecBg;
+class AliESDTrackCuts;
+
+#include "../ITS/AliITSsegmentationSPD.h"
+#include "AliAnalysisTaskSE.h"
+#include "AliTriggerAnalysis.h" 
+
+class AliTrackletTaskMulti : public AliAnalysisTaskSE {
+ public:
+  enum {kData,kBgInj,kBgRot,kBgMix,kMC};
+  enum {kCentSPD2, kCentV0,  kCentV0CR, kCentTrTPC, 
+       kCent2D=9, // just a separator between 1D and 2D bins
+       kCentZDCV0};   // what is used to define centrality
+  //
+  enum {  // define here id's of the standard histos in corresponding TObjArray* fHistosTr...
+    kHEtaZvCut,       // histo zv vs eta for tracklets passing final selection (dist<1 or |dPhi|<narrowWindow ...)
+    kHDPhiDTheta,     // measured dTheta vs dPhi
+    kHDPhiSDThetaX,   // dTheta (1/sin^2 scaled if needed) vs dPhi (bending subtracted)
+    kHWDist,          // Weighted distance 
+    kNStandardH       // number of standard histos per centrality bin
+  };
+  enum { // define here id's of any custom histos to be added to fHistosCustom
+    kHStat,            // job info (meaning of bins defined in the enum below)
+    //
+    kHStatCent,        // events per centrality bin with real values on the axis
+    kHStatCentBin,     // events per centrality bin
+    //
+    kHNPrimMeanMC,     // <n> primaries per mult bin
+    kHNPrim2PartMC,    // <n> prim per part.pair per mult bin
+    kHNPrim2BCollMC,   // <n> prim per bin.coll per mult bin
+    kHNPrim2PartNpMC,  // <n> prim per n part vs npart
+    kHNPrim2BCollNpMC, // <n> prim per n part vs npart
+    kHNPartMC,         // n.part.pairs according to MC
+    kHNPartMeanMC,     // <n> part pairs per mult bin
+    kHNBCollMC,        // n.bin.colls according to MC
+    kHNBCollMeanMC,
+    //
+    kHZVtxNoSel,       // Z vertex distribution before event selection
+    kHNTrackletsNoSel, // N tracklets before event selection
+    kHNClSPD1NoSel,    // N clusters on SPD1 before event selection
+    kHNClSPD2NoSel,    // N clusters on SPD2 before event selection
+    kHV0NoSel,         // V0 mult before selection
+    kHV0CCNoSel,       // V0 corr (Cvetan) mult before selection
+    kHV0NClSPD2NoSel,  // V0 - nspd2 correlation
+    kHV0CCNClSPD2NoSel,// V0 corr - nspd2 correlation
+    kHMultTPCNoSel,    // TPC ref.mult
+    //
+    kHZVtx,            // Z vertex distribution
+    kHNTracklets,      // N tracklets
+    kHNClSPD1,         // N clusters on SPD1
+    kHNClSPD2,         // N clusters on SPD2
+    kHV0,              // V0 mult after selection
+    kHV0CC,            // V0 corr mult after selection
+    kHMultTPC,         // TPC ref.mult
+    //
+    kHZVtxMixDiff,     // difference in Z vtx of mixed events
+    kHNTrMixDiff,      // difference in N tracklets of mixed events
+    //
+    kHPrimPDG,         // PDG code of prim tracklet
+    kHSecPDG,          // PDG code of sec tracklet
+    kHPrimParPDG,      // PDG code of prim tracklet parent
+    kHSecParPDG,       // PDG code of sec tracklet parent
+    //
+    kHClUsedInfoL0,    // used clusters of lr0
+    kHClUsedInfoL1,    // used clusters of lr1
+    kHClAllInfoL0,     // all clusters of lr0
+    kHClAllInfoL1,     // all clusters of lr1
+    //
+    // This MUST be last one: this is just beginning of many histos (one per bin)
+    kHZVEtaPrimMC      // Zv vs eta for all primary tracks (true MC multiplicity)
+  }; // custom histos
+
+  // bins for saved parameters
+  enum {kDummyBin,
+       kEvTot,       // events read
+       kOneUnit,     // just 1 to track primate merges
+       kNWorkers,    // n workers
+       //
+       kDPhi,        // dphi window
+       kDTht,        // dtheta window
+       kNStd,        // N.standard deviations to keep
+       kPhiShift,    // bending shift
+       kThtS2,       // is dtheta scaled by 1/sin^2
+       kThtCW,       // on top of w.dist cut cut also on 1 sigma dThetaX
+       kPhiOvl,      // overlap params
+       kZEtaOvl,     // overlap params
+       kNoOvl,       // flag that overlap are suppressed
+       //
+       kPhiRot,      // rotation phi
+       kInjScl,      // injection scaling
+       kEtaCut,      // eta cut
+       kZVMin,       // min ZVertex to process
+       kZVMax,       // max ZVertex to process
+       //
+       kDPiSCut,     // cut on dphi used to extract signal (when WDist is used in analysis, put it equal to kDPhi
+       kNStdCut,     // cut on weighted distance (~1) used to extract signal 
+       //
+       kMCV0Scale,   // scaling value for V0 in MC
+       //
+       // here we put entries for each mult.bin
+       kBinEntries = 50,
+       kEvProcData,  // events with data mult.object (ESD or reco)
+       kEvProcInj,   // events Injected, total
+       kEvProcRot,   // events Rotated
+       kEvProcMix,   // events Mixed
+       kEntriesPerBin
+  };
+
+  //
+  AliTrackletTaskMulti(const char *name = "AliTrackletTaskMulti");
+  virtual ~AliTrackletTaskMulti(); 
+  
+  virtual void  UserCreateOutputObjects();
+  virtual void  UserExec(Option_t *option);
+  virtual void  Terminate(Option_t *);
+
+  void       SetUseCentralityVar(Int_t v=kCentV0)      {fUseCentralityVar = v;}
+  void       SetUseMC(Bool_t mc = kFALSE)              {fUseMC = mc;}
+  void       SetCheckReconstructables(Bool_t c=kFALSE) {fCheckReconstructables = c;}
+  TObjArray* BookHistosSet(const char* pref, UInt_t selHistos=0xffffffff);
+  TObjArray* BookCustomHistos();
+  void       AddHisto(TObjArray* histos, TObject* h, Int_t at=-1);
+  void       FillHistosSet(TObjArray* histos, double eta, /*double phi,double theta,*/double dphi,double dtheta,double dthetaX,double dist);
+  // RS
+  void       SetNStdDev(Float_t f=1.)           {fNStdDev = f<1e-5 ? 1e-5:f;}
+  void       SetScaleDThetaBySin2T(Bool_t v=kFALSE) {fScaleDTBySin2T = v;}
+  void       SetCutOnDThetaX(Bool_t v=kFALSE)   {fCutOnDThetaX = v;}
+  void       SetPhiWindow(float w=0.08)         {fDPhiWindow   = w<1e-5 ? 1e-5:w;}
+  void       SetThetaWindow(float w=0.025)      {if (w<0) fCutOnDThetaX=kTRUE; fDThetaWindow = TMath::Abs(w)<1e-5 ? 1e-5:TMath::Abs(w);}
+  void       SetPhiShift(float w=0.0045)        {fDPhiShift = w;}
+  void       SetPhiOverlapCut(float w=0.005)    {fPhiOverlapCut = w;}
+  void       SetZetaOverlapCut(float w=0.05)    {fZetaOverlap = w;}
+  void       SetPhiRot(float w=0)               {fPhiRot = w;}
+  void       SetInjScale(Float_t s=1.)          {fInjScale = s>0? s:1.;}
+  void       SetRemoveOverlaps(Bool_t w=kFALSE) {fRemoveOverlaps = w;}
+  //
+  void       SetDPhiSCut(Float_t c=0.06)        {fDPhiSCut = c;}
+  void       SetNStdCut(Float_t c=1.0)          {fNStdCut = c;}
+  void       SetScaleMCV0(Float_t s=1.0)        {fMCV0Scale = s;}  
+  //
+  void       SetEtaCut(Float_t eta)             {fEtaCut = eta;}
+  void       SetZVertexMin(Float_t z)           {fZVertexMin = z;}
+  void       SetZVertexMax(Float_t z)           {fZVertexMax = z;}
+  //
+  Bool_t     GetDoNormalReco()             const {return fDoNormalReco;}
+  Bool_t     GetDoInjection()              const {return fDoInjection;}
+  Bool_t     GetDoRotation()               const {return fDoRotation;}
+  Bool_t     GetDoMixing()                 const {return fDoMixing;}
+  //
+  void       SetDoNormalReco(Bool_t v=kTRUE)    {fDoNormalReco = v;}
+  void       SetDoInjection(Bool_t v=kTRUE)     {fDoInjection = v;}
+  void       SetDoRotation(Bool_t v=kTRUE)      {fDoRotation = v;}
+  void       SetDoMixing(Bool_t v=kTRUE)        {fDoMixing = v;}
+  //
+  /*
+  void       SetTrigger(AliTriggerAnalysis::Trigger trigger)  { fTrigger = trigger; }
+  void       SetMCCentralityBin(MCCentralityBin mccentrbin)   { fMCCentralityBin = mccentrbin;}
+  void       SetCentralityLowLim(Float_t centrlowlim)         { fCentrLowLim = centrlowlim;}
+  void       SetCentralityUpLim(Float_t centruplim)           { fCentrUpLim = centruplim;}
+  void       SetCentralityEst(TString centrest)               { fCentrEst = centrest;}
+  */
+  //
+ protected:
+  void       InitMultReco();
+  Bool_t     HaveCommonParent(const float* clLabs0,const float* clLabs1);
+  void       FillHistos(Int_t type, const AliMultiplicity* mlt);
+  void       FillMCPrimaries();
+  void       FillSpecies(Int_t primsec, Int_t id);
+  void       FillClusterInfo();
+  Int_t      GetPdgBin(Int_t pdgCode);
+  void       CheckReconstructables();
+  Int_t      GetCentralityBin(Float_t multX, Float_t multY=-1);
+  Float_t    GetCorrSPD2(Float_t spd2raw,Float_t zv) const;
+  Float_t    GetCorrV0(const AliESDEvent* esd, float &v0CorrResc) const;
+  Bool_t     ZDCTimeTrigger(const AliESDEvent *aEsd) const;
+  //
+ protected:
+  TList*       fOutput;                   // output list send on output slot 1 
+  //
+  Bool_t       fDoNormalReco;              // do normal reco
+  Bool_t       fDoInjection;               // do injection
+  Bool_t       fDoRotation;                // do rotation
+  Bool_t       fDoMixing;                  // do mixing
+  //
+  Bool_t       fUseMC; 
+  Bool_t       fCheckReconstructables;
+  //
+  TObjArray*   fHistosTrData;              //! all tracklets in data
+  TObjArray*   fHistosTrInj;               //! injected
+  TObjArray*   fHistosTrRot;               //! rotated
+  TObjArray*   fHistosTrMix;               //! mixed
+  //
+  TObjArray*   fHistosTrPrim;              //! primary
+  TObjArray*   fHistosTrSec;               //! secondary
+  TObjArray*   fHistosTrComb;              //! combinatorials
+  TObjArray*   fHistosTrCombU;             //! combinatorials uncorrelated
+  //
+  TObjArray*   fHistosTrRcblPrim;          //! Primary Reconstructable
+  TObjArray*   fHistosTrRcblSec;           //! Secondary Reconstructable
+  TObjArray*   fHistosCustom;              //! custom histos
+  //
+  // Settings for the reconstruction
+  // tracklet reco settings
+  Float_t      fEtaCut;                    // histos filled only for this eta range
+  Float_t      fZVertexMin;                // min Z vtx to process
+  Float_t      fZVertexMax;                // max Z vtx to process
+  //
+  Bool_t       fScaleDTBySin2T;            // request dTheta scaling by 1/sin^2(theta)
+  Bool_t       fCutOnDThetaX;              // if true, apart from NStdDev cut apply also the cut on dThetaX
+  Float_t      fNStdDev;                   // cut on weighted distance
+  Float_t      fDPhiWindow;                // max dPhi
+  Float_t      fDThetaWindow;              // max dTheta
+  Float_t      fDPhiShift;                 // mean bend
+  Float_t      fPhiOverlapCut;             // overlaps cut in phi
+  Float_t      fZetaOverlap;               // overlaps cut in Z
+  Float_t      fPhiRot;                    // rotate L1 wrt L2
+  Float_t      fInjScale;                  // scaling factor for injection
+  Bool_t       fRemoveOverlaps;            // request overlaps removal
+  //
+  Float_t      fDPhiSCut;                  // cut on signal dphiS
+  Float_t      fNStdCut;                   // cut on signal weighted distance
+  Float_t      fMCV0Scale;                 // scaling factor for V0 in MC
+  //
+  AliITSMultRecBg *fMultReco;              //! mult.reco object
+  TTree*       fRPTree;                    //! tree of recpoints
+  TTree*       fRPTreeMix;                 //! tree of recpoints for mixing
+  AliStack*    fStack;                     //! MC stack
+  AliMCEvent*  fMCEvent;                   //! MC Event
+  Float_t      fESDVtx[3];                 //  ESD vertex
+  AliESDtrackCuts* fTrackCuts;             //! optional track cuts
+  //
+  //
+  /*
+  AliTriggerAnalysis::Trigger fTrigger;    // requested trigger
+  MCCentralityBin fMCCentralityBin;        // to select MC centrality bin in which corrections are calculated
+  Float_t      fCentrLowLim;               // to select centrality bin on data
+  Float_t      fCentrUpLim;                // to select centrality bin on data
+  TString      fCentrEst;                  // to select centrality estimator
+  */
+  Float_t fNPart;                          // number of participant pairs from MC
+  Float_t fNBColl;                         // number of bin. collision from MC
+  Int_t  fCurrCentBin;                     // current centrality bin
+  Int_t  fNCentBins;                       // N of mult bins
+  Int_t  fUseCentralityVar;                // what is used to determine the centrality
+  const  Float_t* fkCentBinDef;                     //! selected binning in centrality
+  const  Float_t* fkCentBinDef2DY;                  //! Y point of 2D bin
+  const  Float_t* fkCentBinDef2DS;                  //! slope of 2D bin
+  static const Float_t fgkCentBinDefV0[];           //!definition of mult bin (with lower and upper cuts)
+  static const Float_t fgkCentBinDefV0CR[];         //!definition of mult bin (with lower and upper cuts)
+  static const Float_t fgkCentBinDefSPD2[];         //!definition of mult bin (with lower and upper cuts)
+  static const Float_t fgkCentBinDefTrTPC[];        //!definition of mult bin (with lower and upper cuts)
+  //
+  static const Float_t fgkCentBinDefZDCV0X[];       //! ZDC vs V0Corr X
+  static const Float_t fgkCentBinDefZDCV0Y[];       //! ZDC vs V0Corr Y
+  static const Float_t fgkCentBinDefZDCV0S[];       //! ZDC vs V0Corr Slope
+  //
+  static const char*  fgkPDGNames[];                //!pdg names
+  static const Int_t  fgkPDGCodes[];                //!pdg codes
+  //
+ private:    
+  AliTrackletTaskMulti(const AliTrackletTaskMulti&); // not implemented
+  AliTrackletTaskMulti& operator=(const AliTrackletTaskMulti&); // not implemented 
+  
+  ClassDef(AliTrackletTaskMulti, 1);  
+};
+
+
+#endif
diff --git a/PWG0/multVScentPbPb/AliTrackletTaskUni.cxx b/PWG0/multVScentPbPb/AliTrackletTaskUni.cxx
new file mode 100755 (executable)
index 0000000..6171079
--- /dev/null
@@ -0,0 +1,1321 @@
+/*************************************************************************
+* Copyright(c) 1998-2008, ALICE Experiment at CERN, All rights reserved. *
+*                                                                        *
+* Author: The ALICE Off-line Project.                                    *
+* Contributors are mentioned in the code where appropriate.              *
+*                                                                        *
+* Permission to use, copy, modify and distribute this software and its   *
+* documentation strictly for non-commercial purposes is hereby granted   *
+* without fee, provided that the above copyright notice appears in all   *
+* copies and that both the copyright notice and this permission notice   *
+* appear in the supporting documentation. The authors make no claims     *
+* about the suitability of this software for any purpose. It is          *
+* provided "as is" without express or implied warranty.                  * 
+**************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTaskUni                                             //
+// Analysis task to study performance and combinatorial background      //
+// in tracklet reconstruction                                           //
+// Author:  M. Nicassio (INFN Bari)                                     //
+// Contact: Maria.Nicassio@ba.infn.it, Domenico.Elia@ba.infn.it         //
+//////////////////////////////////////////////////////////////////////////
+
+#include "TChain.h"
+#include "TTree.h"
+#include "TRandom.h"
+#include "TH1F.h"
+#include "TH2F.h" 
+#include "TH3F.h"
+#include "THnSparse.h"
+#include "TList.h"
+#include "TNtuple.h"
+#include "TObjArray.h"
+#include "TGeoGlobalMagField.h"
+
+#include "AliAnalysisManager.h"
+
+#include "AliMultiplicity.h"
+#include "AliESDEvent.h"  
+#include "AliESDInputHandler.h"
+#include "AliESDInputHandlerRP.h"
+#include "../ANALYSIS/EventMixing/AliMixEventInputHandler.h"
+#include "AliCDBPath.h"
+#include "AliCDBManager.h"
+#include "AliCDBEntry.h"
+#include "AliCDBStorage.h"
+#include "AliGeomManager.h"
+#include "AliMagF.h"
+#include "AliESDVZERO.h"
+#include "AliESDZDC.h"
+#include "AliRunLoader.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliMCParticle.h"
+#include "AliStack.h"
+#include "AliGenEventHeader.h"
+#include "../ITS/AliITSRecPoint.h"
+#include "../ITS/AliITSgeomTGeo.h"
+#include "../ITS/AliITSMultReconstructor.h" 
+
+#include "AliLog.h"
+
+#include "AliPhysicsSelection.h"
+#include "AliESDCentrality.h" 
+#include "AliTrackletTaskUni.h"
+#include "AliITSMultRecBg.h"
+#include "AliGenEventHeader.h"
+#include "AliGenHijingEventHeader.h"
+#include "AliGenDPMjetEventHeader.h"
+
+ClassImp(AliTrackletTaskUni)
+
+const char*  AliTrackletTaskUni::fgkPDGNames[] = {
+"#pi^{+}",
+"p",
+"K^{+}",
+"K^{*+}",
+"e^{-}",
+"#mu^{-}",
+"#rho^{+}",
+"D^{+}",
+"D^{*+}",
+"D_{s}^{+}",
+"D_{s}^{*+}",
+"#Delta^{-}",
+"#Delta^{+}",
+"#Delta^{++}",
+"#Sigma^{-}",
+"#Sigma^{+}",
+"#Sigma^{*-}",
+"#Sigma^{*+}",
+"#Sigma^{*+}_{c}",
+"#Sigma^{*++}_{c}",
+"#Xi^{-}",
+"#Xi^{*-}",
+"#Lambda^{+}_{c}",
+"n",
+"#Delta^{0}",
+"#gamma",
+"K^{0}_{S}",
+"K^{0}_{L}",
+"K^{0}",
+"K^{*}",
+"#eta",
+"#pi^{0}",
+"#rho^{0}",
+"#varphi",
+"#eta'",
+"#omega",
+"#Lambda",
+"#Sigma^{0}",
+"#Sigma^{*0}_{c}",
+"#Sigma^{*0}",
+"D^{0}",
+"D^{*0}",
+"#Xi_{0}",
+"#Xi^{*0}",
+"#Xi^{0}_{c}",
+"#Xi^{*0}_{c}",
+"Nuclei",
+"Others"
+};
+
+const int AliTrackletTaskUni::fgkPDGCodes[] = {
+  211,
+ 2212, 
+  321, 
+  323, 
+   11, 
+   13, 
+  213, 
+  411, 
+  413, 
+  431, 
+  433, 
+ 1114, 
+ 2214, 
+ 2224, 
+ 3112, 
+ 3222, 
+ 3114, 
+ 3224, 
+ 4214, 
+ 4224, 
+ 3312, 
+ 3314, 
+ 4122, 
+ 2112, 
+ 2114, 
+   22, 
+  310, 
+  130, 
+  311, 
+  313, 
+  221, 
+  111, 
+  113, 
+  333, 
+  331, 
+  223, 
+ 3122, 
+ 3212, 
+ 4114, 
+ 3214, 
+  421, 
+  423, 
+ 3322, 
+ 3324, 
+ 4132, 
+ 4314
+// nuclei
+// unknown
+};
+
+//________________________________________________________________________
+/*//Default constructor
+AliTrackletTaskUni::AliTrackletTaskUni(const char *name)
+  : AliAnalysisTaskSE(name),
+*/  
+//________________________________________________________________________
+AliTrackletTaskUni::AliTrackletTaskUni(const char *name) 
+  : AliAnalysisTaskSE(name), 
+//
+  fOutput(0), 
+//
+  fDoNormalReco(kFALSE),
+  fDoInjection(kFALSE),
+  fDoRotation(kFALSE),
+  fDoMixing(kFALSE),
+  //
+  fUseMC(kFALSE),
+  fCheckReconstructables(kFALSE),
+//
+  fHistosTrData(0),
+  fHistosTrInj(0),
+  fHistosTrRot(0),
+  fHistosTrMix(0),
+//
+  fHistosTrPrim(0),
+  fHistosTrSec(0),
+  fHistosTrComb(0),
+  fHistosTrCombU(0),
+//
+  fHistosTrRcblPrim(0),
+  fHistosTrRcblSec(0),
+  fHistosCustom(0),
+//
+  fEtaCut(3.0),
+  fZVertexMin(-20),
+  fZVertexMax( 20),
+  fMultCutMin(0),
+  fMultCutMax(99999),
+//
+  fScaleDTBySin2T(kFALSE),
+  fCutOnDThetaX(kFALSE),
+  fNStdDev(1.),
+  fDPhiWindow(0.08),
+  fDThetaWindow(0.025),
+  fDPhiShift(0.0045),
+  fPhiOverlapCut(0.005),
+  fZetaOverlap(0.05),
+  fPhiRot(0.),
+  fInjScale(1.),
+  fRemoveOverlaps(kFALSE),
+//
+  fMultReco(0),
+  fRPTree(0),
+  fRPTreeMix(0),
+  fStack(0),
+  fMCEvent(0)
+  /*
+  ,
+  fTrigger(AliTriggerAnalysis::kAcceptAll),
+  fMCCentralityBin(AliAnalysisTaskSPDdNdEta::kall),
+  fCentrLowLim(0),
+  fCentrUpLim(0),
+  fCentrEst("")
+  */
+{
+  // Constructor
+
+  DefineOutput(1, TList::Class());
+  //
+  SetScaleDThetaBySin2T();
+  SetNStdDev();
+  SetPhiWindow();
+  SetThetaWindow();
+  SetPhiShift();
+  SetPhiOverlapCut();
+  SetZetaOverlapCut();
+  SetPhiRot();
+  SetRemoveOverlaps();
+  //
+}
+//________________________________________________________________________
+AliTrackletTaskUni::~AliTrackletTaskUni()
+{
+  // Destructor
+  // histograms are in the output list and deleted when the output
+  // list is deleted by the TSelector dtor
+  if (fOutput && !AliAnalysisManager::GetAnalysisManager()->IsProofMode()) {  //RRR
+    printf("Deleteing output\n");
+    delete fOutput;
+    fOutput = 0;
+  }
+  //
+  delete fMultReco;
+  //
+  delete fHistosTrData;
+  delete fHistosTrPrim;
+  delete fHistosTrSec;
+  delete fHistosTrComb;
+  delete fHistosTrCombU;
+  delete fHistosTrInj;
+  delete fHistosTrRot;
+  delete fHistosTrMix;
+  delete fHistosTrRcblPrim;
+  delete fHistosTrRcblSec;
+  delete fHistosCustom;
+  //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskUni::UserCreateOutputObjects() 
+{
+  //
+  fOutput = new TList();
+  fOutput->SetOwner(); 
+  //
+  AliCDBManager *man = AliCDBManager::Instance();
+  if (fUseMC) {
+    Bool_t newGeom = kTRUE;
+    man->SetDefaultStorage("alien://Folder=/alice/simulation/2008/v4-15-Release/Residual");
+    if (newGeom) {
+      // new geom
+      AliCDBEntry*  obj = man->Get("GRP/Geometry/Data",130844,8);
+      AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+      if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130844,6,-1)) AliFatal("Failed to misalign geometry");
+    }
+    else {
+      // old geom
+      AliCDBEntry*  obj = man->Get("GRP/Geometry/Data",130845,7);
+      AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+      if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",130845,5,-1)) AliFatal("Failed to misalign geometry");
+    }
+  }
+  else {
+    man->SetDefaultStorage("raw://"); man->SetRun(137045);
+    AliCDBEntry*  obj = man->Get("GRP/Geometry/Data",137045,3);
+    AliGeomManager::SetGeometry((TGeoManager*) obj->GetObject());
+    if (!AliGeomManager::ApplyAlignObjsToGeom("ITS",137045,8,-1)) AliFatal("Failed to misalign geometry");
+  }
+  //
+  // Create histograms
+  //---------------------------------------------Standard histos per tracklet type--->>
+  UInt_t hPattern = 0xffffffff;
+  hPattern &= ~(BIT(kHEtaZvDPhiS));  // pattern of histos to fill
+  fHistosTrData                      = BookHistosSet("TrData",hPattern);
+  if (GetDoInjection()) fHistosTrInj = BookHistosSet("TrInj",hPattern);
+  if (GetDoRotation())  fHistosTrRot = BookHistosSet("TrRot",hPattern);
+  if (GetDoMixing())    fHistosTrMix = BookHistosSet("TrMix",hPattern);
+  if (fUseMC) {
+    hPattern = 0xffffffff;  hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+    fHistosTrPrim  = BookHistosSet("TrPrim",hPattern);
+    //
+    hPattern = 0xffffffff;  hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+    fHistosTrSec   = BookHistosSet("TrSec",hPattern);
+    //
+    hPattern = 0xffffffff;
+    fHistosTrComb  = BookHistosSet("TrComb",hPattern);
+    //
+    hPattern = 0xffffffff;  hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+    fHistosTrCombU = BookHistosSet("TrCombU",hPattern);
+    //
+    if (fCheckReconstructables) {
+      hPattern = 0xffffffff;  hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+      fHistosTrRcblPrim = BookHistosSet("TrRcblPrim",hPattern);
+      //
+      hPattern = 0xffffffff;  hPattern &= ~(BIT(kHEtaZvDist)|(BIT(kHEtaZvDPhiS)));
+      fHistosTrRcblSec  = BookHistosSet("TrRcblSec",hPattern);
+    }
+  }
+  //---------------------------------------------Standard histos per tracklet type---<<
+  //
+  //---------------------------------------------Custom Histos----------------------->>
+  // put here any non standard histos
+  fHistosCustom = BookCustomHistos();
+  //
+  //---------------------------------------------Custom Histos-----------------------<<
+  int nhist = fOutput->GetEntries();
+  for (int i=0;i<nhist;i++) {
+    TObject* hst = fOutput->At(i);
+    if (!hst || !(hst->InheritsFrom(TH1::Class()))) continue;
+    ((TH1*)hst)->Sumw2();
+  }
+  //
+  PostData(1, fOutput);
+  //
+}
+
+//________________________________________________________________________
+void AliTrackletTaskUni::UserExec(Option_t *) 
+{
+  // Main loop
+  //
+  AliAnalysisManager* anMan = AliAnalysisManager::GetAnalysisManager();
+  fRPTree = fRPTreeMix = 0;
+  AliESDInputHandlerRP *handRP = (AliESDInputHandlerRP*)anMan->GetInputEventHandler();
+  if (!handRP) { printf("No RP handler\n"); return; }
+  AliESDEvent *esd  = handRP->GetEvent();
+  if (!esd) { printf("No AliESDEvent\n"); return; }
+  //
+  // do we need to initialize the field?
+  AliMagF* field = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
+  if (!field && !esd->InitMagneticField()) {printf("Failed to initialize the B field\n");return;}
+  //
+  /* // RS to be clarified
+  // Trigger selection
+  static AliTriggerAnalysis* triggerAnalysis = 0; 
+  Bool_t eventTriggered = triggerAnalysis->IsTriggerFired(esd, fTrigger);
+  if (!eventTriggered) {printf("No trigger\n"); return;}
+  //
+  // Centrality selection 
+  Bool_t eventInCentralityBin = kFALSE;
+  // Centrality selection
+  AliESDCentrality *centrality = esd->GetCentrality();
+  if (fCentrEst=="") eventInCentralityBin = kTRUE;
+  else {
+    if(!centrality) {
+      AliError("Centrality object not available"); 
+    }  else {
+      if (centrality->IsEventInCentralityClass(fCentrLowLim,fCentrUpLim,fCentrEst.Data())) eventInCentralityBin = kTRUE;
+    }
+  }
+  */
+
+  const AliESDVertex* vtxESD = esd->GetPrimaryVertexSPD();
+  if (vtxESD->GetNContributors()<1) return;
+  if (vtxESD->GetDispersion()>0.04) return;
+  if (vtxESD->GetZRes()>0.25) return;
+  const AliMultiplicity* multESD = esd->GetMultiplicity();
+  const AliESDVertex* vtxESDTPC = esd->GetPrimaryVertexTPC();
+  if (vtxESDTPC->GetNContributors()<1 ||
+      vtxESDTPC->GetNContributors()<(-10.+0.25*multESD->GetNumberOfITSClusters(0))) return;
+  //
+  TH1F* hstat = (TH1F*)fHistosCustom->UncheckedAt(kHStat);
+  //
+  hstat->Fill(kEvTot); // RS
+  //
+  Double_t esdvtx[3];
+  vtxESD->GetXYZ(esdvtx);
+  for (int i=3;i--;) fESDVtx[i] = esdvtx[i];
+  //
+  float vtxf[3] = {vtxESD->GetX(),vtxESD->GetY(),vtxESD->GetZ()};
+  //
+  //------------------------------------------------------
+  // ZDC cut
+  AliESDZDC *esdZDC = esd->GetESDZDC();
+  // --- ZDC offline trigger ---
+  // Returns if ZDC triggered, based on TDC information
+  Bool_t tdc[32] = {kFALSE};
+  for(Int_t itdc=0; itdc<32; itdc++){
+    for(Int_t i=0; i<4; i++){
+      if (0.025*esdZDC->GetZDCTDCData(itdc, i) != 0){
+       tdc[itdc] = kTRUE;
+      }
+    }
+  }
+  Bool_t zdcNA = tdc[12];
+  Bool_t zdcNC = tdc[10];
+  Bool_t zdcPA = tdc[13];
+  Bool_t zdcPC = tdc[11];
+  //
+  Bool_t zdcC= ((zdcPA) || (zdcNA));
+  Bool_t zdcA= ((zdcPC) || (zdcNC));
+  if (!zdcC || !zdcA) return;
+  //-----------------------------------------------------
+  Float_t multV0A=0,multV0C=0;
+  AliESDVZERO* esdV0 = esd->GetVZEROData();
+  if (esdV0) {
+    multV0A = esdV0->GetMTotV0A();
+    multV0C = esdV0->GetMTotV0C();
+  }
+  if (fUseMC) {
+    const double v0Scale = 0.75108;
+    multV0A *= v0Scale;
+    multV0C *= v0Scale;    
+  }
+  // registed Ntracklets and ZVertex of the event
+  ((TH1F*)fHistosCustom->UncheckedAt(kHZVtxNoSel))->Fill(esdvtx[2]);
+  ((TH1F*)fHistosCustom->UncheckedAt(kHNTrackletsNoSel))->Fill(multESD->GetNumberOfTracklets());      
+  ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD1NoSel))->Fill(multESD->GetNumberOfITSClusters(0));
+  ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD2NoSel))->Fill(multESD->GetNumberOfITSClusters(1));
+  ((TH1F*)fHistosCustom->UncheckedAt(kHV0NoSel))->Fill(multV0A+multV0C);
+  //  ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0A+multV0C,multESD->GetNumberOfITSClusters(1));
+  //
+  //  printf("ESD vertex! %f %f %f, %d contributors\n",esdvtx[0],esdvtx[1],esdvtx[2],vtxESD->GetNContributors());
+
+  if(vtxf[2] < fZVertexMin || vtxf[2] > fZVertexMax) return;
+  ((TH2F*)fHistosCustom->UncheckedAt(kHV0NClSPD2NoSel))->Fill(multV0A+multV0C,multESD->GetNumberOfITSClusters(1));
+  //
+  ///  double mltTst = fUseMC ?  multESD->GetNumberOfITSClusters(1) : multV0A+multV0C;  
+  //  double mltTst = multESD->GetNumberOfITSClusters(1); //RRR
+  double mltTst = multV0A+multV0C; //RRR
+
+  if ((mltTst<fMultCutMin) || (mltTst>fMultCutMax)) return;
+  //
+  //  if((multESD->GetNumberOfTracklets() < fMultCutMin) || (multESD->GetNumberOfTracklets() > fMultCutMax)) return;
+  //
+  printf("Multiplicity from ESD:\n");
+  //  multESD->Print();
+  //
+  AliMCEventHandler* eventHandler = 0;
+  fMCEvent = 0;
+  fStack = 0;
+  //
+  if (fUseMC) {
+    eventHandler = (AliMCEventHandler*)anMan->GetMCtruthEventHandler();
+    if (!eventHandler) { printf("ERROR: Could not retrieve MC event handler\n"); return; }
+    fMCEvent = eventHandler->MCEvent();
+    if (!fMCEvent) { printf("ERROR: Could not retrieve MC event\n"); return; }
+    fStack = fMCEvent->Stack();
+    if (!fStack) { printf("Stack not available\n"); return; }
+  }
+  //
+  fRPTree = handRP->GetTreeR("ITS");
+  if (!fRPTree) { AliError(" Invalid ITS cluster tree !\n"); return; }
+  //
+  //
+  // registed Ntracklets and ZVertex of the event
+  ((TH1F*)fHistosCustom->UncheckedAt(kHZVtx))->Fill(esdvtx[2]);
+  ((TH1F*)fHistosCustom->UncheckedAt(kHNTracklets))->Fill(multESD->GetNumberOfTracklets());      
+  //
+  if (fUseMC) FillMCPrimaries( ((TH2F*)fHistosCustom->UncheckedAt(kHZVEtaPrimMC)) );
+  // fill N clusters
+  ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD1))->Fill(multESD->GetNumberOfITSClusters(0));
+  ((TH1F*)fHistosCustom->UncheckedAt(kHNClSPD2))->Fill(multESD->GetNumberOfITSClusters(1));
+  ((TH1F*)fHistosCustom->UncheckedAt(kHV0))->Fill(multV0A+multV0C);
+  //
+  // normal reconstruction
+  hstat->Fill(kEvProcData);
+  if (GetDoNormalReco() || GetDoInjection()) { // for the injection the normal reco should be done
+    InitMultReco();
+    fMultReco->Run(fRPTree, vtxf);
+    printf("Multiplicity Reconstructed:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    if (GetDoNormalReco()) FillHistos(kData,mlt);
+    //
+  }
+  if (!GetDoNormalReco()) FillHistos(kData,multESD); // fill data histos from ESD
+  //
+  // Injection: it must come right after the normal reco since needs its results
+  if (GetDoInjection()) {
+    if (!fMultReco) InitMultReco(); // in principle, not needed, the reco is created above
+    fMultReco->SetRecType(AliITSMultRecBg::kBgInj);
+    fMultReco->Run(fRPTree, vtxf);
+    printf("Multiplicity from Injection:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    hstat->Fill(kEvProcInj);
+    FillHistos(kBgInj,mlt);
+  }
+  //
+  // Rotation
+  if (GetDoRotation()) {
+    InitMultReco();
+    fMultReco->SetRecType(AliITSMultRecBg::kBgRot);
+    fMultReco->SetPhiRotationAngle(fPhiRot);
+    fMultReco->Run(fRPTree, vtxf);
+    printf("Multiplicity from Rotation:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    hstat->Fill(kEvProcRot);
+    FillHistos(kBgRot,mlt);
+  }
+  //
+  if (GetDoMixing()) {
+    AliMixEventInputHandler* handToMix = (AliMixEventInputHandler*)handRP->MixingHandler();
+    if (!handToMix) { printf("No Mixing handler\n"); return; }
+    handToMix->GetEntry();
+    if(handToMix->MixedEventNumber()<1) {printf("Mixing: No enough events in pool\n"); return;}
+    AliESDInputHandlerRP* handRPMix = (AliESDInputHandlerRP*) handToMix->InputEventHandler(0);
+
+    if (!handRPMix) { printf("No Mixing RP handler\n"); return; }
+    fRPTreeMix = handRPMix->GetTreeR("ITS");
+    if (!fRPTreeMix) { AliError(" Invalid ITS cluster tree of the 2nd event!\n"); return; }
+    //
+    AliESDEvent *esdMix = handRPMix->GetEvent();
+    const AliESDVertex* vtxESDmix = esdMix->GetVertex();
+    ((TH1F*)fHistosCustom->UncheckedAt(kHZVtxMixDiff))->Fill(vtxESDmix->GetZ()-esdvtx[2]);
+    ((TH1F*)fHistosCustom->UncheckedAt(kHNTrMixDiff) )->
+      Fill(esdMix->GetMultiplicity()->GetNumberOfTracklets() - multESD->GetNumberOfTracklets());
+    //
+    InitMultReco();
+    fMultReco->SetRecType(AliITSMultRecBg::kBgMix);
+    fMultReco->Run(fRPTree, vtxf,fRPTreeMix);
+    printf("Multiplicity from Mixing:\n");
+    AliMultiplicity* mlt = fMultReco->GetMultiplicity();
+    if (mlt) mlt->Print();
+    hstat->Fill(kEvProcMix);
+    FillHistos(kBgMix,mlt);
+    //
+  }
+  // =============================================================================<<<
+  //
+  delete fMultReco; 
+  fMultReco = 0;
+  //
+}      
+//________________________________________________________________________
+void AliTrackletTaskUni::Terminate(Option_t *) 
+{
+  Printf("Terminating...");
+  TH1* hstat;
+  TList *lst = dynamic_cast<TList*>(GetOutputData(1));
+  printf("Term: %p %p %p\n",fOutput,lst,fHistosCustom);
+  if (lst && (hstat=(TH1*)lst->FindObject("hStat"))) {
+    Info("Terminate","Registering used settings");
+    // fill used settings
+    hstat->Fill(kDPhi,fDPhiWindow);
+    hstat->Fill(kDTht,fDThetaWindow);
+    hstat->Fill(kNStd,fNStdDev);
+    hstat->Fill(kPhiShift,fDPhiShift);
+    hstat->Fill(kThtS2,fScaleDTBySin2T);  
+    hstat->Fill(kThtCW,fCutOnDThetaX);  
+    hstat->Fill(kPhiOvl,fPhiOverlapCut);
+    hstat->Fill(kZEtaOvl,fZetaOverlap);
+    hstat->Fill(kNoOvl,fRemoveOverlaps);
+    //
+    hstat->Fill(kPhiRot,fPhiRot);
+    hstat->Fill(kInjScl,fInjScale);
+    hstat->Fill(kEtaCut,fEtaCut);
+    hstat->Fill(kZVMin,fZVertexMin);
+    hstat->Fill(kZVMax,fZVertexMax);
+    hstat->Fill(kTrcMin,fMultCutMin);    
+    hstat->Fill(kTrcMax,fMultCutMax);    
+    //
+    hstat->Fill(kOneUnit,1.);    
+  }
+  //
+  
+  //  AliAnalysisTaskSE::Terminate();
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::InitMultReco()
+{
+  // create mult reconstructor
+  if (fMultReco) delete fMultReco;
+  fMultReco = new AliITSMultRecBg();
+  fMultReco->SetCreateClustersCopy(kTRUE);
+  fMultReco->SetScaleDThetaBySin2T(fScaleDTBySin2T);
+  fMultReco->SetNStdDev(fNStdDev);
+  fMultReco->SetPhiWindow( fDPhiWindow );
+  fMultReco->SetThetaWindow( fDThetaWindow );
+  fMultReco->SetPhiShift( fDPhiShift );
+  fMultReco->SetRemoveClustersFromOverlaps(fRemoveOverlaps);
+  fMultReco->SetPhiOverlapCut(fPhiOverlapCut);
+  fMultReco->SetZetaOverlapCut(fZetaOverlap);
+  fMultReco->SetHistOn(kFALSE); 
+  fMultReco->SetRecType( AliITSMultRecBg::kData );
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskUni::BookCustomHistos()
+{
+  // book custom histos, not related to specific tracklet type
+  TObjArray* histos = new TObjArray();
+  TH1F* hstat;
+  //
+  // ------------ job parameters, statistics ------------------------------>>>
+  hstat = new TH1F("hStat","Run statistics",kNStatBins,0.5,kNStatBins-0.5);
+  //
+  hstat->GetXaxis()->SetBinLabel(kEvTot, "Ev.Tot");
+  hstat->GetXaxis()->SetBinLabel(kEvProcData,"Ev.ProcData");
+  hstat->GetXaxis()->SetBinLabel(kEvProcInj,"Ev.ProcInj");
+  hstat->GetXaxis()->SetBinLabel(kEvProcRot,"Ev.ProcRot");
+  hstat->GetXaxis()->SetBinLabel(kEvProcMix,"Ev.ProcMix");
+  //
+  hstat->GetXaxis()->SetBinLabel(kDPhi,  "#Delta#varphi");
+  hstat->GetXaxis()->SetBinLabel(kDTht,  "#Delta#theta");
+  hstat->GetXaxis()->SetBinLabel(kNStd,  "N.std");
+  hstat->GetXaxis()->SetBinLabel(kPhiShift,"#delta#varphi");
+  hstat->GetXaxis()->SetBinLabel(kThtS2,"scale #Delta#theta");
+  hstat->GetXaxis()->SetBinLabel(kPhiOvl,"#varpho_{Ovl}");
+  hstat->GetXaxis()->SetBinLabel(kZEtaOvl,"#z_{Ovl}");
+  hstat->GetXaxis()->SetBinLabel(kNoOvl, "rem.ovl");
+  //
+  hstat->GetXaxis()->SetBinLabel(kPhiRot,"#varphi_{rot}");
+  hstat->GetXaxis()->SetBinLabel(kInjScl,"inj");
+  hstat->GetXaxis()->SetBinLabel(kEtaCut,"#eta cut");
+  hstat->GetXaxis()->SetBinLabel(kZVMin,"ZV_{min} cut");
+  hstat->GetXaxis()->SetBinLabel(kZVMax,"ZV_{max} cut");
+  hstat->GetXaxis()->SetBinLabel(kTrcMin,"Mult_{min} cut");
+  hstat->GetXaxis()->SetBinLabel(kTrcMax,"Mult_{max} cut");  
+  //
+  hstat->GetXaxis()->SetBinLabel(kOneUnit,"ScaleMerge");
+  hstat->GetXaxis()->SetBinLabel(kNWorkers,"Workers");
+  hstat->Fill(kNWorkers);
+  //  
+  AddHisto(histos,hstat,kHStat);
+  // ------------ job parameters, statistics ------------------------------<<<
+  //
+  double etaMn=-3,etaMx=3;
+  double zMn=-30, zMx=30;  
+  int nEtaBins = int((etaMx-etaMn)/0.1);
+  if (nEtaBins<1) nEtaBins = 1;
+  //
+  int nZVBins = int(zMx-zMn);
+  if (nZVBins<1) nZVBins = 1;
+  //
+  // Z vertex distribution for events before selection
+  TH1F* hzvns = new  TH1F("zvNoSel","Z vertex Before Selection",nZVBins,zMn,zMx);
+  hzvns->GetXaxis()->SetTitle("Zvertex");
+  AddHisto(histos,hzvns,kHZVtxNoSel);
+  //
+  int nbmltSPD2 = 700;
+  double maxmltSPD2 = 7000;
+  int nbmltV0 = 1000;
+  double maxmltV0 = 20000;
+  // N tracklets for processed events
+  TH1F* hntns = new  TH1F("NtrackletsNoSel","N Tracklets Before Selection",nbmltSPD2,0,maxmltSPD2);
+  hntns->GetXaxis()->SetTitle("N tracklets");
+  AddHisto(histos,hntns,kHNTrackletsNoSel);
+  //
+  // N SPD1 clusters
+  TH1F* hncl1ns = new  TH1F("NClustersSPD1NoSel","N Clusters on SPD1 Before Selection",nbmltSPD2,0,maxmltSPD2);
+  hncl1ns->GetXaxis()->SetTitle("N Clus SPD1");
+  AddHisto(histos,hncl1ns,kHNClSPD1NoSel);
+  //
+  // N SPD2 clusters
+  TH1F* hncl2ns = new  TH1F("NClustersSPD2NoSel","N Clusters on SPD2 Before Selection",nbmltSPD2,0,maxmltSPD2);
+  hncl2ns->GetXaxis()->SetTitle("N Clus SPD2");
+  AddHisto(histos,hncl2ns,kHNClSPD2NoSel);
+  //
+  // V0 
+  TH1F* hnV0ns = new  TH1F("V0NoSel","V0 signal Before Selection",nbmltV0,0,maxmltV0);
+  hnV0ns->GetXaxis()->SetTitle("V0 signal");
+  AddHisto(histos,hnV0ns,kHV0NoSel);
+  //
+  // V0 
+  //TH2F* hnV0SPD2ns = new  TH2F("V0NDP2NoSel","NSPD2 vs V0 signal Before Selection",2500,0,20000,1400,0,maxmltSPD2);
+  TH2F* hnV0SPD2ns = new  TH2F("V0NDP2NoMltSel","NSPD2 vs V0 signal Before Mlt Selection",100,0,maxmltV0,100,0,maxmltSPD2);
+  hnV0SPD2ns->GetXaxis()->SetTitle("V0 signal");
+  hnV0SPD2ns->GetYaxis()->SetTitle("N Clus SPD2 ");
+  AddHisto(histos,hnV0SPD2ns,kHV0NClSPD2NoSel);
+  //
+  //
+  // Z vertex distribution for selected events
+  TH1F* hzv = new  TH1F("zv","Z vertex",nZVBins,zMn,zMx);
+  hzv->GetXaxis()->SetTitle("Zvertex");
+  AddHisto(histos,hzv,kHZVtx);
+  //
+  // N tracklets for processed events
+  TH1F* hnt = new  TH1F("Ntracklets","N Tracklets",nbmltSPD2,0,maxmltSPD2);
+  hnt->GetXaxis()->SetTitle("N tracklets");
+  AddHisto(histos,hnt,kHNTracklets);
+  //
+  // N SPD1 clusters
+  TH1F* hncl1 = new  TH1F("NClustersSPD1","N Clusters on SPD1",nbmltSPD2,0,maxmltSPD2);
+  hncl1->GetXaxis()->SetTitle("N Clus SPD1");
+  AddHisto(histos,hncl1,kHNClSPD1);
+  //
+  // N SPD2 clusters
+  TH1F* hncl2 = new  TH1F("NClustersSPD2","N Clusters on SPD2",nbmltSPD2,0,maxmltSPD2);
+  hncl2->GetXaxis()->SetTitle("N Clus SPD2");
+  AddHisto(histos,hncl2,kHNClSPD2);
+  //
+  // V0 
+  TH1F* hnV0 = new  TH1F("V0","V0 signal",nbmltV0,0,maxmltV0);
+  hnV0->GetXaxis()->SetTitle("V0 signal");
+  AddHisto(histos,hnV0,kHV0);
+  //
+  //----------------------------------------------------------------------
+  int nEtaBinsS = int(2*fEtaCut/0.1);
+  if (nEtaBinsS<1) nEtaBins = 1;
+  //
+  int nZVBinsS = int(fZVertexMax-fZVertexMin);
+  if (nZVBinsS<1) nZVBinsS = 1;
+
+  if (fUseMC) {
+    // Z vertex vs Eta distribution for primaries
+    TH2F* hzvetap = new  TH2F("zvEtaPrimMC","Z vertex vs eta PrimMC",nEtaBinsS,-fEtaCut,fEtaCut,nZVBinsS,fZVertexMin,fZVertexMax);
+    hzvetap->GetXaxis()->SetTitle("#eta");
+    hzvetap->GetYaxis()->SetTitle("Zvertex");
+    AddHisto(histos,hzvetap,kHZVEtaPrimMC);
+  }
+  //
+  if (GetDoMixing()) {
+    //
+    // Difference in Z vertex for mixed events
+    TH1F* hzdiff = new TH1F("MixSPDVertexDiff","SPD #Delta Z Vertex distribution ",100,-5,5);
+    hzdiff->GetXaxis()->SetTitle("#Delta Z Vertex [cm]");
+    hzdiff->GetYaxis()->SetTitle(Form("Entries / %1.2f [cm]",10./100.));
+    AddHisto(histos,hzdiff,kHZVtxMixDiff);
+    //
+    // Difference in N tracklets for mixed events
+    TH1F* hntdiff = new TH1F("MixNTrackletsDiff"," SPD tracklets Diff ",2000,-3000,3000);
+    hntdiff->GetXaxis()->SetTitle("# tracklet diff");
+    AddHisto(histos,hntdiff,kHNTrMixDiff);
+  }
+  // 
+  // --------------------------------------------------
+  int nDistBins = int(fNStdDev)*2;
+  int npdg = sizeof(fgkPDGNames)/sizeof(char*);
+  TH2F* hpdgP = new TH2F("pdgPrim","primary PDG",npdg,0,npdg,nDistBins,0,fNStdDev);
+  AddHisto(histos,hpdgP,kHPrimPDG);
+  TH2F* hpdgS = new TH2F("pdgSec","secondary PDG",npdg,0,npdg,nDistBins,0,fNStdDev);
+  AddHisto(histos,hpdgS,kHSecPDG);
+  TH2F* hpdgPP = new TH2F("pdgPrimPar","primary parent PDG ",npdg,0,npdg,nDistBins,0,fNStdDev);
+  AddHisto(histos,hpdgPP,kHPrimParPDG);
+  TH2F* hpdgSP = new TH2F("pdgSecPar","secondary parent PDG",npdg,0,npdg,nDistBins,0,fNStdDev);
+  AddHisto(histos,hpdgSP,kHSecParPDG);
+  for (int i=0;i<npdg;i++) {
+    hpdgP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+    hpdgS->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+    hpdgPP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+    hpdgSP->GetXaxis()->SetBinLabel(i+1,fgkPDGNames[i]);
+  }
+  //
+  // -------------------------------------------------
+  histos->SetOwner(kFALSE);
+
+  return histos;
+}
+
+//_________________________________________________________________________
+TObjArray* AliTrackletTaskUni::BookHistosSet(const char* pref, UInt_t selHistos) 
+{
+  // book standard set of histos attaching the pref in front of the name/title
+  //
+  const int kNDPhiBins = 100;
+  const int kNDThtBins = 100;
+  int nDistBins = int(fNStdDev)*2;
+
+  int nEtaBins = int(2*fEtaCut/0.1);
+  if (nEtaBins<1) nEtaBins = 1;
+  //
+  int nZVBins = int(fZVertexMax-fZVertexMin);
+  if (nZVBins<1) nZVBins = 1;
+  float dphir = fDPhiWindow*TMath::Sqrt(fNStdDev);
+  float dthtr = fDThetaWindow*TMath::Sqrt(fNStdDev);
+  //
+  TObjArray* histos = new TObjArray();
+  TH2F* h2;
+  THnSparseF* hsp;
+  char buffn[100],bufft[500];
+  //
+  if (selHistos & (0x1<<kHEtaZvDist) ) {
+    // sparse 3d histo for w.dist vs zv vs eta 
+    sprintf(buffn,"%s_DistZvEta",pref);
+    sprintf(bufft,"(%s)Weighted Dist.(#Delta) vs Zv vs Eta",pref);
+    int nbnEZD[3]    = {nEtaBins,nZVBins,nDistBins};
+    double xmnEZD[3] = {-fEtaCut,fZVertexMin,0};
+    double xmxEZD[3] = { fEtaCut,fZVertexMax,fNStdDev};
+    hsp = new THnSparseF(buffn,bufft,3,nbnEZD,xmnEZD,xmxEZD);
+    hsp->GetAxis(0)->SetTitle("#eta");
+    hsp->GetAxis(1)->SetTitle("Zv");
+    sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+           "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+    hsp->GetAxis(2)->SetTitle(bufft);
+    AddHisto(histos,hsp,kHEtaZvDist);
+  }
+  //
+  if (selHistos & (0x1<<kHEtaZvDPhiS) ) {
+    // sparse 3d histo for dphi vs zv vs eta 
+    sprintf(buffn,"%s_DistZvDPhiS",pref);
+    sprintf(bufft,"(%s) #Delta#varphi-#delta_{#varphi} vs Zv vs Eta",pref);
+    int nbnEZP[3]    = {nEtaBins,nZVBins, int(dphir*2/0.005)};
+    double xmnEZP[3] = {-fEtaCut,fZVertexMin,-dphir};
+    double xmxEZP[3] = { fEtaCut,fZVertexMax, dphir};
+    hsp = new THnSparseF(buffn,bufft,3,nbnEZP,xmnEZP,xmxEZP);
+    hsp->GetAxis(0)->SetTitle("#eta");
+    hsp->GetAxis(1)->SetTitle("Zv");
+    hsp->GetAxis(2)->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+    AddHisto(histos,hsp,kHEtaZvDPhiS);
+  }
+  //
+  if (selHistos & (0x1<<kHEtaZvCut) ) {
+    sprintf(buffn,"%s_ZvEtaCutT",pref);
+    sprintf(bufft,"(%s) Zv vs Eta with tracklet cut",pref);
+    h2 = new TH2F(buffn,bufft,nEtaBins,-fEtaCut,fEtaCut, nZVBins, fZVertexMin,fZVertexMax);
+    h2->GetXaxis()->SetTitle("#eta");
+    h2->GetYaxis()->SetTitle("Zv");
+    AddHisto(histos,h2,kHEtaZvCut);
+  }
+  //
+  if (selHistos & (0x1<<kHDPhiDTheta) ) {
+    sprintf(buffn,"%s_dPhidTheta",pref);
+    sprintf(bufft,"(%s) #Delta#theta vs #Delta#varphi",pref);
+    h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+    h2->GetXaxis()->SetTitle("#Delta#varphi [rad]");
+    h2->GetYaxis()->SetTitle("#Delta#theta [rad]");
+    AddHisto(histos,h2,kHDPhiDTheta);
+  }
+  //
+  if (selHistos & (0x1<<kHDPhiSDThetaX) ) {
+    sprintf(buffn,"%s_dPhiSdThetaX",pref);
+    sprintf(bufft,"(%s) #Delta#theta%s vs #Delta#varphi-#delta_{#varphi}",pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+    h2 = new TH2F(buffn,bufft,kNDPhiBins,-dphir,dphir,kNDThtBins,-dthtr,dthtr);
+    h2->GetXaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+    sprintf(bufft,"#Delta#theta%s",fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+    h2->GetYaxis()->SetTitle(bufft);
+    AddHisto(histos,h2,kHDPhiSDThetaX);
+  }
+  //
+  if (selHistos & (0x1<<kHEtaDPhiS) ) {
+    sprintf(buffn,"%s_EtaDPhiS",pref);
+    sprintf(bufft,"(%s) #Delta#varphi-#delta_{#varphi} vs #eta",pref);
+    h2 = new TH2F(buffn,bufft,nEtaBins, -fEtaCut,fEtaCut,kNDPhiBins,-dphir,dphir);
+    h2->GetXaxis()->SetTitle("#eta");
+    h2->GetYaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+    AddHisto(histos,h2,kHEtaDPhiS);
+  }
+  //
+  if (selHistos & (0x1<<kHEtaDThetaX) ) {
+    sprintf(buffn,"%s_EtaDThetaX",pref);
+    sprintf(bufft,"(%s) #Delta#theta%s vs #eta",pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+    h2 = new TH2F(buffn,bufft,nEtaBins, -fEtaCut,fEtaCut,kNDThtBins,-dthtr,dthtr);
+    h2->GetXaxis()->SetTitle("#eta");
+    sprintf(bufft,"#Delta#theta%s",fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+    h2->GetYaxis()->SetTitle(bufft);
+    AddHisto(histos,h2,kHEtaDThetaX);
+  }
+  //
+  if (selHistos & (0x1<<kHEtaDist) ) {
+    sprintf(buffn,"%s_EtaDist",pref);
+    sprintf(bufft,"(%s) Weighted Dist.(#Delta) vs #eta",pref);
+    h2 = new TH2F(buffn,bufft,nEtaBins, -fEtaCut,fEtaCut,nDistBins,0,fNStdDev);
+    h2->GetXaxis()->SetTitle("#eta");
+    sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+           "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+    h2->GetYaxis()->SetTitle(bufft);
+    AddHisto(histos,h2,kHEtaDist);
+  }
+  //
+  if (selHistos & (0x1<<kHZvDPhiS) ) {
+    sprintf(buffn,"%s_ZvDPhiS",pref);
+    sprintf(bufft,"(%s) #Delta#varphi-#delta_{#varphi} vs Zv",pref);
+    h2 = new TH2F(buffn,bufft, nZVBins, fZVertexMin,fZVertexMax, kNDPhiBins,-dphir,dphir);
+    h2->GetXaxis()->SetTitle("Zv");
+    h2->GetYaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+    AddHisto(histos,h2,kHZvDPhiS);
+  }
+  //
+  if (selHistos & (0x1<<kHZvDThetaX) ) {
+    sprintf(buffn,"%s_ZvDThetaX",pref);
+    sprintf(bufft,"(%s) #Delta#theta%s vs Zv",pref,fScaleDTBySin2T ? "/sin^{2}(#theta)":"");
+    h2 = new TH2F(buffn,bufft, nZVBins, fZVertexMin,fZVertexMax, kNDThtBins,-dthtr,dthtr);
+    h2->GetXaxis()->SetTitle("Zv");
+    h2->GetYaxis()->SetTitle("#Delta#varphi-#delta_{#varphi} [rad]");
+    AddHisto(histos,h2,kHZvDThetaX);
+  }
+  //
+  if (selHistos & (0x1<<kHZvDist) ) {
+    sprintf(buffn,"%s_ZvDist",pref);
+    sprintf(bufft,"(%s) Weighted Dist.(#Delta) vs Zv",pref);
+    h2 = new TH2F(buffn,bufft, nZVBins, fZVertexMin,fZVertexMax, nDistBins,0,fNStdDev);
+    h2->GetXaxis()->SetTitle("Zv");
+    sprintf(bufft,"#Delta=[(#Delta#varphi-#delta_{#varphi})/#sigma#varphi]^{2}+"
+           "[#Delta#theta%s/#sigma#theta]^{2}",fScaleDTBySin2T ? "*sin^{-2}(#theta)":"");
+    h2->GetYaxis()->SetTitle(bufft);
+    AddHisto(histos,h2,kHZvDist);
+  }
+  //
+  histos->SetOwner(kFALSE);
+  return histos;
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::AddHisto(TObjArray* histos, TObject* h, Int_t at)
+{
+  // add single histo to the set
+  if (at>=0) histos->AddAtAndExpand(h,at);
+  else       histos->Add(h);
+  fOutput->Add(h);
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::FillHistos(Int_t type, const AliMultiplicity* mlt)
+{
+  // fill histos of given type
+  if (!mlt) return;
+  //
+  TObjArray* histos = 0;
+  if      (type == kData)  histos = fHistosTrData;
+  else if (type == kBgInj) histos = fHistosTrInj;
+  else if (type == kBgRot) histos = fHistosTrRot;
+  else if (type == kBgMix) histos = fHistosTrMix;
+  //
+  Bool_t fillMC = (type==kData) && fUseMC && fStack;
+  //
+  //---------------------------------------- CHECK ------------------------------>>>
+  TArrayF vtxMC;
+  AliGenHijingEventHeader* pyHeader = 0;
+  //
+  if (fUseMC) {
+    pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+    pyHeader->PrimaryVertex(vtxMC);
+  }
+  //---------------------------------------- CHECK ------------------------------<<<
+  //
+  if (!histos) return;
+  int ntr = mlt->GetNumberOfTracklets();
+  //
+  for (int itr=ntr;itr--;) {
+    //
+    //---------------------------------------- CHECK ------------------------------>>>
+    if (fUseMC) {
+      Bool_t reject = kFALSE;
+      while(1) {
+       int lab0 = mlt->GetLabel(itr,0);
+       int lab1 = mlt->GetLabel(itr,1);
+       if (lab0!=lab1) break;
+       if (!fStack->IsPhysicalPrimary(lab0)) break;
+       //
+       TParticle* part = fStack->Particle(lab0);
+       Float_t dz = part->Vz() - vtxMC[2];
+       if (TMath::Abs(dz)<1e-6) break;
+       reject = kTRUE; 
+       break;
+      }
+      if (reject) continue;
+    }
+    //---------------------------------------- CHECK ------------------------------<<<
+    //
+    double theta  = mlt->GetTheta(itr);
+    double phi    = mlt->GetPhi(itr);
+    double dtheta = mlt->GetDeltaTheta(itr);
+    double dphi   = mlt->GetDeltaPhi(itr);
+    double dist   = mlt->CalcDist(itr);
+    //
+    FillHistosSet(histos,phi,theta,dphi,dtheta,dist);
+    // special handling for mc info
+    if (fillMC && fStack) {
+      int lab0 = mlt->GetLabel(itr,0);
+      int lab1 = mlt->GetLabel(itr,1);
+      int typeMC = 2; // comb.bg.
+      if (lab0 == lab1)        typeMC = fStack->IsPhysicalPrimary(lab0) ? 0:1; // prim or sec
+      if      (typeMC==0) FillHistosSet(fHistosTrPrim,phi,theta,dphi,dtheta,dist); // primary
+      else if (typeMC==1) FillHistosSet(fHistosTrSec, phi,theta,dphi,dtheta,dist); // secondary
+      else {
+       FillHistosSet(fHistosTrComb,phi,theta,dphi,dtheta,dist); // comb
+       // for combinatorals fill also the uncorrelated part
+       if (fMultReco) {
+         float *trl = fMultReco->GetTracklet(itr);
+         int clId0 = (int)trl[AliITSMultReconstructor::kClID1];
+         int clId1 = (int)trl[AliITSMultReconstructor::kClID2];
+         float *clLabs0 = fMultReco->GetClusterOfLayer(0,clId0) + AliITSMultReconstructor::kClMC0;
+         float *clLabs1 = fMultReco->GetClusterOfLayer(1,clId1) + AliITSMultReconstructor::kClMC0;
+         if (!HaveCommonParent(clLabs0,clLabs1)) 
+           FillHistosSet(fHistosTrCombU,phi,theta,dphi,dtheta,dist);
+       }
+      } // combinatorials
+      FillSpecies(typeMC, lab0, dist);
+      if (fCheckReconstructables) CheckReconstructables();
+    }
+  }
+  //
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::FillMCPrimaries(TH2F* hetaz)
+{
+  // fill all MC primaries Zv vs Eta
+  if (!fStack || !fMCEvent) return;
+
+  //---------------------------------------- CHECK ------------------------------>>>
+  TArrayF vtxMC;
+  AliGenHijingEventHeader* pyHeader = 0;
+  //
+  if (fUseMC) {
+    pyHeader = (AliGenHijingEventHeader*) fMCEvent->GenEventHeader();//header->GenEventHeader();
+    pyHeader->PrimaryVertex(vtxMC);
+  }
+  //---------------------------------------- CHECK ------------------------------<<<
+  //
+
+
+  int ntr = fStack->GetNtrack();
+  for (int itr=ntr;itr--;) {
+    if (!fStack->IsPhysicalPrimary(itr)) continue;
+    AliMCParticle *part  = (AliMCParticle*)fMCEvent->GetTrack(itr);
+    if (!part->Charge()) continue;
+    //
+    //---------------------------------------- CHECK ------------------------------>>>
+    Float_t dz = part->Zv() - vtxMC[2];
+    if (TMath::Abs(dz)>1e-6) continue; // reject
+    //---------------------------------------- CHECK ------------------------------<<<
+    //
+
+    Float_t theta = part->Theta();
+    if (theta<1e-6 || theta>TMath::Pi()-1e-6) continue;
+    Float_t eta = part->Eta();
+    hetaz->Fill(eta, fESDVtx[2]);
+  }
+  //
+}
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::FillHistosSet(TObjArray* histos, double /*phi*/,double theta,
+                                      double dphi,double dtheta,double dist) 
+{
+  // fill standard set of histos
+  if (dist>fNStdDev) return;
+  //
+  double dphiS  = TMath::Abs(dphi) - fDPhiShift;
+  if (dphi<0) dphiS = -dphiS;
+  double eta    = -TMath::Log(TMath::Tan(theta/2));
+  if (TMath::Abs(eta)>fEtaCut) return;
+  //
+  double dThetaX = dtheta;
+  if (fScaleDTBySin2T) {
+    double sint   =  TMath::Sin(theta);
+    dThetaX /= (sint*sint);
+  }
+  //
+  if (fCutOnDThetaX && TMath::Abs(dThetaX)>fDThetaWindow) return;
+  //
+  if (histos->UncheckedAt(kHEtaZvDist)) {
+    double ezd[3] = {eta,fESDVtx[2],dist};
+    ((THnSparseF*)histos->UncheckedAt(kHEtaZvDist))->Fill(ezd);
+  }
+  //
+  if (histos->UncheckedAt(kHEtaZvDPhiS)) {
+    double ezp[3] = {eta,fESDVtx[2],dphiS};
+    ((THnSparseF*)histos->UncheckedAt(kHEtaZvDPhiS))->Fill(ezp);
+  }
+  //
+  if (histos->UncheckedAt(kHDPhiSDThetaX)) 
+    ((TH2F*)histos->UncheckedAt(kHDPhiSDThetaX))->Fill(dphiS,dThetaX);
+  //
+  if (histos->UncheckedAt(kHEtaDPhiS))
+    ((TH2F*)histos->UncheckedAt(kHEtaDPhiS))->Fill(eta,dphiS);
+  //
+  if (histos->UncheckedAt(kHEtaDThetaX))
+    ((TH2F*)histos->UncheckedAt(kHEtaDThetaX))->Fill(eta,dThetaX);
+  //
+  if (histos->UncheckedAt(kHEtaDist))
+    ((TH2F*)histos->UncheckedAt(kHEtaDist))->Fill(eta,dist);
+  //
+  if (histos->UncheckedAt(kHZvDPhiS)) 
+    ((TH2F*)histos->UncheckedAt(kHZvDPhiS))->Fill(fESDVtx[2],dphiS);
+  //
+  if (histos->UncheckedAt(kHZvDThetaX))
+    ((TH2F*)histos->UncheckedAt(kHZvDThetaX))->Fill(fESDVtx[2],dThetaX);
+  //
+  if (histos->UncheckedAt(kHZvDist)) 
+    ((TH2F*)histos->UncheckedAt(kHZvDist))->Fill(fESDVtx[2],dist);
+  //
+  if (dist<=1 && histos->UncheckedAt(kHEtaZvCut)) 
+    ((TH2F*)histos->UncheckedAt(kHEtaZvCut))->Fill(eta,fESDVtx[2]);
+  //
+}
+//__________________________________________________________________
+void AliTrackletTaskUni::FillSpecies(Int_t primsec, Int_t id, double dist)
+{
+  // fill PDGcode 
+  TH1 *hPart=0,*hParent=0;
+  if (primsec==0) {
+    hPart   = (TH1F*)fHistosCustom->UncheckedAt(kHPrimPDG);
+    hParent = (TH1F*)fHistosCustom->UncheckedAt(kHPrimParPDG);
+  } 
+  else if (primsec==1) {
+    hPart   = (TH1F*)fHistosCustom->UncheckedAt(kHSecPDG);
+    hParent = (TH1F*)fHistosCustom->UncheckedAt(kHSecParPDG);    
+  }
+  else return;
+  int ntr = fStack->GetNtrack();
+  TParticle* part = fStack->Particle(id);
+  int pdgCode = TMath::Abs(part->GetPdgCode());
+  int pdgBin = GetPdgBin(pdgCode);
+  int parID = part->GetFirstMother();
+  int pdgCodePar = -1;
+  int pdgBinPar = -1;
+  while (parID>=0 && parID<ntr) {
+    part = fStack->Particle(parID);
+    pdgCodePar = TMath::Abs(part->GetPdgCode());
+    parID = part->GetFirstMother();
+  }
+  if (pdgCodePar>0) pdgBinPar = GetPdgBin(pdgCodePar);
+  //
+  hPart->Fill(pdgBin,dist);
+  hParent->Fill(pdgBinPar,dist);
+  //
+}
+
+//_________________________________________________________________________
+Int_t AliTrackletTaskUni::GetPdgBin(Int_t pdgCode)
+{
+  // return my pdg bin
+  int ncodes = sizeof(fgkPDGCodes)/sizeof(int);
+  int pdgBin=0;
+  for (pdgBin=0;pdgBin<ncodes;pdgBin++) if (pdgCode==fgkPDGCodes[pdgBin]) break;
+  if (pdgBin>=ncodes) {
+    if (float(pdgCode)>1e9) pdgBin = ncodes; // nuclei
+    else pdgBin = ncodes+1; // unknown
+  }
+  return pdgBin;
+}
+
+//_________________________________________________________________________
+Bool_t AliTrackletTaskUni::HaveCommonParent(const float* clLabs0,const float* clLabs1)
+{
+  // do 2 clusters have common parrent
+  const int kMaxPar = 50;
+  static int pars[2][50];
+  int npars[2]={0,0};
+  const float *labs[2] = {clLabs0,clLabs1};
+  int ntr = fStack->GetNtrack();
+  for (int il=0;il<2;il++) {
+    for (int ilb=0;ilb<3;ilb++) {
+      int lbl = (int)labs[il][ilb];
+      if (lbl<0 || lbl>=ntr) continue;
+      //
+      while (npars[il]<kMaxPar-1) {
+       pars[il][ npars[il]++ ] = lbl;
+       TParticle* part = fStack->Particle(lbl);
+       if (!part) break;
+       lbl = part->GetFirstMother();
+       if (lbl<1 || lbl>=ntr) break;
+      }
+    }
+  }
+  // compare array of parents
+  for (int i0=npars[0];i0--;) for (int i1=npars[1];i1--;) if (pars[0][i0]==pars[1][i1]) return kTRUE;
+  return kFALSE;
+}
+
+
+//_________________________________________________________________________
+void AliTrackletTaskUni::CheckReconstructables()
+{
+  // fill reconstructable tracklets hitsos
+  static TArrayI trInd;
+  static TBits   isPrimArr;
+  //
+  if (!fMultReco || !fMultReco->IsRecoDone()) {AliInfo("To check reconstructables the reco had to be requested"); return;}
+  if (!fStack) {AliInfo("MC Stack is not availalble"); return;}
+  const double kPtMin = 0.05;
+  //
+  TClonesArray *clArr[2];
+  for (int ilr=0;ilr<2;ilr++) {
+    clArr[ilr] = fMultReco->GetClustersOfLayer(ilr);
+    if (!clArr[ilr]) {AliInfo("Clusters are not available"); return;}
+  }
+  //
+  int ntr = fStack->GetNtrack();
+  if (!ntr) return;
+  trInd.Reset();
+  if (trInd.GetSize()<ntr) trInd.Set(ntr);
+  isPrimArr.ResetAllBits();
+  // count track wich may be reconstructable
+  //
+  int ntrStore=0,ntrStorePrim=0; 
+  Int_t *trIndArr = trInd.GetArray();
+  for (Int_t it=0; it<ntr; it++) {
+    TParticle* part = fStack->Particle(it);
+    if (TMath::Abs(part->Eta())>2.2)       continue;
+    if (TMath::Abs(part->Pt())<kPtMin)      continue;
+    if (fStack->IsPhysicalPrimary(it)) {
+      isPrimArr.SetBitNumber(it);
+      ntrStorePrim++;
+    }
+    else { // check if secondary is worth cheking
+      TParticlePDG* pdgPart = part->GetPDG();
+      if (TMath::Abs(pdgPart->Charge())!=3)  continue;
+      if (part->R()>5.)                      continue;
+    }
+    trIndArr[it] = ++ntrStore;
+  }
+  //
+  AliInfo(Form("Selected %d MC particles (%d prim) out of %d in the stack\n",ntrStore,ntrStorePrim,ntr));
+  //
+  const int kMaxCl=3;
+  AliITSRecPoint **clIndL[2];
+  clIndL[0] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+  clIndL[1] = new AliITSRecPoint*[kMaxCl*ntrStore]; // max 2 clusters per layer
+  memset(clIndL[0],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+  memset(clIndL[1],0,kMaxCl*ntrStore*sizeof(AliITSRecPoint*));
+  //
+  for (int ilr=0;ilr<2;ilr++) {
+    TClonesArray *clusters = clArr[ilr];
+    int ncl = clusters->GetEntriesFast();
+    for (int icl=ncl;icl--;) {
+      AliITSRecPoint *cl = (AliITSRecPoint*)clusters->UncheckedAt(icl);
+      for (int ilb=3;ilb--;) {
+       int lbl = cl->GetLabel(ilb); if (lbl<0 || lbl>=ntr) continue;
+       int lblI = trIndArr[lbl];
+       if (--lblI<0) continue;    // not kept
+       for (int icc=0;icc<kMaxCl;icc++) if (!clIndL[ilr][lblI+icc*ntrStore]) {clIndL[ilr][lblI+ntrStore*icc] = cl; break;} // first empty one
+      }
+    }
+  }
+  //
+  Float_t clusterLay[2][AliITSMultReconstructor::kClNPar];
+  double trComp[6][kMaxCl*kMaxCl];
+  int indQual[kMaxCl*kMaxCl];
+  //
+  for (int itr=ntr;itr--;) {
+    int lblI = trIndArr[itr];
+    if (--lblI<0) continue; // discarded
+    int ntrCand = 0;        // number of tracklet candidates (including overlaps)
+    for (int icl0=0;icl0<kMaxCl;icl0++) {
+      AliITSRecPoint *cl0 = clIndL[0][lblI+icl0*ntrStore];
+      if (!cl0 || !clIndL[1][lblI]) break;
+      cl0->GetGlobalXYZ( clusterLay[0] );
+      fMultReco->ClusterPos2Angles(clusterLay[0], fESDVtx);
+      for (int icl1=0;icl1<kMaxCl;icl1++) {
+       AliITSRecPoint *cl1 = clIndL[1][lblI+icl1*ntrStore];
+       if (!cl1) break;
+       cl1->GetGlobalXYZ( clusterLay[1] );
+       fMultReco->ClusterPos2Angles(clusterLay[1], fESDVtx);
+       trComp[AliITSMultReconstructor::kTrPhi][ntrCand]    = clusterLay[0][AliITSMultReconstructor::kClPh];
+       trComp[AliITSMultReconstructor::kTrTheta][ntrCand]  = clusterLay[0][AliITSMultReconstructor::kClTh];      
+       trComp[AliITSMultReconstructor::kTrDTheta][ntrCand] = clusterLay[0][AliITSMultReconstructor::kClTh] - clusterLay[1][AliITSMultReconstructor::kClTh]; 
+       trComp[AliITSMultReconstructor::kTrDPhi][ntrCand]   = clusterLay[0][AliITSMultReconstructor::kClPh] - clusterLay[1][AliITSMultReconstructor::kClPh];
+       trComp[AliITSMultReconstructor::kTrLab1][ntrCand]   = icl1*10 + icl0;
+       double &dphi = trComp[ntrCand][3];
+       if (dphi>TMath::Pi()) dphi=2.*TMath::Pi()-dphi;     // take into account boundary condition
+       trComp[5][ntrCand] = fMultReco->CalcDist(trComp[AliITSMultReconstructor::kTrDPhi][ntrCand], 
+                                                trComp[AliITSMultReconstructor::kTrDTheta][ntrCand], 
+                                                trComp[AliITSMultReconstructor::kTrTheta][ntrCand]);
+       ntrCand++;
+      }
+    }
+    if (!ntrCand) continue; // no tracklets
+    if (ntrCand>1) TMath::Sort(ntrCand,trComp[5],indQual,kFALSE); else indQual[0] = 0; // sort in weighted distance
+    if (fRemoveOverlaps) ntrCand = 1; // select the best
+    //
+    // disable worst tracklet with shared cluster
+    for (int itc=0;itc<ntrCand;itc++) {
+      int ind = indQual[itc];
+      if (trComp[AliITSMultReconstructor::kTrLab1][ind]<0) continue; // already disabled
+      for (int jtc=itc+1;jtc<ntrCand;jtc++) {
+       int jnd = indQual[jtc];
+       if (trComp[AliITSMultReconstructor::kTrLab1][jnd]<0) continue; // already disabled
+       if ( int(trComp[AliITSMultReconstructor::kTrLab1][ind])/10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])/10 ||
+            int(trComp[AliITSMultReconstructor::kTrLab1][ind])%10 == int(trComp[AliITSMultReconstructor::kTrLab1][jnd])%10) trComp[AliITSMultReconstructor::kTrLab1][jnd] = -1;
+      }
+    }
+    //
+    // store, but forbid cluster reusing
+    TObjArray* histos = isPrimArr.TestBitNumber(itr) ? fHistosTrRcblPrim : fHistosTrRcblSec;
+    for (int itc=0;itc<ntrCand;itc++) {
+      int ind = indQual[itc];
+      if (trComp[4][ind]<0) continue; // discarded
+      FillHistosSet(histos,
+                   trComp[AliITSMultReconstructor::kTrPhi][ind],trComp[AliITSMultReconstructor::kTrTheta][ind],
+                   trComp[AliITSMultReconstructor::kTrDPhi][ind],trComp[AliITSMultReconstructor::kTrDTheta][ind],
+                   trComp[5][ind]);
+    }
+  }
+  //
+  delete[] clIndL[0];
+  delete[] clIndL[1];
+}
+
diff --git a/PWG0/multVScentPbPb/AliTrackletTaskUni.h b/PWG0/multVScentPbPb/AliTrackletTaskUni.h
new file mode 100755 (executable)
index 0000000..29cbe44
--- /dev/null
@@ -0,0 +1,229 @@
+#ifndef ALITRACKLETTASKUNI_H
+#define ALITRACKLETTASKUNI_H
+
+///////////////////////////////////////////////////////////////////////////
+// Class AliTrackletTask                                                 //
+// Analysis task to study performance of tracklet reconstruction         //
+// algorithm and combinatorial background                                //
+// Author:  M. Nicassio (INFN Bari)                                      //
+// Contact: Maria.Nicassio@ba.infn.it, Domenico.Elia@ba.infn.it          //
+///////////////////////////////////////////////////////////////////////////
+
+class TH1F; 
+class TH2F;
+class AliESDEvent;
+class TList;
+class TNtuple;
+
+class AliMCParticle;
+class AliITSMultRecBg;
+
+#include "../ITS/AliITSsegmentationSPD.h"
+#include "AliAnalysisTaskSE.h"
+#include "AliTriggerAnalysis.h" 
+
+class AliTrackletTaskUni : public AliAnalysisTaskSE {
+ public:
+  enum {kData,kBgInj,kBgRot,kBgMix,kMC};
+  //
+  enum {  // define here id's of the standard histos in corresponding TObjArray* fHistosTr...
+    kHEtaZvDist,      // 3 d sparse histo with dist  (uncut) vs zv vs eta
+    kHEtaZvDPhiS,     // 3 d sparse histo with dphiS (uncut) vs zv vs eta
+    kHEtaZvCut,       // zv vs eta with strict cut on tracklets applied (dist<1 or |dPhi|<narrowWindow)
+    kHDPhiDTheta,     // measured dTheta vs dPhi
+    kHDPhiSDThetaX,   // dTheta (1/sin^2 scaled if needed) vs dPhi (bending subtracted)
+    kHEtaDPhiS,       // dPhi (bending subtracted) vs eta
+    kHEtaDThetaX,     // dTheta (1/sin^2 scaled if needed) vs eta
+    kHEtaDist,        // Weighted distance vs eta
+    kHZvDPhiS,        // dPhi (bending subtracted) vs Zv
+    kHZvDThetaX,      // dTheta (1/sin^2 scaled if needed) vs Zv
+    kHZvDist          // Weighted distance vs Zv
+  };
+  enum { // define here id's of any custom histos to be added to fHistosCustom
+    kHStat,            // job info (meaning of bins defined in the enum below)
+    kHZVEtaPrimMC,     // Zv vs eta for all primary tracks (true MC multiplicity)
+    //
+    kHZVtxNoSel,       // Z vertex distribution before event selection
+    kHNTrackletsNoSel, // N tracklets before event selection
+    kHNClSPD1NoSel,    // N clusters on SPD1 before event selection
+    kHNClSPD2NoSel,    // N clusters on SPD2 before event selection
+    kHV0NoSel,         // V0 mult before selection
+    kHV0NClSPD2NoSel,  // V0 - nspd2 correlation
+    //
+    kHZVtx,            // Z vertex distribution
+    kHNTracklets,      // N tracklets
+    kHNClSPD1,         // N clusters on SPD1
+    kHNClSPD2,         // N clusters on SPD2
+    kHV0,              // V0 mult after selection
+    //
+    kHZVtxMixDiff,     // difference in Z vtx of mixed events
+    kHNTrMixDiff,      // difference in N tracklets of mixed events
+    //
+    kHPrimPDG,         // PDG code of prim tracklet
+    kHSecPDG,          // PDG code of sec tracklet
+    kHPrimParPDG,      // PDG code of prim tracklet parent
+    kHSecParPDG        // PDG code of sec tracklet parent
+  }; // custom histos
+
+  // bins for saved parameters
+  enum {kDummyBin,
+       kEvTot,       // events read
+       kEvProcData,  // events with data mult.object (ESD or reco)
+       kEvProcInj,   // events Injected
+       kEvProcRot,   // events Rotated
+       kEvProcMix,   // events Mixed
+       //
+       kDPhi,        // dphi window
+       kDTht,        // dtheta window
+       kNStd,        // N.standard deviations to keep
+       kPhiShift,    // bending shift
+       kThtS2,       // is dtheta scaled by 1/sin^2
+       kThtCW,       // on top of w.dist cut cut also on 1 sigma dThetaX
+       kPhiOvl,      // overlap params
+       kZEtaOvl,     // overlap params
+       kNoOvl,       // flag that overlap are suppressed
+       //
+       kPhiRot,      // rotation phi
+       kInjScl,      // injection scaling
+       kEtaCut,      // eta cut
+       kZVMin,       // min ZVertex to process
+       kZVMax,       // max ZVertex to process
+       kTrcMin,      // min mult to process
+       kTrcMax,      // max mult to process
+       //
+       kOneUnit=49,  // just 1 to track mergings
+       kNWorkers=50, // n workers
+       kNStatBins
+  };
+
+  //
+  AliTrackletTaskUni(const char *name = "AliTrackletTaskUni");
+  virtual ~AliTrackletTaskUni(); 
+  
+  virtual void  UserCreateOutputObjects();
+  virtual void  UserExec(Option_t *option);
+  virtual void  Terminate(Option_t *);
+
+  void       SetUseMC(Bool_t mc = kFALSE)              {fUseMC = mc;}
+  void       SetCheckReconstructables(Bool_t c=kFALSE) {fCheckReconstructables = c;}
+  TObjArray* BookHistosSet(const char* pref, UInt_t selHistos=0xffffffff);
+  TObjArray* BookCustomHistos();
+  void       AddHisto(TObjArray* histos, TObject* h, Int_t at=-1);
+  void       FillHistosSet(TObjArray* histos, double phi,double theta,double dphi,double dtheta,double dist);
+  // RS
+  void       SetNStdDev(Float_t f=1.)           {fNStdDev = f<1e-5 ? 1e-5:f;}
+  void       SetScaleDThetaBySin2T(Bool_t v=kFALSE) {fScaleDTBySin2T = v;}
+  void       SetCutOnDThetaX(Bool_t v=kFALSE)   {fCutOnDThetaX = v;}
+  void       SetPhiWindow(float w=0.08)         {fDPhiWindow   = w<1e-5 ? 1e-5:w;}
+  void       SetThetaWindow(float w=0.025)      {if (w<0) fCutOnDThetaX=kTRUE; fDThetaWindow = TMath::Abs(w)<1e-5 ? 1e-5:TMath::Abs(w);}
+  void       SetPhiShift(float w=0.0045)        {fDPhiShift = w;}
+  void       SetPhiOverlapCut(float w=0.005)    {fPhiOverlapCut = w;}
+  void       SetZetaOverlapCut(float w=0.05)    {fZetaOverlap = w;}
+  void       SetPhiRot(float w=0)               {fPhiRot = w;}
+  void       SetInjScale(Float_t s=1.)          {fInjScale = s>0? s:1.;}
+  void       SetRemoveOverlaps(Bool_t w=kFALSE) {fRemoveOverlaps = w;}
+  //
+  void       SetEtaCut(Float_t eta)             {fEtaCut = eta;}
+  void       SetZVertexMin(Float_t z)           {fZVertexMin = z;}
+  void       SetZVertexMax(Float_t z)           {fZVertexMax = z;}
+  void       SetMultCutMin(Int_t n=0)           {fMultCutMin = n;}
+  void       SetMultCutMax(Int_t n=99999)       {fMultCutMax = n;}
+  //
+  Bool_t     GetDoNormalReco()             const {return fDoNormalReco;}
+  Bool_t     GetDoInjection()              const {return fDoInjection;}
+  Bool_t     GetDoRotation()               const {return fDoRotation;}
+  Bool_t     GetDoMixing()                 const {return fDoMixing;}
+  //
+  void       SetDoNormalReco(Bool_t v=kTRUE)    {fDoNormalReco = v;}
+  void       SetDoInjection(Bool_t v=kTRUE)     {fDoInjection = v;}
+  void       SetDoRotation(Bool_t v=kTRUE)      {fDoRotation = v;}
+  void       SetDoMixing(Bool_t v=kTRUE)        {fDoMixing = v;}
+  //
+  /*
+  void       SetTrigger(AliTriggerAnalysis::Trigger trigger)  { fTrigger = trigger; }
+  void       SetMCCentralityBin(MCCentralityBin mccentrbin)   { fMCCentralityBin = mccentrbin;}
+  void       SetCentralityLowLim(Float_t centrlowlim)         { fCentrLowLim = centrlowlim;}
+  void       SetCentralityUpLim(Float_t centruplim)           { fCentrUpLim = centruplim;}
+  void       SetCentralityEst(TString centrest)               { fCentrEst = centrest;}
+  */
+  //
+ protected:
+  void       InitMultReco();
+  Bool_t     HaveCommonParent(const float* clLabs0,const float* clLabs1);
+  void       FillHistos(Int_t type, const AliMultiplicity* mlt);
+  void       FillMCPrimaries(TH2F* hetaz);
+  void       FillSpecies(Int_t primsec, Int_t id, Double_t dist);
+  Int_t      GetPdgBin(Int_t pdgCode);
+  void       CheckReconstructables();
+  //
+ protected:
+  TList*       fOutput;                   // output list send on output slot 1 
+  //
+  Bool_t       fDoNormalReco;              // do normal reco
+  Bool_t       fDoInjection;               // do injection
+  Bool_t       fDoRotation;                // do rotation
+  Bool_t       fDoMixing;                  // do mixing
+  //
+  Bool_t       fUseMC; 
+  Bool_t       fCheckReconstructables;
+  //
+  TObjArray*   fHistosTrData;              //! all tracklets in data
+  TObjArray*   fHistosTrInj;               //! injected
+  TObjArray*   fHistosTrRot;               //! rotated
+  TObjArray*   fHistosTrMix;               //! mixed
+  //
+  TObjArray*   fHistosTrPrim;              //! primary
+  TObjArray*   fHistosTrSec;               //! secondary
+  TObjArray*   fHistosTrComb;              //! combinatorials
+  TObjArray*   fHistosTrCombU;             //! combinatorials uncorrelated
+  //
+  TObjArray*   fHistosTrRcblPrim;          //! Primary Reconstructable
+  TObjArray*   fHistosTrRcblSec;           //! Secondary Reconstructable
+  TObjArray*   fHistosCustom;              //! custom histos
+  //
+  // Settings for the reconstruction
+  // tracklet reco settings
+  Float_t      fEtaCut;                    // histos filled only for this eta range
+  Float_t      fZVertexMin;                // min Z vtx to process
+  Float_t      fZVertexMax;                // max Z vtx to process
+  Int_t        fMultCutMin;                // min mult in ESD to process?
+  Int_t        fMultCutMax;                // max mult in ESD to process?
+  //
+  Bool_t       fScaleDTBySin2T;            // request dTheta scaling by 1/sin^2(theta)
+  Bool_t       fCutOnDThetaX;              // if true, apart from NStdDev cut apply also the cut on dThetaX
+  Float_t      fNStdDev;                   // cut on weighted distance
+  Float_t      fDPhiWindow;                // max dPhi
+  Float_t      fDThetaWindow;              // max dTheta
+  Float_t      fDPhiShift;                 // mean bend
+  Float_t      fPhiOverlapCut;             // overlaps cut in phi
+  Float_t      fZetaOverlap;               // overlaps cut in Z
+  Float_t      fPhiRot;                    // rotate L1 wrt L2
+  Float_t      fInjScale;                  // scaling factor for injection
+  Bool_t       fRemoveOverlaps;            // request overlaps removal
+  //
+  AliITSMultRecBg *fMultReco;              //! mult.reco object
+  TTree*       fRPTree;                    //! tree of recpoints
+  TTree*       fRPTreeMix;                 //! tree of recpoints for mixing
+  AliStack*    fStack;                     //! MC stack
+  AliMCEvent*  fMCEvent;                   //! MC Event
+  Float_t      fESDVtx[3];                 //  ESD vertex
+  //
+  /*
+  AliTriggerAnalysis::Trigger fTrigger;    // requested trigger
+  MCCentralityBin fMCCentralityBin;        // to select MC centrality bin in which corrections are calculated
+  Float_t      fCentrLowLim;               // to select centrality bin on data
+  Float_t      fCentrUpLim;                // to select centrality bin on data
+  TString      fCentrEst;                  // to select centrality estimator
+  */
+  static const char*  fgkPDGNames[];                //!pdg names
+  static const Int_t  fgkPDGCodes[];                //!pdg codes
+  //
+ private:    
+  AliTrackletTaskUni(const AliTrackletTaskUni&); // not implemented
+  AliTrackletTaskUni& operator=(const AliTrackletTaskUni&); // not implemented 
+  
+  ClassDef(AliTrackletTaskUni, 1);  
+};
+
+
+#endif
diff --git a/PWG0/multVScentPbPb/AnalysisMacroGlob.C b/PWG0/multVScentPbPb/AnalysisMacroGlob.C
new file mode 100755 (executable)
index 0000000..c4fb625
--- /dev/null
@@ -0,0 +1,188 @@
+void AnalysisMacroGlob(TString dataset="/alice/sim/LHC10f8f_130844",
+                      TString outFName="glovar.root",
+                      Int_t  nEvents     = 5000,
+                      Int_t  nEventsSkip = 0) 
+{
+  //  
+  TString format = GetFormatFromDataSet(dataset);
+  //
+  // ALICE stuff
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) mgr = new AliAnalysisManager("Test train");
+  //
+  Bool_t isMC = dataset.Contains("sim");
+  InputHandlerSetup(format,kFALSE,isMC);
+  gProof->Load("AliTaskGlobVar.cxx++g");
+  //
+  /*
+  gROOT->LoadMacro("AddTaskGlobVar.C");
+  AliTaskGlobVar *task = AddTaskGlobVar(outFName.Data());
+  */
+  AliTaskGlobVar *task = new AliTaskGlobVar("AliTaskGlobVar");
+  // create output container
+  AliAnalysisDataContainer *coutput1 = 
+    mgr->CreateContainer("clist", TList::Class(),AliAnalysisManager::kOutputContainer,outFName.Data());
+  // add our task to the manager
+  mgr->AddTask(task);
+  //
+  // finaly connect input and output
+  mgr->ConnectInput(task, 0,  mgr->GetCommonInputContainer());
+  mgr->ConnectOutput(task,1,coutput1);
+  //
+  if (!isMC) {
+    AddPhysicsSelection();
+    task->SelectCollisionCandidates( AliVEvent::kUserDefined );
+    task->SetUseMC(kFALSE);
+  }
+  else task->SetUseMC(kTRUE);
+  //  else task->SelectCollisionCandidates( AliVEvent::kMB);
+  //
+  // Run analysis
+  mgr->InitAnalysis();
+  // process dataset  
+  mgr->StartAnalysis("proof", dataset.Data(), nEvents, nEventsSkip); 
+  //
+  TString evstCmd = "if [ -e event_stat.root ]; then \nmv event_stat.root evstat_"; 
+  evstCmd += outFName;  evstCmd += " \nfi";
+  gSystem->Exec( evstCmd.Data() );
+  
+}
+
+
+TString GetFormatFromDataSet(TString dataset) {
+  
+//   Info("runAAF.C","Detecting format from dataset (may take while, depends on network connection)...");
+  TString dsTreeName;
+  if (dataset.Contains("#")) {
+    Info("runAAF.C",Form("Detecting format from dataset name '%s' ...",dataset.Data()));
+    dsTreeName=dataset(dataset.Last('#'),dataset.Length());
+  } else {
+    Info("runAAF.C",Form("Detecting format from dataset '%s' (may take while, depends on network connection) ...",dataset.Data()));
+    TFileCollection *ds = gProof->GetDataSet(dataset.Data());
+    if (!ds) {
+      Error(Form("Dataset %s doesn't exist on proof cluster!!!!",dataset.Data()));
+      return "";
+    }
+    dsTreeName = ds->GetDefaultTreeName();
+  }
+
+  if (dsTreeName.Contains("esdTree")) {
+    Info("runAAF.C","ESD input format detected ...");
+    return "ESD";
+  } else if (dsTreeName.Contains("aodTree"))  {
+    Info("runAAF.C","AOD input format detected ...");
+    return "AOD";
+  } else {
+    Error("runAAF.C",Form("Tree %s is not supported !!!",dsTreeName.Data()));
+    Error("runAAF.C",Form("Maybe set your DS to %s#esdTree or %s#aodTree",dataset.Data(),dataset.Data()));
+  }
+  
+  return "";
+}
+
+Bool_t InputHandlerSetup(TString format = "esd", Bool_t useRP=kFALSE, Bool_t useKine = kFALSE)
+{
+  format.ToLower();
+
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+
+  AliAnalysisDataContainer *cin = mgr->GetCommonInputContainer();
+
+  if (cin) return;
+
+  if (!format.CompareTo("esd"))
+  {
+    AliESDInputHandler *esdInputHandler = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+    if (!esdInputHandler)
+    {
+      Info("CustomAnalysisTaskInputSetup", "Creating esdInputHandler ...");
+      if (useRP) esdInputHandler = new AliESDInputHandlerRP();
+      else       esdInputHandler = new AliESDInputHandler();
+      mgr->SetInputEventHandler(esdInputHandler);
+    }
+    
+    if (useKine)
+    {
+      AliMCEventHandler* mcInputHandler = dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+
+      if (!mcInputHandler)
+      {
+        Info("CustomAnalysisTaskInputSetup", "Creating mcInputHandler ...");
+        AliMCEventHandler* mcInputHandler = new AliMCEventHandler();
+        mgr->SetMCtruthEventHandler(mcInputHandler);
+      }
+    }
+
+  }
+  else if (!format.CompareTo("aod"))
+  {
+    AliAODInputHandler *aodInputHandler = dynamic_cast<AliAODInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+    if (!aodInputHandler)
+    {
+      Info("CustomAnalysisTaskInputSetup", "Creating aodInputHandler ...");
+      aodInputHandler = new AliAODInputHandler();
+      mgr->SetInputEventHandler(aodInputHandler);
+    }
+  }
+  else
+  {
+    Info("Wrong input format!!! Only ESD and AOD are supported. Skipping Task ...");
+    return kFALSE;
+  }
+
+  return kTRUE;
+}
+
+void AddPhysicsSelection(Bool_t isMC=kFALSE)
+{
+  // physics selection a la Michele
+  printf("Requesting physics selection in %s mode\n",isMC ? "MC":"Data");
+  gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+  //isMC is true when processing monte carlo, the second 0 disables the cluster vs tracklets
+  AliPhysicsSelectionTask* physicsSelectionTask = AddTaskPhysicsSelection(isMC,0);
+  if(!isMC) {
+    AliPhysicsSelection * physSel = physicsSelectionTask->GetPhysicsSelection();
+    physSel->AddCollisionTriggerClass("+CMBAC-B-NOPF-ALL");
+    /*
+    physSel->AddCollisionTriggerClass("+CMBS1C-B-NOPF-ALL");
+    physSel->AddCollisionTriggerClass("+CMBS1A-B-NOPF-ALL");
+    */
+    //
+    physSel->AddCollisionTriggerClass("+CMBS2C-B-NOPF-ALL");
+    physSel->AddCollisionTriggerClass("+CMBS2A-B-NOPF-ALL");
+    //
+    // This are needed only to fill the statistics tables
+    physSel->AddBGTriggerClass("+CMBAC-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBAC-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBAC-E-NOPF-ALL");
+    //
+    /*
+    physSel->AddBGTriggerClass("+CMBS1C-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1C-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1C-E-NOPF-ALL");
+    //
+    physSel->AddBGTriggerClass("+CMBS1A-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1A-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1A-E-NOPF-ALL");
+    //
+    */
+    /*
+    //
+    physSel->AddBGTriggerClass("+CMBS2C-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2C-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2C-E-NOPF-ALL");
+    //
+    physSel->AddBGTriggerClass("+CMBS2A-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2A-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2A-E-NOPF-ALL");
+    */
+  } 
+  // if you use the following line, your task only gets the selected events
+  //  task->SelectCollisionCandidates(AliVEvent::kUserDefined);
+  //
+  //Alternatively, in the UserExec of your task:
+  //Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kUserDefined);
+  //
+}
diff --git a/PWG0/multVScentPbPb/CorrectSpectra.C b/PWG0/multVScentPbPb/CorrectSpectra.C
new file mode 100755 (executable)
index 0000000..6dd8b86
--- /dev/null
@@ -0,0 +1,1300 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TList.h"
+#include "TFile.h"
+#include "TStyle.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "THnSparse.h"
+#include "TLegend.h"
+#include "TSystem.h"
+#include "TMath.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+#include "TLatex.h"
+#include "TF1.h"
+#include "TLine.h"
+#include "TPaletteAxis.h"
+//
+//
+#endif
+#include "/home/shahoian/ALICE/mymacros/SaveCanvas.h"
+
+
+
+const char kHStatName[]="hStat";
+double kEps = 1e-6;
+//
+double kdPhiBgTailMin = 0.1; // lower limit of dphi tail to use for bg normalization  
+double kdPhiBgTailMax = 0.3; // upper limit of dphi tail to use for bg normalization   
+//
+double kWDistBgTailMin = 5.; // lower limit of wgh.distance tail to use for bg normalization  
+double kWDistBgTailMax = 25.; // upper limit of wgh.distance tail to use for bg normalization
+
+double kdPhiSgCut = 0.06;     // cut in dphi-bent used to extract the signal, extracted from stat histo
+double kWDistSgCut = 1.5;        // cut in w.distance used to extract the signal, extracted from stat histo
+//
+enum { kNormShapeDist,      // normalize bg tails usig weighted distance shape 
+       kNormShapeDPhi,      // normalize bg tails usig dPhi-bend shape
+       kNormShapes};
+
+enum { kSclWghMean,         // normalize bg tails to data using weighted mean of bin-by-bin ratios 
+       kSclIntegral,        // normalize bg tails to data using integral
+       kSclTypes};
+
+// histograms to be used for bg nomalization for each of NormShapes used
+const char* kNormShapeH[kNormShapes] = {
+  "EtaDist",                // Weighted distance vs Eta
+  "EtaDPhiS"                // Dphi-bent vs distance
+}; 
+
+const char* figDir = "fig161110";
+TString  useBgType    = "Inj";
+Int_t    useShapeType = kNormShapeDist;    // which distribution to use for bg normalization
+Bool_t   useMCLB      = 0;//kFALSE;             // use Comb MC Labels as a template for Bg.
+Int_t    useScaleType = kSclIntegral;//kSclWghMean;       // which type of tails normalization to use
+Double_t useEtaCut    = 1.;                // cut on eta
+Double_t useZvMin     = -5.;                // cut on Z vertex
+Double_t useZvMax     =  5.;                // cut on Z vertex
+Int_t    useBinGrEta  = -1;                // for bg fits group eta bins
+Int_t    useBinGrZv   = -1;                // for bg fits group Zv bins
+
+enum {kBitNormPerEvent=BIT(14)};
+  // bins for saved parameters in the hStat histo
+enum {kDummyBin,
+      kEvTot,       // events read
+      kEvProcData,  // events with data mult.object (ESD or reco)
+      kEvProcInj,   // events Injected
+      kEvProcRot,   // events Rotated
+      kEvProcMix,   // events Mixed
+      //
+      kDPhi,        // dphi window
+      kDTht,        // dtheta window
+      kNStd,        // N.standard deviations to keep
+      kPhiShift,    // bending shift
+      kThtS2,       // is dtheta scaled by 1/sin^2
+      kPhiOvl,      // overlap params
+      kZEtaOvl,     // overlap params
+      kNoOvl,       // flag that overlap are suppressed
+      //
+      kPhiRot,      // rotation phi
+      kInjScl,      // injection scaling
+      kEtaCut,      // eta cut
+      kZVMin,       // min ZVertex to process
+      kZVMax,       // max ZVertex to process
+      kTrcMin,      // min mult to process
+      kTrcMax,      // max mult to process
+      //
+      kOneUnit=49,  // just 1 to track mergings
+      kNWorkers=50, // n workers
+      kNStatBins
+};
+
+
+enum {kSigCorr,kMCPrim,kRawDtCut,kSignalEst,kSignalEstMC,kBgEst,k1MBeta,k1MBetaMC,kAlpha,kAlphaMC,kBgMC,kBgRescFc,kDataDist,kBgDist,kBgMCDist, kNHistos, kMCShift=20};
+
+void    CorrectSpectra(const char* flNameData, const char* flNameMC,const char* unique="");
+void    PrepareHistos(TList* lst, Bool_t isMC, TObjArray* outArray);
+void    ProcessHistos(TObjArray* outArray);
+TH1*    NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &scle);
+TObject* FindObject(const char* nameH, const TList* lst, Bool_t normPerEvent=kTRUE);
+TList*  LoadList(const char* flName, const char* addPref, const char* nameL="clist");
+void    GetRatE(double x,double xe, double y,double ye, double &rat, double &rate);
+Int_t   CheckStat(const TList* lst,const char* dtType);
+void    Integrate(TH1* hist, double xmn,double xmx, double &val, double& err);
+void    CropHisto(TH1* histo, int b00, int b01, int b10=-1, int b11=-1);
+void    CropHisto(TH1* histo, double b00, double b01, double b10=-1, double b11=-1);
+void    GetRealMinMax(TH1* h, double &vmn, double &vmx);
+const char*   HName(const char* prefix,const char* htype);
+
+void ProjDZE(THnSparseF* hrawd, THnSparseF* hgenb, THnSparseF* hmcComb, TObjArray* res, int bstep0=-1,int bstep1=-1);
+
+void PlotResults();
+void PlotDNDEta();
+void PlotDist();
+void PlotAlphaBeta();
+void PlotSpecies();
+
+TList *listDt=0, *listMC=0;
+TObjArray resArr;
+char outStr[1000];
+char outTitle[1000];
+TString uniqueName="";
+
+void CorrectSpectra(const char* flNameData, const char* flNameMC, const char* uniqueNm)
+{
+  //
+  uniqueName = uniqueNm;
+  listDt = LoadList(flNameData,"dt_");
+  listMC = LoadList(flNameMC,"mc_");
+  //
+  resArr.Clear();
+  PrepareHistos(listMC, kTRUE,  &resArr);
+  PrepareHistos(listDt, kFALSE, &resArr);
+  //
+  ProcessHistos(&resArr); 
+  //
+  sprintf(outStr,"CutEta%.1f_Zv%.1f_%.1f_bg%s_Shape_%s_mcLB%d_cutSig%.1f_cutBg%.1f",useEtaCut,useZvMin,useZvMax,useBgType.Data(),
+         useShapeType==kNormShapeDist ? "wdst":"dphi", 
+         useMCLB,
+         useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+         useShapeType==kNormShapeDist ? kWDistBgTailMin:kdPhiBgTailMin);
+  sprintf(outTitle,"%s, |#eta|<%.1f, %.1f<Z_{V}<%.1f,  Bg.:%s, UseMCLB=%d, CutVar:%s, |sig|<%.2f, %.2f<|bg.nrm|<%.2f",
+         uniqueName.Data(),
+         useEtaCut,useZvMin,useZvMax,useBgType.Data(),
+         useMCLB,
+         useShapeType==kNormShapeDist ? "#Delta":"#Delta#varphi-#delta_{#varphi}",
+         useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+         useShapeType==kNormShapeDist ? kWDistBgTailMin : kdPhiBgTailMin,
+         useShapeType==kNormShapeDist ? kWDistBgTailMax : kdPhiBgTailMax         
+         );
+  PlotResults();
+}
+
+//_____________________________________________________________________
+void PrepareHistos(TList* lst, Bool_t isMC, TObjArray* outArray)
+{
+  // params:
+  //
+  int shift = isMC ? kMCShift : 0;
+  //
+  const char* xxZvEta;
+  if (useShapeType==kNormShapeDist) xxZvEta = "DistZvEta";
+  else                              xxZvEta = "DistZvDPhiS";
+
+  printf("PrepareBg  : (%4s) of type %s from %s with shape %d\n",isMC?" MC ":"Data",useBgType.Data(),lst->GetName(),useShapeType);
+  if (!CheckStat(lst,useBgType.Data())) {printf("Bg of type %s is absent in list %s\n",useBgType.Data(),lst->GetName()); return;}
+  //
+  THnSparseF* hD = (THnSparseF*) FindObject(HName("Data",xxZvEta),lst);
+  THnSparseF* hB = (THnSparseF*) FindObject(HName(useBgType.Data(),xxZvEta),lst);
+  //
+  // special feature: use MC Labels bg as a shape instead of generated bg
+  if (useMCLB/* && !isMC*/) {
+    TString nm  = hB->GetName();   nm  += "_MCLB";
+    TString tit = hB->GetTitle();  tit += "_MCLB";
+    THnSparseF* hBMCLB = (THnSparseF*) FindObject(HName("Comb",xxZvEta),listMC)->Clone(nm.Data());
+    hBMCLB->SetTitle(tit.Data());
+    hB = hBMCLB;
+  }
+  THnSparseF* hBmc = 0;
+  if (isMC) hBmc = (THnSparseF*) FindObject(HName("Comb",xxZvEta),lst);
+  //
+  ProjDZE(hD,hB,hBmc, outArray, useBinGrEta, useBinGrZv);
+  //
+  if (!isMC) return;
+  //
+  // prepare MC primary signal histo
+  TH2F* mcPrim = (TH2F*)FindObject( "zvEtaPrimMC", lst );
+  mcPrim = (TH2F*) mcPrim->Clone("mcTrueSignal");
+  CropHisto(mcPrim,-useEtaCut,useEtaCut,useZvMin,useZvMax);
+  outArray->AddAtAndExpand(mcPrim, kMCPrim + shift);
+  //
+}
+
+//_____________________________________________________________________
+void ProcessHistos(TObjArray* outArray) 
+{
+  //
+  // build alpha matrix
+  TH2* halp = (TH2*)outArray->At(kMCShift + kMCPrim);
+  halp = (TH2*) halp->Clone("Alpha");
+  halp->SetTitle("#alpha");
+  halp->Divide( (TH2*)outArray->At(kMCShift + k1MBeta) );
+  halp->Divide( (TH2*)outArray->At(kMCShift + kRawDtCut) );
+  halp->SetMinimum(1.5);
+  halp->SetMaximum(4.);
+  outArray->AddAtAndExpand(halp, kAlpha);
+  //
+  // build alpha matrix with MC labels bg
+  TH2* halpMC = (TH2*)outArray->At(kMCShift + kMCPrim);
+  halpMC = (TH2*) halpMC->Clone("AlphaMC");
+  halpMC->SetTitle("#alpha MC labels");
+  halpMC->Divide( (TH2*)outArray->At(kMCShift + k1MBetaMC) );
+  halpMC->Divide( (TH2*)outArray->At(kMCShift + kRawDtCut) );
+  halpMC->SetMinimum(1.5);
+  halpMC->SetMaximum(4.);
+  outArray->AddAtAndExpand(halpMC, kAlphaMC);
+  //
+  // build corrected signal
+  TH2* hsigCorr = (TH2*)outArray->At(kSignalEst);
+  hsigCorr = (TH2*) hsigCorr->Clone("SignalEstCorr");
+  hsigCorr->SetTitle("Corrected Signal");
+  hsigCorr->Multiply( halp );
+  outArray->AddAtAndExpand(hsigCorr, kSigCorr);
+  //
+}
+
+TCanvas *canvFin=0;
+TCanvas *canvAlp=0;
+TCanvas *canvBet=0;
+TCanvas* canvDst=0;
+TCanvas* canvSpec=0;
+
+void PlotResults() 
+{
+  PlotDist();
+  PlotAlphaBeta();
+  PlotSpecies();
+  PlotDNDEta();
+
+}
+
+void PlotDNDEta()
+{
+  //
+  TObjArray *res = &resArr;
+  char buff[1000];
+  // eta range
+  double plEta = useEtaCut*1.1;
+  gStyle->SetOptFit(0);
+  gStyle->SetOptStat(0);
+  gStyle->SetOptTitle(0);
+  double mn = 1e6,mx = -1e6;
+  canvFin = new TCanvas("canvFin", "canvFin",0,50,700,550);
+  canvFin->SetLeftMargin(0.15);
+  //  canvFin->ToggleEventStatus();
+  //
+  // corrected data
+  TH1* hsigCorr = ((TH2F*)res->At(kSigCorr))->ProjectionX("DataCorrSignal");
+  SetHStyle(hsigCorr,kRed,20,1.0);
+  hsigCorr->GetXaxis()->SetRangeUser(-plEta+kEps,plEta-kEps);
+  hsigCorr->Scale(1./hsigCorr->GetBinWidth(1));
+  hsigCorr->Draw();
+  mx = TMath::Max(mx, hsigCorr->GetMaximum());
+  mn = TMath::Min(mn, hsigCorr->GetMinimum());
+  TF1* pl0 = new TF1("pl0","pol0");
+  pl0->SetParameter(0,hsigCorr->GetMinimum());
+  hsigCorr->Fit(pl0,"q0","",-0.5,.5);
+  double fval = pl0->GetParameter(0);
+  double ferr = pl0->GetParError(0);
+  char ftres[1000];
+  sprintf(ftres,"dN/d#eta_{|#eta|<0.5} = %d #pm %d",int(fval),int(ferr));
+  printf("dN/d#eta_{|#eta|<0.5} = %.2f  %.2f\n",fval,ferr);
+  TLatex *txfit = new TLatex(-0.2,hsigCorr->GetMinimum()*0.9, ftres);
+  txfit->SetTextSize(0.04);
+  txfit->Draw();
+  //
+  // raw data
+  TH1* hraw = ((TH2F*)res->At(kRawDtCut))->ProjectionX("DataRaw");
+  SetHStyle(hraw,kRed,21,1.0);
+  hraw->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hraw->Scale(1./hraw->GetBinWidth(1));
+  hraw->Draw("same");
+  mn = TMath::Min(mn, hraw->GetMinimum());
+  mx = TMath::Max(mx, hraw->GetMaximum());
+  //  
+  // raw data bg sub
+  TH1* hraws = ((TH2F*)res->At(kSignalEst))->ProjectionX("DataRawSub");
+  SetHStyle(hraws,kRed,23,1.0);
+  hraws->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hraws->Scale(1./hraw->GetBinWidth(1));
+  hraws->Draw("same");
+  mn = TMath::Min(mn, hraw->GetMinimum());
+  mx = TMath::Max(mx, hraw->GetMaximum());
+  //
+  // bg
+  TH1* hbg = ((TH2F*)res->At(kBgEst))->ProjectionX("BgEst");
+  SetHStyle(hbg,kMagenta,22,1.0);
+  hbg->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hbg->Scale(1./hbg->GetBinWidth(1));
+  hbg->Draw("same");
+  mn = TMath::Min(mn, hbg->GetMinimum());
+  mx = TMath::Max(mx, hbg->GetMaximum());
+  //
+  // mc part ----------------------------
+  // raw data
+  TH1* hrawMC = ((TH2F*)res->At(kRawDtCut+kMCShift))->ProjectionX("DataRawMC");
+  SetHStyle(hrawMC,kBlue,24,1.0);
+  hrawMC->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hrawMC->Scale(1./hrawMC->GetBinWidth(1));
+  hrawMC->Draw("same");
+  mn = TMath::Min(mn, hrawMC->GetMinimum());
+  mx = TMath::Max(mx, hrawMC->GetMaximum());
+  //  
+  // raw data bg sub
+  TH1* hrawsMC = ((TH2F*)res->At(kSignalEst+kMCShift))->ProjectionX("DataRawSubMC");
+  SetHStyle(hrawsMC,kBlue,26,1.0);
+  hrawsMC->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hrawsMC->Scale(1./hrawMC->GetBinWidth(1));
+  hrawsMC->Draw("same");
+  mn = TMath::Min(mn, hrawMC->GetMinimum());
+  mx = TMath::Max(mx, hrawMC->GetMaximum());
+  //
+  // raw data bgMClabels sub
+  TH1* hrawsMCLB = ((TH2F*)res->At(kSignalEstMC+kMCShift))->ProjectionX("DataRawSubMCLB");
+  SetHStyle(hrawsMCLB,kGreen+2,30,1.0);
+  hrawsMCLB->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hrawsMCLB->Scale(1./hrawsMCLB->GetBinWidth(1));
+  hrawsMCLB->Draw("same");
+  mn = TMath::Min(mn, hrawsMCLB->GetMinimum());
+  mx = TMath::Max(mx, hrawsMCLB->GetMaximum());
+  //
+  // bg est
+  TH1* hbgMCEst = ((TH2F*)res->At(kBgEst+kMCShift))->ProjectionX("BgEstMC");
+  SetHStyle(hbgMCEst,kBlue,26,1.0);
+  hbgMCEst->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hbgMCEst->Scale(1./hbgMCEst->GetBinWidth(1));
+  hbgMCEst->Draw("same");
+  mn = TMath::Min(mn, hbgMCEst->GetMinimum());
+  mx = TMath::Max(mx, hbgMCEst->GetMaximum());
+  //  
+  // bg MC
+  TH1* hbgMC = ((TH2F*)res->At(kBgMC+kMCShift))->ProjectionX("BgMC");
+  SetHStyle(hbgMC,kGreen+2,25,1.0);
+  hbgMC->GetXaxis()->SetRangeUser(-plEta,plEta);
+  hbgMC->Scale(1./hbgMC->GetBinWidth(1));
+  hbgMC->Draw("same");
+  mn = TMath::Min(mn, hbgMC->GetMinimum());
+  mx = TMath::Max(mx, hbgMC->GetMaximum());
+  //
+  mn = 0;
+  hsigCorr->SetMinimum(mn);
+  hsigCorr->SetMaximum(mx + 0.4*(mx-mn));
+  gPad->Modified();
+  //
+  TLegend *legDnDeta = new TLegend(0.15,0.75, 0.45,0.95);
+  legDnDeta->SetFillColor(kWhite);
+  legDnDeta->SetHeader("Data");
+  legDnDeta->AddEntry(hsigCorr,"Corrected","pl");
+  legDnDeta->AddEntry(hraw,    "Reconstructed","pl");
+  sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+  legDnDeta->AddEntry(hraws,   buff,"pl");
+  sprintf(buff,"Background %s.",useBgType.Data());
+  legDnDeta->AddEntry(hbg,     buff,"pl");
+  legDnDeta->Draw();
+  //
+  TLegend *legDnDetaMC = new TLegend(0.60,0.72, 0.95,0.95);
+  legDnDetaMC->SetFillColor(kWhite);
+  legDnDetaMC->SetHeader("MC");
+  legDnDetaMC->AddEntry(hrawMC,    "Reconstructed","pl");
+  sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+  legDnDetaMC->AddEntry(hrawsMC,   buff,"pl");
+  sprintf(buff,"Reconstructed - Bckg.%s.","MC.Labels");
+  legDnDetaMC->AddEntry(hrawsMCLB,   buff,"pl");
+  sprintf(buff,"Background %s.",useBgType.Data());
+  legDnDetaMC->AddEntry(hbgMCEst,     buff,"pl");
+  sprintf(buff,"Background %s.","MC Labels");
+  legDnDetaMC->AddEntry(hbgMC,     buff,"pl");
+
+  legDnDetaMC->Draw();
+  //
+  gPad->SetGrid(1.1);
+  gPad->Modified();
+  canvFin->cd();
+  AddLabel(outTitle,0.1,0.97, kBlack,0.025);
+  sprintf(buff,"%s/%sdNdEta_%s",figDir,uniqueName.Data(),outStr);
+  SaveCanvas(canvFin,buff,"cg");
+  //
+}
+//
+void PlotAlphaBeta() 
+{
+  char buff[1000];
+  gStyle->SetOptFit(0);
+  gStyle->SetOptStat(0);
+  gStyle->SetOptTitle(0);
+  TObjArray* res = &resArr;
+  //------------------------------------------------------
+  canvBet = new TCanvas("canvBet","canvBet",10,10,1000,400);
+  canvBet->Divide(3,1,0.01,0.06);
+  canvBet->cd(1);
+  TH1* dtBet = (TH1*)res->At(k1MBeta);
+  TH1* mcBet = (TH1*)res->At(k1MBeta+kMCShift);
+  TH1* mcBetLB = (TH1*)res->At(k1MBetaMC+kMCShift);
+  double mn,mx,mnt,mxt;
+  GetRealMinMax(dtBet,mn,mx);
+  GetRealMinMax(mcBet,mnt,mxt);
+  if (mnt<mn) mn = mnt;
+  if (mxt>mx) mx = mxt;
+  GetRealMinMax(mcBetLB,mnt,mxt);
+  if (mnt<mn) mn = mnt;
+  if (mxt>mx) mx = mxt;
+  //
+  dtBet->SetMinimum(mn - 0.05*(mx-mn));
+  dtBet->SetMaximum(mx + 0.05*(mx-mn));
+  mcBet->SetMinimum(mn - 0.05*(mx-mn));
+  mcBet->SetMaximum(mx + 0.05*(mx-mn));
+  mcBetLB->SetMinimum(mn - 0.05*(mx-mn));
+  mcBetLB->SetMaximum(mx + 0.05*(mx-mn));
+  //
+  canvBet->cd(1);
+  gPad->SetRightMargin(0.15);
+  dtBet->Draw("colz");
+  AddLabel("#beta Data",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  dtBet->GetYaxis()->SetTitleOffset(1.4);
+  TPaletteAxis *p = (TPaletteAxis*)dtBet->FindObject("palette");
+  if (p) p->SetX1NDC(0.85);
+  canvBet->cd(2);
+  gPad->SetRightMargin(0.15);
+  mcBet->Draw("colz");
+  AddLabel("#beta MC (bckg.estimated)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  mcBet->GetYaxis()->SetTitleOffset(1.4);
+  p = (TPaletteAxis*)mcBet->FindObject("palette");
+  if (p) p->SetX1NDC(0.85);
+  canvBet->cd(3);
+  gPad->SetRightMargin(0.15);
+  mcBetLB->Draw("colz");
+  AddLabel("#beta MC (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  mcBetLB->GetYaxis()->SetTitleOffset(1.4);
+  p = (TPaletteAxis*)mcBetLB->FindObject("palette");
+  if (p) p->SetX1NDC(0.85);
+  //
+  canvBet->cd();
+  AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+  //
+  sprintf(buff,"%s/%sBeta_%s",figDir,uniqueName.Data(),outStr);
+  SaveCanvas(canvBet,buff,"cg");
+
+  //------------------------------------------------------
+  canvAlp = new TCanvas("canvAlp","canvAlp",10,10,900,400);
+  canvAlp->Divide(2,1,0.01,0.06);
+  canvAlp->cd(1);
+  TH1* dtAlp = (TH1*)res->At(kAlpha);
+  TH1* mcAlp = (TH1*)res->At(kAlphaMC);
+  GetRealMinMax(dtAlp,mn,mx);
+  GetRealMinMax(mcAlp,mnt,mxt);
+  if (mnt<mn) mn = mnt;
+  if (mxt>mx) mx = mxt;
+  dtAlp->SetMinimum(mn - 0.05*(mx-mn));
+  dtAlp->SetMaximum(mx + 0.05*(mx-mn));
+  mcAlp->SetMinimum(mn - 0.05*(mx-mn));
+  mcAlp->SetMaximum(mx + 0.05*(mx-mn));
+  //
+  canvAlp->cd(1);
+  gPad->SetRightMargin(0.15);
+  dtAlp->Draw("colz");
+  AddLabel("#alpha (bckg.estimated)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  dtAlp->GetYaxis()->SetTitleOffset(1.4);
+  TPaletteAxis *pa = (TPaletteAxis*)dtBet->FindObject("palette");
+  if (pa) pa->SetX1NDC(0.85);
+  canvAlp->cd(2);
+  gPad->SetRightMargin(0.15);
+  mcAlp->Draw("colz");
+  AddLabel("#alpha (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  mcAlp->GetYaxis()->SetTitleOffset(1.4);
+  pa = (TPaletteAxis*)mcBet->FindObject("palette");
+  if (pa) pa->SetX1NDC(0.85);
+  gPad->Modified();
+  canvAlp->cd();
+  AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+  //
+  sprintf(buff,"%s/%sAlpha_%s",figDir,uniqueName.Data(),outStr);
+  SaveCanvas(canvAlp,buff,"cg");
+  
+}
+
+void PlotSpecies() 
+{
+  char buff[1000];
+  gStyle->SetOptFit(0);
+  gStyle->SetOptStat(0);
+  gStyle->SetOptTitle(0);
+  //------------------------------------------------------
+  TH2F* hSpecPrim  = (TH2F*)FindObject( "pdgPrim", listMC,kFALSE);
+  TH2F* hSpecSec   = (TH2F*)FindObject( "pdgSec", listMC,kFALSE);
+  TH2F* hSpecPrimP = (TH2F*)FindObject( "pdgPrimPar", listMC,kFALSE);
+  TH2F* hSpecSecP  = (TH2F*)FindObject( "pdgSecPar", listMC,kFALSE);
+  int nbd = hSpecPrim->GetXaxis()->GetNbins();
+  //
+  TH1* hSpecPrimAll = hSpecPrim->ProjectionX("specPrimAll",1,nbd+1,"e");
+  hSpecPrimAll->Scale(100./hSpecPrimAll->Integral());
+  hSpecPrimAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimAll->GetXaxis()->SetLabelSize(0.06);
+  hSpecPrimAll->GetXaxis()->LabelsOption("v");
+  //
+  TH1* hSpecSecAll  = hSpecSec->ProjectionX("specSecAll",1,nbd+1,"e");
+  hSpecSecAll->Scale(100./hSpecSecAll->Integral());
+  hSpecSecAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecAll->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecPrimPAll = hSpecPrimP->ProjectionX("specPrimPAll",1,nbd+1,"e");
+  hSpecPrimPAll->Scale(100./hSpecPrimPAll->Integral());
+  hSpecPrimPAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimPAll->GetXaxis()->SetLabelSize(0.06);
+  hSpecPrimPAll->GetXaxis()->LabelsOption("v");
+
+  //
+  TH1* hSpecSecPAll  = hSpecSecP->ProjectionX("specSecPAll",1,nbd+1,"e");
+  hSpecSecPAll->Scale(100./hSpecSecPAll->Integral());
+  hSpecSecPAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecPAll->GetXaxis()->SetLabelSize(0.05);
+  //
+  int binCut = hSpecPrim->GetXaxis()->FindBin(kWDistSgCut-kEps);
+  TH1* hSpecPrimSel = hSpecPrim->ProjectionX("specPrimSel",1,binCut,"e");
+  hSpecPrimSel->Scale(100./hSpecPrimSel->Integral());
+  hSpecPrimSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimSel->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecSecSel  = hSpecSec->ProjectionX("specSecSel",1,binCut,"e");
+  hSpecSecSel->Scale(100./hSpecSecSel->Integral());
+  hSpecSecSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecSel->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecPrimPSel = hSpecPrimP->ProjectionX("specPrimPSel",1,binCut,"e");
+  hSpecPrimPSel->Scale(100./hSpecPrimPSel->Integral());
+  hSpecPrimPSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimPSel->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecSecPSel  = hSpecSecP->ProjectionX("specSecPSel",1,binCut,"e");
+  hSpecSecPSel->Scale(100./hSpecSecPSel->Integral());
+  hSpecSecPSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecPSel->GetXaxis()->SetLabelSize(0.05);
+
+
+  canvSpec = new TCanvas("canvSpec","canvSpec",10,10,1100,800);
+  canvSpec->Divide(1,2,0.01,0.01);
+  canvSpec->cd(1);
+  hSpecPrimAll->Draw();
+  SetHStyle(hSpecPrimAll,kBlue,25,1.1);
+  hSpecPrimSel->Draw("same");
+  SetHStyle(hSpecPrimSel,kRed,20,1);
+  //
+  hSpecSecAll->Draw("same");
+  SetHStyle(hSpecSecAll,kGreen,32,1.1);
+  hSpecSecSel->Draw("same");
+  SetHStyle(hSpecSecSel,kBlack,22,1);
+  //
+  TLegend *legPart = new TLegend(0.8,0.72, 0.999,0.999);
+  legPart->SetFillColor(kWhite);
+  legPart->SetHeader("Tracklet PDG");
+  //
+  legPart->AddEntry(hSpecPrimAll,    "Prim., before #Delta cut","pl");
+  legPart->AddEntry(hSpecPrimSel,    "Prim., after #Delta cut","pl");
+  legPart->AddEntry(hSpecSecAll,     "Sec., before #Delta cut","pl");
+  legPart->AddEntry(hSpecSecSel,     "Sec., after #Delta cut","pl");
+  //
+  legPart->Draw();
+  gPad->SetLogy();
+  gPad->SetGrid(1,1);
+  gPad->Modified();
+  //
+  canvSpec->cd(2);
+  hSpecPrimPAll->Draw();
+  SetHStyle(hSpecPrimPAll,kBlue,25,1.1);
+  hSpecPrimPSel->Draw("same");
+  SetHStyle(hSpecPrimPSel,kRed,20,1);
+  //
+  hSpecSecPAll->Draw("same");
+  SetHStyle(hSpecSecPAll,kGreen,32,1.1);
+  hSpecSecPSel->Draw("same");
+  SetHStyle(hSpecSecPSel,kBlack,22,1);
+  //
+  TLegend *legPartP = new TLegend(0.8,0.72, 0.999,0.999);
+  legPartP->SetFillColor(kWhite);
+  legPartP->SetHeader("Tracklet Parents PDG");
+  //
+  legPartP->AddEntry(hSpecPrimPAll,    "Prim., before #Delta cut","pl");
+  legPartP->AddEntry(hSpecPrimPSel,    "Prim., after #Delta cut","pl");
+  legPartP->AddEntry(hSpecSecPAll,     "Sec., before #Delta cut","pl");
+  legPartP->AddEntry(hSpecSecPSel,     "Sec., after #Delta cut","pl");
+  //
+  legPartP->Draw();
+  gPad->SetLogy();
+  gPad->SetGrid(1,1);
+  gPad->Modified();
+  //
+  canvSpec->cd(1);
+  AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+  canvSpec->cd();
+  //
+  sprintf(buff,"%s/%sSpecies_%s",figDir,uniqueName.Data(),outStr);
+  SaveCanvas(canvSpec,buff,"cg");
+}
+
+void PlotDist()
+{
+  TObjArray* res = &resArr;
+  char buff[1000];
+  canvDst = new TCanvas("canvDst","canvDst",10,10,700,500);
+  TH1* mcdst = (TH1*)res->At(kDataDist+kMCShift);
+  TH1* mcdstbg = (TH1*)res->At(kBgDist+kMCShift);
+  TH1* mcdstbgLB = (TH1*)res->At(kBgMCDist+kMCShift);
+  TH1* dtdst = (TH1*)res->At(kDataDist);
+  TH1* dtdstbg = (TH1*)res->At(kBgDist);
+  //
+  TH2* mcDstZN     = (TH2*)FindObject(useShapeType==kNormShapeDist  ?  "TrData_ZvDist":"TrData_ZvDPhiS", listMC );
+  TH2* mcDstZSec   = (TH2*)FindObject(useShapeType==kNormShapeDist  ?  "TrSec_ZvDist":"TrSec_ZvDPhiS", listMC );
+  TH2* mcDstZCombU = (TH2*)FindObject(useShapeType==kNormShapeDist  ?  "TrCombU_ZvDist":"TrCombU_ZvDPhiS", listMC );
+  TH2* mcDstZCombC = (TH2*)FindObject(useShapeType==kNormShapeDist  ?  "TrComb_ZvDist":"TrComb_ZvDPhiS", listMC );
+  //
+  mcDstZN->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+  mcDstZSec->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+  mcDstZCombU->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+  mcDstZCombC->GetXaxis()->SetRangeUser(useZvMin+kEps,useZvMax-kEps);
+  //
+  TH1* mcDstN  = mcDstZN->ProjectionY("mcDstN");
+  TH1* mcDstSec  = mcDstZSec->ProjectionY("mcDstSec");
+  TH1* mcDstCombU = mcDstZCombU->ProjectionY("mcDstCombU");
+  TH1* mcDstCombC = mcDstZCombC->ProjectionY("mcDstCombC");
+  //
+  double scl,sclE;
+  mcDstN = NormalizeBg(mcdst,mcDstN,scl,sclE);
+  mcDstSec->Scale(scl);
+  mcDstCombU->Scale(scl);
+  mcDstCombC->Scale(scl);
+  mcDstCombC->Add(mcDstCombU,-1);
+  //
+  dtdst->Draw("");
+  gPad->Modified();
+  dtdst->GetXaxis()->SetLabelSize(0.03);
+  dtdst->GetXaxis()->SetTitleSize(0.03);
+  dtdst->GetXaxis()->SetTitleOffset(2);
+  dtdstbg->Draw("same");
+
+  mcdst->Draw("same");
+  mcDstSec->Draw("same");
+  mcdstbgLB->Draw("same");
+  mcdstbg->Draw("same");
+  mcDstCombC->Draw("same");
+  //
+
+  SetHStyle(mcdst,kBlue, 25,0.7);
+  SetHStyle(mcdstbgLB,kGreen, 7/*32*/,0.5);
+  SetHStyle(mcdstbg,kCyan, 7/*26*/,0.5);
+  SetHStyle(mcDstCombC,kGreen+2, 21,0.7);
+  SetHStyle(mcDstSec,kBlue+2, 22,0.7);
+  //
+  SetHStyle(dtdst,kRed, 20,0.7);
+  SetHStyle(dtdstbg,kBlue, 34,0.7);
+  //
+  double vmcTot,vmcTotE;
+  double vmcSec,vmcSecE, ratSec,ratSecE;  
+  double vmcCmbEst,vmcCmbEstE, ratCmbEst,ratCmbEstE;
+  double vmcCmb,vmcCmbE, ratCmb,ratCmbE;
+  double vmcCmbC,vmcCmbCE, ratCmbC,ratCmbCE;  
+  double cutSgMin,cutSgMax;
+  double cutBgMin,cutBgMax;
+  if (useShapeType==kNormShapeDist) {
+    cutSgMin = 0;
+    cutSgMax = kWDistSgCut;
+    cutBgMin = kWDistBgTailMin;
+    cutBgMax = kWDistBgTailMax;
+  }
+  else {
+    cutSgMin =  0;
+    cutSgMax =  kdPhiSgCut;
+    cutBgMin =  kdPhiBgTailMin;
+    cutBgMax =  kdPhiBgTailMax;
+  }  
+  Integrate(mcdst,    cutSgMin,cutSgMax, vmcTot,vmcTotE);     
+  Integrate(mcDstSec, cutSgMin,cutSgMax, vmcSec,vmcSecE);
+  GetRatE(vmcSec,vmcSecE, vmcTot,vmcTotE, ratSec,ratSecE);
+  //
+  Integrate(mcdstbgLB, cutSgMin,cutSgMax, vmcCmb,vmcCmbE);  
+  GetRatE(vmcCmb,vmcCmbE, vmcTot,vmcTotE, ratCmb,ratCmbE);
+  //
+  Integrate(mcdstbg,  cutSgMin,cutSgMax, vmcCmbEst,vmcCmbEstE); 
+  GetRatE(vmcCmbEst,vmcCmbEstE, vmcTot,vmcTotE, ratCmbEst,ratCmbEstE);
+  //
+  Integrate(mcDstCombC,  cutSgMin,cutSgMax, vmcCmbC,vmcCmbCE);  
+  GetRatE(vmcCmbC,vmcCmbCE, vmcTot,vmcTotE, ratCmbC,ratCmbCE);
+  //
+  double vdtTot,vdtTotE;
+  double vdtBg,vdtBgE, ratdtBg,ratdtBgE;  
+  //  
+  Integrate(dtdst,    cutSgMin,cutSgMax, vdtTot,vdtTotE);     
+  Integrate(dtdstbg,  cutSgMin,cutSgMax, vdtBg,vdtBgE);     
+  GetRatE( vdtBg,vdtBgE,  vdtTot,vdtTotE, ratdtBg,ratdtBgE);
+  //
+  //
+  double dmn = mcdst->GetMinimum();
+  double dmx = mcdst->GetMaximum();
+  TLine *ln = new TLine(cutSgMax, dmn, cutSgMax, dmx);
+  ln->SetLineColor(kBlack);
+  ln->Draw();
+  TLine *lnc = new TLine(cutBgMin, dmn, cutBgMin, dmx);
+  lnc->SetLineColor(kRed);
+  lnc->Draw();
+  if (useShapeType==kNormShapeDPhi) {
+    ln = new TLine(-cutSgMax, dmn, -cutSgMax, dmx);
+    ln->SetLineColor(kBlack);
+    ln->Draw();
+    //
+    lnc = new TLine(-cutBgMin, dmn, -cutBgMin, dmx);
+    lnc->SetLineColor(kRed);
+    lnc->Draw();
+  }
+  //
+  TLegend *legDstMC1 = new TLegend(0.60,0.72, 0.95,0.95);
+  legDstMC1->SetFillColor(kWhite);
+
+  //
+  legDstMC1->AddEntry(dtdst,    "Data raw","pl");
+  sprintf(buff,"Data Comb. %s. : %.1f%%",useBgType.Data(),ratdtBg*100);
+  legDstMC1->AddEntry(dtdstbg,  buff,"pl");
+  //
+
+
+  legDstMC1->AddEntry(mcdst,    "MC raw","pl");
+  sprintf(buff,"MC Comb. %s. : %.1f%%",useBgType.Data(),ratCmbEst*100);
+  legDstMC1->AddEntry(mcdstbg,  buff,"pl");
+  //
+  sprintf(buff,"MC Comb. %s. : %.1f%%","MC Lbl.",ratCmb*100);
+  legDstMC1->AddEntry(mcdstbgLB,  buff,"pl");
+
+  sprintf(buff,"MC Comb.Uncorr %s. : %.1f%%","MC Lbl.",ratCmbC*100);
+  legDstMC1->AddEntry(mcDstCombC,  buff,"pl");
+
+  sprintf(buff,"MC Sec.   : %.1f%%",ratSec*100);
+  legDstMC1->AddEntry(mcDstSec,  buff,"pl");
+
+  legDstMC1->Draw();
+
+  if (useShapeType==kNormShapeDist) gPad->SetLogx();
+  gPad->SetLogy();
+  gPad->SetGrid(1,1);
+  gPad->Modified();
+  //
+  canvDst->cd();
+  AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+  //
+  sprintf(buff,"%s/%sDst_%s",figDir,uniqueName.Data(),outStr);
+  SaveCanvas(canvDst,buff,"cg");
+  //
+}
+
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, int bx0, int bx1, int by0, int by1)        
+{
+  // fill 0 to all bins outside defined range
+  TAxis *xax = histo->GetXaxis();
+  int nbx = xax->GetNbins(); 
+  double vmn=1e16,vmx=-1e16;
+  if (histo->InheritsFrom(TH2::Class())) {
+    TAxis *yax = histo->GetYaxis();
+    int nby = yax->GetNbins();
+    for (int ix=nbx+2;ix--;) {
+      for (int iy=nby+2;iy--;) {
+       if ((ix<bx0||ix>bx1)||(iy<by0||iy>by1)) {
+         histo->SetBinContent(ix,iy,0);
+         histo->SetBinError(ix,iy,0);
+       }
+       else {
+         double vl = histo->GetBinContent(ix,iy);
+         if (vl<vmn) vmn = vl;
+         if (vl>vmx) vmx = vl;
+       }
+      }
+    }
+  }
+  else {
+    for (int ix=nbx+2;ix--;) {
+      if ((ix<bx0||ix>bx1)) {
+       histo->SetBinContent(ix,0);
+       histo->SetBinError(ix,0);
+      }
+      else {
+       double vl = histo->GetBinContent(ix);
+       if (vl<vmn) vmn = vl;
+       if (vl>vmx) vmx = vl;
+      }
+    }
+  }
+  //
+  if (vmn==vmx) {
+    vmn = 0.95*vmn;
+    vmx = 1.05*vmx;
+  }
+  histo->SetMaximum(vmx);
+  histo->SetMinimum(vmn);
+}
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, double vx0, double vx1, double vy0, double vy1)            
+{
+  // fill 0 to all bins outside defined range
+  TAxis *xax = histo->GetXaxis();
+  int bx0,bx1,by0=-1,by1=-1;
+  bx0 = xax->FindBin(vx0+kEps);
+  bx1 = xax->FindBin(vx1-kEps);
+  if (histo->InheritsFrom(TH2::Class())) {
+    TAxis *yax = histo->GetYaxis();
+    by0 = yax->FindBin(vy0+kEps);
+    by1 = yax->FindBin(vy1-kEps);
+  }
+  CropHisto(histo,bx0,bx1,by0,by1);
+}
+
+//______________________________________________________________________
+TH1* NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &sclE)
+{
+  // match generated bg and data tails, calculate normalization, return normalized bg copy
+  //
+  TAxis* xax = dataH->GetXaxis();
+  int nbtot = xax->GetNbins();
+  int bgBins[2][2] = {{0}}; // limiting bins for tails integration
+  Int_t ntails; // 0 for dphi plot, 1 for weighted dist plot  
+  if  (useShapeType == kNormShapeDist) { // only positive tail
+    bgBins[0][0] = xax->FindBin(kWDistBgTailMin+kEps); // positive tail min bin
+    bgBins[0][1] = xax->FindBin(kWDistBgTailMax-kEps); // positive tail max bin
+    ntails = 1;
+  }
+  else if (useShapeType == kNormShapeDPhi) {         // both tails
+    bgBins[0][0] = xax->FindBin( kdPhiBgTailMin+kEps); // positive tail min bin
+    bgBins[0][1] = xax->FindBin( kdPhiBgTailMax-kEps); // positive tail max bin
+    bgBins[1][0] = xax->FindBin(-kdPhiBgTailMax+kEps); // negative tail min bin
+    bgBins[1][1] = xax->FindBin(-kdPhiBgTailMin-kEps); // positive tail max bin    
+    ntails = 2;
+  }
+  else {printf("NormalizeBg: unknown shape type %d\n",useShapeType);exit(1);}
+  printf("NormalizeBg: bins for tails: right: %d:%d / left: %d:%d\n",bgBins[0][0],bgBins[0][1],bgBins[1][0],bgBins[1][1]);
+  // 
+  double meanR=0,meanRE=0,meanRE2=0;
+  double meanD=0,meanDE2=0;
+  double meanB=0,meanBE2=0;
+  double meanRI=0,meanRIE=0;
+  for (int itp=0;itp<=ntails;itp++) {
+    for (int ib=bgBins[itp][0];ib<=bgBins[itp][1];ib++) {
+      if (ib<1||ib>nbtot) continue;
+      double vD = dataH->GetBinContent(ib);
+      double vB = bgH->GetBinContent(ib);
+      double eD = dataH->GetBinError(ib);
+      double eB = bgH->GetBinError(ib);
+      meanD += vD; meanDE2 += eD*eD;
+      meanB += vB; meanBE2 += eB*eB;
+      if (vD<=0 || vB<=0 || eD<=0 || eB<=0) continue;
+      double rat = vD/vB;
+      double ratE2 = rat*rat*(eD*eD/vD/vD + eB*eB/vB/vB); 
+      meanR   += rat/ratE2; meanRE2 += 1.0/ratE2;
+    }
+  }
+  //
+  if (meanRE2>0) {
+    meanR  /= meanRE2;
+    meanRE2 = 1./meanRE2;
+    meanRE = TMath::Sqrt(meanRE2);
+  }
+  if (meanDE2>0 && meanBE2>0) {
+    meanRI  = meanD/meanB;
+    meanRIE =  meanRI*TMath::Sqrt(meanDE2/meanD/meanD + meanBE2/meanB/meanB);
+  }
+  printf("NormalizeBg: Tails scaling %s wrt %s: Wgh.Mean:%.4f(%.4f) / Integral:%.4f(%.4f)\n",
+        bgH->GetName(),dataH->GetName(), meanR,meanRE, meanRI,meanRIE);
+  printf("NormalizeBg: Select scaling type %s\n",useScaleType==kSclWghMean ? "Wgh.Mean":"Integral");
+  //
+  scl  = useScaleType==kSclWghMean ? meanR  : meanRI;
+  sclE = useScaleType==kSclWghMean ? meanRE : meanRIE;
+  //
+  // rescaled bg
+  char buff[1000];
+  sprintf(buff,"%s_bgNorm",bgH->GetName());
+  bgH = (TH1*)bgH->Clone(buff);
+  sprintf(buff,"%s bgNorm%d %.4f+-%.4f",bgH->GetName(),useScaleType,scl,sclE);
+  TH1* dumH = (TH1*)bgH->Clone("dummySCL$"); dumH->Reset();
+  for (int i=1;i<=nbtot;i++) {
+    dumH->SetBinContent(i,scl);
+    dumH->SetBinError(i,sclE);
+  }
+  bgH->Multiply(dumH);
+  delete dumH;
+  return bgH;
+}
+
+//______________________________________________________________________
+TObject* FindObject(const char* nameH, const TList* lst, Bool_t normPerEvent)
+{
+  // get histo, optionally normalizing it per processed event
+  if (!lst) {printf("FindObject %s: No list provided\n",nameH); exit(1);}
+  int nent = lst->GetEntries();
+  TString nm;
+  TObject *hst = 0;
+  for (int i=nent;i--;) {
+    nm = lst->At(i)->GetName();
+    if (nm.EndsWith(nameH)) {hst = lst->At(i); break;}
+  }
+  if (!hst) {printf("FindObject: No %s histo in list %s\n",nameH,lst->GetName()); exit(1);}
+  if (!normPerEvent || hst->TestBit(kBitNormPerEvent)) return hst; // already normalized
+  TString nameHS = nameH;
+  if (nameHS==kHStatName) return hst;                              // never scale stat. histo
+  //
+  TH1* hstat = (TH1*)FindObject(kHStatName,lst,kFALSE);
+  double nrm = hstat->GetBinContent(kEvProcData);
+  if (nrm<1) {printf("FindObject: Anomaluous %d number of events processed in list %p\n",int(nrm),lst); exit(1);}
+  //
+  // account for eventual cut in Z
+  TH1* hzv = (TH1*)FindObject("zv",lst,kFALSE);
+  int nbz = hzv->GetNbinsX();
+  double zvTot = hzv->Integral(1,nbz);
+  int zb0 = hzv->FindBin( useZvMin+kEps); if (zb0<1)   zb0 = 1;
+  int zb1 = hzv->FindBin( useZvMax-kEps); if (zb1>nbz) zb1 = nbz;
+  double zvSel = hzv->Integral(zb0,zb1);
+  if (zvTot<1 || zvSel<1) {printf("No statistics: NzvTot: %.1f NzvSel:%.f\n",zvTot,zvSel); return 0;}
+  else printf("%f fraction of selected events is used with current Zv cut %.1f:%.1f\n",zvSel/zvTot,useZvMin,useZvMax);
+  nrm *= zvSel/zvTot;
+  //
+  if      (hst->InheritsFrom(TH1::Class())) ((TH1*)hst)->Scale(1./nrm);
+  else if (hst->InheritsFrom(THnSparse::Class())) {
+    THnSparse* spr = (THnSparse*) hst;
+    spr->Sumw2();
+    int coord[3] = {0,0,0};
+    for (Long64_t i = 0; i < spr->GetNbins(); ++i) {
+      // Get the content of the bin from the current histogram
+      Double_t v = spr->GetBinContent(i, coord);
+      spr->SetBinContent(coord, v/nrm);
+      spr->SetBinError(coord,TMath::Sqrt(v)/nrm);
+    }    
+  }
+  //
+  hst->SetBit(kBitNormPerEvent);
+  return hst;
+}
+
+//______________________________________________________________________
+TList* LoadList(const char* flName, const char* addPref, const char* nameL)
+{
+  // load list with histos
+  TString nms = flName;
+  gSystem->ExpandPathName(nms);
+  TFile* fl = TFile::Open(nms.Data());
+  if (!fl) {printf("LoadList: No file %s\n",nms.Data()); exit(1);}
+  TList* lst = (TList*)fl->Get(nameL);
+  if (!lst) {printf("LoadList: No list %s in file %s\n",nameL,nms.Data()); exit(1);}
+  lst->SetName(flName);
+  //
+  int nEnt = lst->GetSize();
+  TString nm;
+  for (int i=0;i<nEnt;i++) {
+    TNamed* ob = (TNamed*)lst->At(i);
+    nm = addPref;
+    nm += ob->GetName();
+    ob->SetName(nm.Data());
+  }
+  //
+  return lst;
+}
+
+//____________________________________________________________________________
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate)
+{
+  rat = 0; rate = 0;
+  if (TMath::Abs(y)<1e-16 || TMath::Abs(x)<1e-16) return;
+  rat = x/y;
+  rate = rat*TMath::Sqrt( xe*xe/(x*x) + ye*ye/(y*y));
+}
+
+//____________________________________________________________________________
+void Integrate(TH1* hist, double xmn,double xmx, double &val, double& err)
+{
+  // integrate 1d histo within given limits
+  TAxis* xax = hist->GetXaxis();
+  int bmn = xax->FindBin(xmn+kEps); if (bmn<1) bmn = 0; // include 
+  int bmx = xax->FindBin(xmx-kEps);
+  val = hist->IntegralAndError(bmn,bmx,err);
+  // is this histo with symmetric axis ? then integrate also negative half axis
+  if (TMath::Abs( xax->GetXmin() + xax->GetXmax() )<1e-6) {
+    bmn = xax->FindBin(-xmx+kEps); 
+    bmx = xax->FindBin(-xmn-kEps); 
+    double errn;
+    val += hist->IntegralAndError(bmn,bmx,errn);
+    err = TMath::Sqrt(err*err + errn*errn);
+  }
+}
+
+
+//____________________________________________________________________________
+const char* HName(const char* prefix,const char* htype)
+{
+  // compose the name of histo in the clist
+  static TString strh;
+  strh = "Tr"; strh += prefix; strh += "_"; strh += htype;
+  return strh.Data();
+}
+
+//____________________________________________________________________________
+Int_t CheckStat(const TList* lst, const char* dtType)
+{
+  // check if needed bg was generated
+  TH1* hstat = (TH1*)FindObject(kHStatName,lst);
+  TString dts = dtType;
+  if (dts=="Data") return int( hstat->GetBinContent(kEvProcData) );
+  if (dts=="Mix")  return int( hstat->GetBinContent(kEvProcMix) );
+  if (dts=="Inj")  return int( hstat->GetBinContent(kEvProcInj) );
+  if (dts=="Rot")  return int( hstat->GetBinContent(kEvProcRot) );
+  printf("Unknown process %s statistics is checked. Alowed: Data,Mix,Inj,Rot",dtType);
+  return 0;
+}
+
+//____________________________________________________________________________
+void ProjDZE(THnSparseF* hrawd, THnSparseF* hgenb, THnSparseF* hmcComb, TObjArray* res, int bStepEta,int bStepZv)
+{
+  // project 3d histo of Dist vs Zv vs Eta to Zv vs Eta with all cuts
+  int shift = hmcComb ? kMCShift : 0; // is this mc?
+  //
+  // determine boundaries for zv and eta cuts
+  //
+  double cutDstMin,cutDstMax;
+  double cutBgMin,cutBgMax;
+  double cutSgMin,cutSgMax;
+  if (useShapeType==kNormShapeDist) {
+    cutDstMin = 0;
+    cutDstMax = kWDistBgTailMax;
+    //
+    cutBgMin = kWDistBgTailMin;
+    cutBgMax = kWDistBgTailMax;
+    //
+    cutSgMin = 0;
+    cutSgMax = kWDistSgCut;
+  }
+  else {
+    cutDstMin = -kdPhiBgTailMax;
+    cutDstMax =  kdPhiBgTailMax;    
+    //
+    cutBgMin =  kdPhiBgTailMin;
+    cutBgMax =  kdPhiBgTailMax;
+    //
+    cutSgMin =  0;
+    cutSgMax =  kdPhiSgCut;
+  }
+  //
+  int bn0[3] = {0}; // 1st bin to count
+  int bn1[3] = {0}; // last bin to count
+  // eta 
+  TAxis* axEta = hrawd->GetAxis(0);
+  bn0[0] = axEta->FindBin(-useEtaCut+kEps);
+  bn1[0] = axEta->FindBin( useEtaCut-kEps);
+  // Zv
+  TAxis* axZv = hrawd->GetAxis(1);
+  bn0[1] = axZv->FindBin( useZvMin+kEps);
+  bn1[1] = axZv->FindBin( useZvMax-kEps);
+  // W.dist
+  TAxis* axDst = hrawd->GetAxis(2);
+  bn0[2] = axDst->FindBin( cutDstMin + kEps);
+  bn1[2] = axDst->FindBin( cutDstMax - kEps);
+  //
+  //
+  int nb[3] = { bn1[0]-bn0[0]+1, bn1[1]-bn0[1]+1, bn1[2]-bn0[2]+1};  // number of bins to count
+  int nbTot[3] = {axEta->GetNbins(), axZv->GetNbins(), axDst->GetNbins() }; // total bins
+  //
+  if (bStepEta<1 || bStepEta>nb[0]) bStepEta = nb[0];
+  if (bStepZv<1  || bStepEta>nb[1]) bStepZv  = nb[1];
+  //
+  for (int i=3;i--;) { // set default axis range
+    hrawd->GetAxis(i)->SetRange(1,nbTot[i]);
+    hgenb->GetAxis(i)->SetRange(1,nbTot[i]);
+    if (hmcComb) hmcComb->GetAxis(i)->SetRange(1,nbTot[i]);
+  }
+  //
+  char grpTit[100];
+  sprintf(grpTit,"grp_eta%d_zv%d",bStepEta,bStepZv);
+  //
+  TString pref = hmcComb ? "mc" : "dt";
+  //
+  // "Data" histo with cut on tails where we look for signal
+  hrawd->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+  TH2* hRawDtCut = hrawd->Projection(1,0,"e");
+  hrawd->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+  hRawDtCut->SetName(pref+"_RawWithCut");
+  hRawDtCut->SetTitle(pref+" Raw with cut on tracklets");
+  res->AddAtAndExpand(hRawDtCut, kRawDtCut+shift);
+  //
+  // "Data - Est.Bg" histo with cut on tails where we look for signal
+  hrawd->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+  TH2* hSignalEst = hrawd->Projection(1,0,"e");
+  hrawd->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+  hSignalEst->SetName(pref+"_SignalCut_"+grpTit);
+  hSignalEst->SetTitle(pref+" Signal (raw-bg) with cut on tracklets "+grpTit);
+  res->AddAtAndExpand(hSignalEst, kSignalEst+shift);
+  //
+  // "Data - MC.Bg" histo with cut on tails where we look for signal
+  TH2* hSignalEstMC = 0;
+  if (hmcComb) {
+    hrawd->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+    hSignalEstMC  = hrawd->Projection(1,0,"e");
+    hrawd->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+    hSignalEstMC->SetName(pref+"_SignalCut_bgMCLabels_"+grpTit);
+    hSignalEstMC->SetTitle(pref+" Signal (raw-bg_MCLabels) with cut on tracklets "+grpTit);
+    res->AddAtAndExpand(hSignalEstMC, kSignalEstMC+shift);
+  }
+  //
+  // Estimated background in the cut range
+  hgenb->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+  TH2* hBgEst = hgenb->Projection(1,0,"e");
+  hgenb->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+  hBgEst->SetName(pref+"_BgEst_"+grpTit);
+  hBgEst->SetTitle(pref+" Estimated Bg "+grpTit);
+  res->AddAtAndExpand(hBgEst, kBgEst+shift);
+  //
+  // 1-beta for "data" = (Data_cut - Bg_cut) / Data_cut
+  TH2* h1mBeta     = hrawd->Projection(1,0,"e"); 
+  h1mBeta->Reset();
+  h1mBeta->SetName(pref+"_h1mBeta_"+grpTit);
+  h1mBeta->SetTitle(pref+" 1-#beta with gen.bg. "+grpTit);
+  res->AddAtAndExpand(h1mBeta, k1MBeta+shift);
+  //
+  // If MC labels info is provided
+  TH2* h1mBetaMC = 0;  // 1-beta for MC with bg from labels
+  TH2* hBgMC = 0;      // bg from MC labels
+  if (hmcComb) {
+    hmcComb->GetAxis(2)->SetRangeUser(cutDstMin+kEps,cutDstMax-kEps);
+    h1mBetaMC = hmcComb->Projection(1,0,"e");
+    h1mBetaMC->SetName(pref+"_h1mBetaMC");
+    h1mBetaMC->SetTitle(pref+" 1-#beta with bg. from MC labels");
+    h1mBetaMC->Divide(hRawDtCut);
+    res->AddAtAndExpand(h1mBetaMC, k1MBetaMC+shift);
+    for (int ib0=1;ib0<=nbTot[0];ib0++) 
+      for (int ib1=1;ib1<=nbTot[1];ib1++) 
+       h1mBetaMC->SetBinContent(ib0,ib1, 1.- h1mBetaMC->GetBinContent(ib0,ib1)); 
+    //
+    hBgMC = hmcComb->Projection(1,0,"e");
+    hBgMC->SetName(pref+"_Bg_MClab");
+    hBgMC->SetTitle(pref+" Bg from MC labels");
+    res->AddAtAndExpand(hBgMC, kBgMC+shift);
+    //
+    // finalize estimated signal with bg from MC labels
+    hSignalEstMC->Add(hBgMC,-1);
+    //
+    hmcComb->GetAxis(2)->SetRange(bn0[2],bn1[2]);
+  }
+  // 
+  // rescaling factors for generated bg 
+  TH2* hBgRescFc  = hrawd->Projection(1,0,"e"); hBgRescFc->Reset();
+  hBgRescFc->SetName(pref+"_hBgRescFactors_"+grpTit);
+  hBgRescFc->SetTitle(pref+" Scale.factor for gen.bg. "+grpTit);
+  res->AddAtAndExpand(hBgRescFc, kBgRescFc+shift);
+  //
+  int nbint = bStepEta*bStepZv;
+  float nbinstsq = TMath::Sqrt(nbint);
+  hrawd->GetAxis(0)->SetRange(bn0[0],bn1[0]);
+  hrawd->GetAxis(1)->SetRange(bn0[1],bn1[1]);
+  TH1* hDstDt = hrawd->Projection(2,"e");
+  hrawd->GetAxis(0)->SetRange(1,nbTot[0]);
+  hrawd->GetAxis(1)->SetRange(1,nbTot[1]);
+  hDstDt->SetName(pref+"_DistRaw_"+grpTit);   // "Data" projection on tracklet quality (w.distance) axis to check the tails
+  hDstDt->SetTitle(pref+" DistRaw "+grpTit); 
+  double nrmDst,dumErr = 0;
+  Integrate(hDstDt, cutBgMin,cutBgMax, nrmDst, dumErr);
+  hDstDt->Scale(1./nrmDst);
+  res->AddAtAndExpand(hDstDt, kDataDist+shift);
+  //
+  hgenb->GetAxis(0)->SetRange(bn0[0],bn1[0]);
+  hgenb->GetAxis(1)->SetRange(bn0[1],bn1[1]);
+  TH1* hDstBg = hgenb->Projection(2,"e");  hDstBg->Reset();  
+  hgenb->GetAxis(0)->SetRange(1,nbTot[0]);
+  hgenb->GetAxis(1)->SetRange(1,nbTot[1]);
+  hDstBg->SetName(pref+"_DistBgNorm_"+grpTit);  // Gen.Bg projection on tracklet quality (w.distance) axis to check the tails
+  hDstBg->SetTitle(pref+" DistBgNorm "+grpTit);  // Gen.Bg projection on tracklet quality (w.distance) axis to check the tails
+  res->AddAtAndExpand(hDstBg, kBgDist+shift);
+  TH1* hDstBgMC = 0;
+  if (hmcComb) {
+    hmcComb->GetAxis(0)->SetRange(bn0[0],bn1[0]);
+    hmcComb->GetAxis(1)->SetRange(bn0[1],bn1[1]);
+    hDstBgMC = hmcComb->Projection(2,"e");
+    hmcComb->GetAxis(0)->SetRange(1,nbTot[0]);
+    hmcComb->GetAxis(1)->SetRange(1,nbTot[1]);
+    hDstBgMC->SetName(pref+"_DistBgMC");
+    hDstBgMC->SetTitle(pref+" Bg. Distance from MC labels");
+    hDstBgMC->Scale(1./nrmDst);
+    res->AddAtAndExpand(hDstBgMC, kBgMCDist+shift);
+  }
+  //
+  // fill 1-beta matrix
+  for (int ib0=bn0[0];ib0<=bn1[0];ib0+=bStepEta) { // eta
+    hrawd->GetAxis(0)->SetRange(ib0,ib0+bStepEta-1);
+    hgenb->GetAxis(0)->SetRange(ib0,ib0+bStepEta-1);
+    for (int ib1=bn0[1];ib1<=bn1[1];ib1+=bStepZv) { // zv
+      hrawd->GetAxis(1)->SetRange(ib1,ib1+bStepZv-1);
+      hgenb->GetAxis(1)->SetRange(ib1,ib1+bStepZv-1);
+      //
+      TH1D* dstD = hrawd->Projection(2,"e"); // data "qaulity" for given eta:zv bin
+      TH1D* dstB = hgenb->Projection(2,"e"); // data "qaulity" for given eta:zv bin
+      double scl,sclE;
+      TH1* nrmB = NormalizeBg(dstD,dstB,scl,sclE);  // get rescaling factor for bg. from tails comparison
+      double bgVal,bgErr;
+      double dtVal,dtErr;
+      // integral in the range where we look for signal
+      Integrate(nrmB, cutSgMin, cutSgMax, bgVal, bgErr);
+      Integrate(dstD, cutSgMin, cutSgMax, dtVal, dtErr);
+      double beta,betaErr;
+      GetRatE(bgVal,bgErr, dtVal, dtErr,beta,betaErr);
+      //    betaErr*=nbinstsq; // ??? RS
+      for (int i=ib0;i<ib0+bStepEta;i++) {
+       for (int j=ib1;j<ib1+bStepZv;j++) {
+         hBgRescFc->SetBinContent(i,j, scl);
+         hBgRescFc->SetBinError(i,j, sclE);
+       }
+      }
+      hDstBg->Add(nrmB);
+      delete dstD;
+      delete dstB;
+      delete nrmB;
+      //
+    }
+  }
+  hDstBg->Scale(1./nrmDst);
+  //
+  // finalize estimated bg and signal matrices
+  hBgEst->Multiply(hBgRescFc);
+  hSignalEst->Add(hBgEst,-1);
+  //
+  // finalize 1-beta
+  for (int ib0=bn0[0];ib0<=bn1[0];ib0++) { // eta
+    for (int ib1=bn0[1];ib1<=bn1[1];ib1++) { // zv
+      //      printf("Bin %d %d\n",ib0,ib1);
+      double bg  = hBgEst->GetBinContent(ib0,ib1);
+      double bgE = hBgEst->GetBinError(ib0,ib1);
+      double dt  = hRawDtCut->GetBinContent(ib0,ib1);
+      double dtE = hRawDtCut->GetBinError(ib0,ib1);
+      double beta,betaE;
+      GetRatE(bg,bgE,dt,dtE, beta,betaE );      
+      h1mBeta->SetBinContent(ib0,ib1,1.-beta);
+      h1mBeta->SetBinError(ib0,ib1,betaE);
+      //
+    }
+  }
+  //
+  // crop to needed range
+  for (int i=shift;i<kNHistos+shift;i++) {
+    TH2* hist = (TH2*)res->At(i);
+    if (!hist || !hist->InheritsFrom(TH2::Class())) continue;
+    CropHisto(hist, bn0[0],bn1[0], bn0[1],bn1[1]);
+  }
+  //
+  h1mBeta->SetMinimum(0.6);
+  h1mBeta->SetMaximum(0.85);
+  if (hmcComb) {
+    h1mBetaMC->SetMinimum(0.6);
+    h1mBetaMC->SetMaximum(0.85);
+  }
+  //
+  // restore
+  for (int i=3;i--;) { // set default axis range
+    hrawd->GetAxis(i)->SetRange(1,nbTot[i]);
+    hgenb->GetAxis(i)->SetRange(1,nbTot[i]);
+    if (hmcComb) hmcComb->GetAxis(i)->SetRange(1,nbTot[i]);
+  }
+  //
+}
+
+
+void GetRealMinMax(TH1* histo, double &vmn, double &vmx)
+{
+  TAxis *xax = histo->GetXaxis();
+  int nbx = xax->GetNbins(); 
+  vmn=1e6, vmx=-1e6;
+  if (histo->InheritsFrom(TH2::Class())) {
+    TAxis *yax = histo->GetYaxis();
+    int nby = yax->GetNbins();
+    for (int ix=nbx+2;ix--;) {
+      for (int iy=nby+2;iy--;) {
+       double vl = histo->GetBinContent(ix,iy);
+       if (vl<kEps) continue;
+       if (vl<vmn) vmn = vl;
+       if (vl>vmx) vmx = vl;
+      }
+    }
+  }
+  //
+  else {
+    for (int ix=nbx+2;ix--;) {
+      double vl = histo->GetBinContent(ix);
+      if (vl<vmn) vmn = vl;
+      if (vl>vmx) vmx = vl;
+    }
+  }
+  //
+}
diff --git a/PWG0/multVScentPbPb/CorrectSpectraMulti.C b/PWG0/multVScentPbPb/CorrectSpectraMulti.C
new file mode 100755 (executable)
index 0000000..9bd8738
--- /dev/null
@@ -0,0 +1,1290 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TList.h"
+#include "TFile.h"
+#include "TStyle.h"
+#include "TH1F.h"
+#include "TH2F.h"
+#include "THnSparse.h"
+#include "TLegend.h"
+#include "TSystem.h"
+#include "TMath.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+#include "TLatex.h"
+#include "TF1.h"
+#include "TLine.h"
+#include "TPaletteAxis.h"
+#include "TArrayD.h"
+#include "TGraphErrors.h"
+//
+//
+#endif
+#include "/home/shahoian/ALICE/mymacros/SaveCanvas.h"
+
+
+
+const char kHStatName[]="hStat";
+double kEps = 1e-6;
+//
+double kdPhiBgTailMin = 0.1; // lower limit of dphi tail to use for bg normalization  
+double kdPhiBgTailMax = 0.3; // upper limit of dphi tail to use for bg normalization   
+//
+double kWDistBgTailMin = 5.; // lower limit of wgh.distance tail to use for bg normalization  
+double kWDistBgTailMax = 25.; // upper limit of wgh.distance tail to use for bg normalization
+
+double kdPhiSgCut=-1;       // cut in dphi-bent used to extract the signal, extracted from stat histo
+double kWDistSgCut=-1;      // cut in w.distance used to extract the signal, extracted from stat histo
+//
+enum { kNormShapeDist,      // normalize bg tails usig weighted distance shape 
+       kNormShapeDPhi,      // normalize bg tails usig dPhi-bend shape
+       kNormShapes};
+
+enum { kSclWghMean,         // normalize bg tails to data using weighted mean of bin-by-bin ratios 
+       kSclIntegral,        // normalize bg tails to data using integral
+       kSclTypes};
+
+
+const char* figDir = "figMult";
+TString  useBgType    = "Inj";
+Int_t    useShapeType = kNormShapeDist;    // which distribution to use for bg normalization
+Bool_t   useMCLB      = kFALSE;             // use Comb MC Labels as a template for Bg.
+Int_t    useScaleType = kSclIntegral;//kSclWghMean;       // which type of tails normalization to use
+const double kEtaFitRange = 0.5;
+
+enum {kBitNormPerEvent=BIT(14)};
+  // bins for saved parameters in the hStat histo
+enum {kDummyBin,
+      kEvTot,       // events read
+      kOneUnit,     // just 1 to track primate merges
+      kNWorkers,    // n workers
+      //
+      kDPhi,        // dphi window
+      kDTht,        // dtheta window
+      kNStd,        // N.standard deviations to keep
+      kPhiShift,    // bending shift
+      kThtS2,       // is dtheta scaled by 1/sin^2
+      kThtCW,       // on top of w.dist cut cut also on 1 sigma dThetaX
+      kPhiOvl,      // overlap params
+      kZEtaOvl,     // overlap params
+      kNoOvl,       // flag that overlap are suppressed
+      //
+      kPhiRot,      // rotation phi
+      kInjScl,      // injection scaling
+      kEtaCut,      // eta cut
+      kZVMin,       // min ZVertex to process
+      kZVMax,       // max ZVertex to process
+      //
+      kDPiSCut,     // cut on dphi used to extract signal (when WDist is used in analysis, put it equal to kDPhi
+      kNStdCut,     // cut on weighted distance (~1) used to extract signal 
+      //
+      kMCV0Scale,   // scaling value for V0 in MC
+      //
+      // here we put entries for each mult.bin
+      kBinEntries = 50,
+      kEvProcData,  // events with data mult.object (ESD or reco)
+      kEvProcInj,   // events Injected, total
+      kEvProcRot,   // events Rotated
+      kEvProcMix,   // events Mixed
+      kEntriesPerBin
+};
+
+
+enum {kSigCorr,kMCPrim,kRawDtCut,kSignalEst,kSignalEstMC,kBgEst,k1MBeta,k1MBetaMC,kAlpha,kAlphaMC,kBgMC,kBgRescFc,kDataDist,kBgDist,kBgMCDist, kMCShift=20, kNHistos=kMCShift+kMCShift};
+
+void    CorrectSpectraMulti(const char* flNameData, const char* flNameMC,const char* unique="");
+Bool_t  PrepareHistos(int bin, TList* lst, Bool_t isMC);
+void    ProcessHistos(int bin);
+TH1*    NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &scle);
+TObject* FindObject(int bin, const char* nameH, const TList* lst, Bool_t normPerEvent=kTRUE);
+TList*  LoadList(const char* flName, const char* addPref, const char* nameL="clist");
+void    GetRatE(double x,double xe, double y,double ye, double &rat, double &rate);
+Int_t   CheckStat(const TList* lst,const char* dtType);
+void    Integrate(TH1* hist, double xmn,double xmx, double &val, double& err);
+void    CropHisto(TH1* histo, int b00, int b01, int b10=-1, int b11=-1);
+void    CropHisto(TH1* histo, double b00, double b01, double b10=-1, double b11=-1);
+void    GetRealMinMax(TH1* h, double &vmn, double &vmx);
+const char*   HName(const char* prefix,const char* htype);
+
+void PlotResults();
+void PlotDNDEta(int bin);
+void PlotAlphaBeta(int bin);
+void PlotSpecies();
+
+Float_t myMergeFactor = -1; // if the files were manually merged, scale everything except statistics by 1/myMergeFactor
+Int_t nCentBins = -1;
+TList *listDt=0, *listMC=0;
+TObjArray resArr;
+char outStr[1000];
+char outTitle[1000];
+TString uniqueName="";
+//
+TArrayD dNdEta,dNdEtaErr;
+TCanvas *canvFin=0;
+//
+Bool_t creatDnDEtaCMacro = kFALSE;
+Bool_t creatAlphaBetaCMacro = kFALSE;
+Bool_t creatSpeciesCMacro = kFALSE;
+
+void CorrectSpectraMulti(const char* flNameData, const char* flNameMC, const char* uniqueNm)
+{
+  //
+  uniqueName = uniqueNm;
+  listDt = LoadList(flNameData,"dt_");
+  listMC = LoadList(flNameMC,"mc_");
+  //
+  resArr.Clear();
+  //
+  TH1* hstat = (TH1*)FindObject(-1,kHStatName,listDt,kFALSE);
+  //
+  int nbstat = hstat->GetNbinsX();
+  nCentBins = (nbstat - kBinEntries)/kEntriesPerBin;
+  printf("%d bins will be processed\n",nCentBins);
+  if (nCentBins<1) return;
+  myMergeFactor = hstat->GetBinContent(kOneUnit);
+  printf("Detected %f mergings\n",myMergeFactor);
+  //
+  dNdEta.Set(nCentBins);
+  dNdEtaErr.Set(nCentBins);
+  //
+  kdPhiSgCut  = hstat->GetBinContent(kDPiSCut)/myMergeFactor;
+  kWDistSgCut = hstat->GetBinContent(kNStdCut)/myMergeFactor;
+  printf("Signal cuts used: dPhiS: %f WDist:%f\n",kdPhiSgCut,kWDistSgCut);
+  //
+  for (int ib=0;ib<nCentBins;ib++) {
+    if (!PrepareHistos(ib,listMC,kTRUE))  return;
+    if (!PrepareHistos(ib,listDt,kFALSE)) return;
+    ProcessHistos(ib); 
+    //
+  }
+  //
+  sprintf(outStr,"CutEta%.1f_Zv%.1f_%.1f_bg%s_Shape_%s_mcLB%d_cutSig%.1f_cutBg%.1f",
+         hstat->GetBinContent(kEtaCut)/myMergeFactor,
+         hstat->GetBinContent(kZVMin)/myMergeFactor,
+         hstat->GetBinContent(kZVMax)/myMergeFactor,    
+         useBgType.Data(),
+         useShapeType==kNormShapeDist ? "wdst":"dphi", 
+         useMCLB,
+         useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+         useShapeType==kNormShapeDist ? kWDistBgTailMin:kdPhiBgTailMin);
+  //
+  PlotResults();
+  //
+  printf("Final Results:\n");
+  printf("dNdEta:    "); 
+  for (int i=nCentBins;i--;) printf("%.2f,",dNdEta[i]); printf("\n");
+  printf("dNdEtaErr: "); 
+  for (int i=nCentBins;i--;) printf("%.2f,",dNdEtaErr[i]); printf("\n");
+
+}
+
+//_____________________________________________________________________
+Bool_t PrepareHistos(int bin, TList* lst, Bool_t isMC)
+{
+  // fill standard histos for given bin
+  //
+  char buffn[500];
+  char bufft[500];
+  //
+  double cutBgMin,cutBgMax;
+  double cutSgMin,cutSgMax;
+  //
+  if (useShapeType==kNormShapeDist) {
+    cutBgMin = kWDistBgTailMin;
+    cutBgMax = kWDistBgTailMax;
+    //
+    cutSgMin = 0;
+    cutSgMax = kWDistSgCut;
+  }
+  else {
+    cutBgMin =  kdPhiBgTailMin;
+    cutBgMax =  kdPhiBgTailMax;
+    //
+    cutSgMin =  0;
+    cutSgMax =  kdPhiSgCut;
+  }
+  //
+  const char* zeCut = "ZvEtaCutT";
+  TObjArray* res = &resArr;
+  int shift = bin*kNHistos + (isMC ? kMCShift : 0);
+  //
+  // histo for "data" Z vs Eta with default signal cut
+  TH2* hRawDtCut = (TH2*) FindObject(bin,HName("Data",zeCut),lst);
+  if (!hRawDtCut) return kFALSE;
+  sprintf(buffn,"bin%d_%s_RawWithCut",bin,isMC ? "mc":"dt");
+  sprintf(bufft,"bin%d %s Raw Data with cut on tracklets",bin,isMC ? "mc":"dt");
+  hRawDtCut = (TH2*)hRawDtCut->Clone(buffn);
+  hRawDtCut->SetTitle(bufft);
+  res->AddAtAndExpand(hRawDtCut, kRawDtCut+shift);
+  //
+  int nbEta = hRawDtCut->GetXaxis()->GetNbins();
+  int nbZV  = hRawDtCut->GetYaxis()->GetNbins();
+  //
+  // "Data - Est.Bg" histo with cut on tails where we look for signal
+  sprintf(buffn,"bin%d_%s_SignalWithCut",bin,isMC ? "mc":"dt");
+  sprintf(bufft,"bin%d %s Signal (raw-bg) with cut on tracklets",bin,isMC ? "mc":"dt");
+  TH2* hSignalEst = (TH2F*)hRawDtCut->Clone(buffn);
+  hSignalEst->SetTitle(bufft);
+  res->AddAtAndExpand(hSignalEst, kSignalEst+shift);
+  //
+  // "Data - MC.Bg" histo with cut on tails where we look for signal
+  TH2* hSignalEstMC = 0;
+  if (isMC) {
+    sprintf(buffn,"bin%d_%s_SignalWithCut_bgMCLabels",bin,isMC ? "mc":"dt");
+    sprintf(bufft,"bin%d %s Signal (raw-bg_MCLabels) with cut on tracklets",bin,isMC ? "mc":"dt");
+    hSignalEstMC = (TH2F*)hRawDtCut->Clone(buffn);
+    hSignalEstMC->SetTitle(bufft);
+    res->AddAtAndExpand(hSignalEstMC, kSignalEstMC+shift);
+  }
+  //
+  // Estimated background in the cut range
+  sprintf(buffn,"bin%d_%s_BgEst",bin,isMC ? "mc":"dt");
+  sprintf(bufft,"bin%d %s Estimated Bg",bin,isMC ? "mc":"dt");
+  TH2* hBgEst = (TH2*) FindObject(bin,HName(useBgType.Data(),zeCut),lst);
+  if (!hBgEst) return kFALSE;
+  hBgEst = (TH2*)hBgEst->Clone(buffn);
+  hBgEst->SetTitle(bufft);
+  res->AddAtAndExpand(hBgEst,kBgEst +shift);
+  //
+  // special feature: use MC Labels bg as a shape instead of generated bg
+  /*
+  if (useMCLB) {
+    TString nm  = hBgEst->GetName();   nm  += "_MCLB";
+    TString tit = hBgEst->GetTitle();  tit += "_MCLB";
+    TH2* hBMCLB = (TH2*) FindObject(bin,HName("Comb",zeCut),listMC);
+    if (!hBMCLB) return kFALSE;
+    hBMCLB = (TH2F*)hBMCLB->Clone(nm.Data());
+    hBMCLB->SetTitle(tit.Data());
+    delete hBgEst;
+    hBgEst = hBMCLB;
+    res->AddAtAndExpand(hBgEst,kBgEst +shift);
+  }
+  */
+  //
+  // 1-beta for "data" = (Data_cut - Bg_cut) / Data_cut
+  sprintf(buffn,"bin%d_%s_1mBeta",bin,isMC ? "mc":"dt");
+  sprintf(bufft,"bin%d %s 1-#beta with estimated bg",bin,isMC ? "mc":"dt");
+  TH2* h1mBeta = (TH2*)hBgEst->Clone(buffn);
+  h1mBeta->SetTitle(bufft);
+  h1mBeta->Reset();
+  res->AddAtAndExpand(h1mBeta, k1MBeta+shift);
+  //
+  // If MC labels info is provided, prepare 1-beta with MC bg
+  TH2* h1mBetaMC = 0;  // 1-beta for MC with bg from labels
+  TH2* hBgMC = 0;      // bg from MC labels
+  if (isMC) {
+    sprintf(buffn,"bin%d_%s_BgMC",bin,isMC ? "mc":"dt");
+    sprintf(bufft,"bin%d %s Bg from MC labels",bin,isMC ? "mc":"dt");
+    hBgMC = (TH2*) FindObject(bin,HName("Comb",zeCut),listMC);
+    if (!hBgMC) return kFALSE;
+    hBgMC = (TH2F*)hBgMC->Clone(buffn);
+    hBgMC->SetTitle(bufft);
+    res->AddAtAndExpand(hBgMC, kBgMC+shift);
+    //
+    sprintf(buffn,"bin%d_%s_h1mBetaMC",bin,isMC ? "mc":"dt");
+    sprintf(bufft,"bin%d %s 1-#beta with bg. from MC labels",bin,isMC ? "mc":"dt");
+    h1mBetaMC = (TH2F*) hBgMC->Clone(buffn);
+    h1mBetaMC->SetTitle(bufft);
+    res->AddAtAndExpand(h1mBetaMC, k1MBetaMC+shift);
+    h1mBetaMC->Divide(hRawDtCut);
+    for (int ib0=1;ib0<=nbEta;ib0++) 
+      for (int ib1=1;ib1<=nbZV;ib1++) 
+       h1mBetaMC->SetBinContent(ib0,ib1, 1.- h1mBetaMC->GetBinContent(ib0,ib1));
+    //
+    hSignalEstMC->Add(hBgMC,-1);
+  }
+  //
+  // uncut w.distance or dphi distribution for data
+  TH1* hDstDt = (TH1*) FindObject(bin,HName("Data",useShapeType==kNormShapeDist ? "WDist":"DPhiS"),lst);
+  if (!hDstDt) return kFALSE;
+  sprintf(buffn,"bin%d_%s_DistRawData",bin,isMC ? "mc":"dt");
+  sprintf(bufft,"bin%d %s Raw Distance for Data",bin,isMC ? "mc":"dt");
+  hDstDt = (TH1*) hDstDt->Clone(buffn);
+  hDstDt->SetTitle(bufft);
+  double nrmDst,dumErr = 0;
+  Integrate(hDstDt, cutBgMin,cutBgMax, nrmDst, dumErr);
+  hDstDt->Scale(1./nrmDst);
+  res->AddAtAndExpand(hDstDt, kDataDist+shift);
+  //
+  // uncut w.distance or dphi distribution for generated bg
+  TH1* hDstBg = (TH1*) FindObject(bin,HName(useBgType.Data(),useShapeType==kNormShapeDist ? "WDist":"DPhiS"),lst);
+  if (!hDstBg) return kFALSE;
+  sprintf(buffn,"bin%d_%s_DistRawGenBgNorm",bin,isMC ? "mc":"dt");
+  sprintf(bufft,"bin%d %s Raw Distance for Gen.Bg. Normalized to data",bin,isMC ? "mc":"dt");
+  hDstBg = (TH1*) hDstBg->Clone(buffn);
+  hDstBg->SetTitle(bufft);
+  hDstBg->Scale(1./nrmDst);
+  //  res->AddAtAndExpand(hDstBg, kBgDist+shift);
+  //
+  if (useMCLB) { // use MC dist. shape as a template
+    TH1* mcshp = (TH1*) FindObject(bin,HName("Comb",useShapeType==kNormShapeDist ? "WDist":"DPhiS"),listMC);
+    double nrm1 = hDstBg->Integral();
+    double nrmMC = mcshp->Integral();
+    sprintf(buffn,"bin%d_%s_DistRawGenBgNormMCLB",bin,isMC ? "mc":"dt");
+    sprintf(bufft,"bin%d %s Raw Distance for Gen.Bg. Normalized to data MCLB",bin,isMC ? "mc":"dt");
+    if (hDstBg) delete hDstBg;
+    hDstBg = (TH1*) mcshp->Clone(buffn);
+    hDstBg->SetTitle(bufft);
+    hDstBg->Scale(nrm1/nrmMC);
+  }
+  //
+  // uncut w.distance or dphi distribution for comb. MC labels
+  TH1* hDstBgMC = 0; 
+  if (isMC) {
+    hDstBgMC = (TH1*) FindObject(bin,HName("Comb",useShapeType==kNormShapeDist ? "WDist":"DPhiS"),lst);
+    if (!hDstBgMC) return kFALSE;
+    sprintf(buffn,"bin%d_%s_DistBgMC",bin,isMC ? "mc":"dt");
+    sprintf(bufft,"bin%d %s Bg. Distance from MC labels",bin,isMC ? "mc":"dt");
+    hDstBgMC = (TH1*) hDstBgMC->Clone(buffn);
+    hDstBgMC->SetTitle(bufft);
+    hDstBgMC->Scale(1./nrmDst);
+    res->AddAtAndExpand(hDstBgMC, kBgMCDist+shift);
+  }
+  //
+  // fill 1-beta matrix
+  double scl,sclE;
+  hDstBg = NormalizeBg(hDstDt,hDstBg,scl,sclE);  // get rescaling factor for bg. from tails comparison
+  res->AddAtAndExpand(hDstBg, kBgDist+shift);
+  double bgVal,bgErr;
+  double dtVal,dtErr;
+  // integral in the range where we look for signal
+  Integrate(hDstBg, cutSgMin, cutSgMax, bgVal, bgErr);
+  Integrate(hDstDt, cutSgMin, cutSgMax, dtVal, dtErr);
+  double sclb,sclbErr;
+  GetRatE(bgVal,bgErr, dtVal, dtErr,sclb,sclbErr);
+  //  hDstBg->Scale(1./nrmDst);
+  //
+  // finalize estimated bg and signal matrices
+  hBgEst->Scale(scl);
+  //
+  hSignalEst->Add(hBgEst,-1);
+  //
+  // finalize 1-beta
+  for (int ib0=1;ib0<=nbEta;ib0++) { // eta
+    for (int ib1=1;ib1<=nbZV;ib1++) { // zv
+      //      printf("Bin %d %d\n",ib0,ib1);
+      double bg  = hBgEst->GetBinContent(ib0,ib1);
+      double bgE = hBgEst->GetBinError(ib0,ib1);
+      double dt  = hRawDtCut->GetBinContent(ib0,ib1);
+      double dtE = hRawDtCut->GetBinError(ib0,ib1);
+      double beta,betaE;
+      GetRatE(bg,bgE,dt,dtE, beta,betaE );      
+      h1mBeta->SetBinContent(ib0,ib1,1.-beta);
+      h1mBeta->SetBinError(ib0,ib1,betaE);
+      //
+    }
+  }  
+  //
+  if (isMC) {
+    // prepare MC primary signal histo
+    sprintf(buffn,"bin%d_zvEtaPrimMC",bin);
+    sprintf(bufft,"bin%d MC True signal Zv vs Eta",bin);
+    TH2F* mcPrim = (TH2F*)FindObject(bin,"zvEtaPrimMC", lst );
+    mcPrim = (TH2F*) mcPrim->Clone(buffn);
+    mcPrim->SetTitle(bufft);
+    res->AddAtAndExpand(mcPrim, kMCPrim + shift);
+  }
+  //
+  return kTRUE;
+}
+
+//_____________________________________________________________________
+void ProcessHistos(int bin)
+{
+  //
+  int shift = bin*kNHistos;
+  //
+  TString prefN = "bin"; prefN += bin; prefN+="_";
+  TString prefT = "bin"; prefT += bin; prefT+=" ";
+  TObjArray* res = &resArr;
+  // build alpha matrix
+  TH2* halp = (TH2*)res->At(shift + kMCShift + kMCPrim);
+  halp = (TH2*) halp->Clone(prefN+"Alpha");
+  halp->SetTitle(prefN+"#alpha");
+  halp->Divide( (TH2*)res->At(shift + kMCShift + k1MBeta) );
+  halp->Divide( (TH2*)res->At(shift + kMCShift + kRawDtCut) );
+  res->AddAtAndExpand(halp, shift + kAlpha);
+  //
+  // build alpha matrix with MC labels bg
+  TH2* halpMC = (TH2*)res->At(shift + kMCShift + kMCPrim);
+  halpMC = (TH2*) halpMC->Clone(prefN + "AlphaMC");
+  halpMC->SetTitle(prefT + "#alpha MC labels");
+  halpMC->Divide( (TH2*)res->At(shift + kMCShift + k1MBetaMC) );
+  halpMC->Divide( (TH2*)res->At(shift + kMCShift + kRawDtCut) );
+  res->AddAtAndExpand(halpMC, shift + kAlphaMC);
+  //
+  // build corrected signal
+  TH2* hsigCorr = (TH2*)res->At(shift + kSignalEst);
+  hsigCorr = (TH2*) hsigCorr->Clone(prefN + "SignalEstCorr");
+  hsigCorr->SetTitle(prefT + "Corrected Signal");
+  hsigCorr->Multiply( halp );
+  res->AddAtAndExpand(hsigCorr, shift + kSigCorr);
+  //
+  TH1* hsigCorrX = hsigCorr->ProjectionX("DataCorrSignalX");
+  hsigCorrX->Scale(1./hsigCorr->GetBinWidth(1));
+  TF1* pl0 = new TF1("pl0","pol0");
+  pl0->SetParameter(0,hsigCorr->GetMinimum());
+  hsigCorrX->Fit(pl0,"q0","",-kEtaFitRange,kEtaFitRange);
+  double fval = pl0->GetParameter(0);
+  double ferr = pl0->GetParError(0);
+  delete hsigCorrX;
+  dNdEta[bin]    = fval;
+  dNdEtaErr[bin] = ferr;
+  printf("Bin %d: dN/d#eta_{|#eta|<0.5} = %.2f  %.2f\n",bin, fval,ferr);
+  //
+}
+
+void PlotResults() 
+{
+  TString psnm1 = figDir; psnm1 += "/"; psnm1 += uniqueName; 
+  psnm1 += "_"; psnm1 += nCentBins; psnm1+= "bins_";
+  psnm1 += outStr; psnm1 += ".ps";
+  TString psnm0 = psnm1.Data(); 
+  psnm0 += "[";
+  TString psnm2 = psnm1.Data(); 
+  psnm2 += "]";
+  //
+  TH1* hstat = (TH1*)FindObject(-1,kHStatName,listDt,kFALSE);
+  //
+  TH1* hbins = (TH1*)FindObject(-1,"EvCentr",listDt,kFALSE);
+  //
+  if (!canvFin) canvFin = new TCanvas("canvFin", "canvFin",0,50,700,1000);
+  canvFin->Clear();
+  //
+  canvFin->Print(psnm0.Data());
+  //
+  canvFin->Divide(1,2);
+  canvFin->cd(1);
+  gPad->SetLeftMargin(0.15);
+  TGraphErrors* grp = new TGraphErrors(nCentBins);
+  for (int i=0;i<nCentBins;i++) {
+    grp->SetPoint(i,hbins->GetBinCenter(i+1),dNdEta[i]);
+    grp->SetPointError(i,hbins->GetBinWidth(i+1)/2,dNdEtaErr[i]);
+  }
+  grp->SetMarkerStyle(20);
+  grp->SetMarkerColor(kRed);
+  grp->SetLineColor(kRed);
+  grp->SetMinimum(1e-6);
+  grp->Draw("ap");
+  grp->GetXaxis()->SetTitle("Centrality Variable");
+  grp->GetYaxis()->SetTitle("dN/d#eta_{|#eta|<0.5}");
+  grp->GetYaxis()->SetTitleOffset(1.8);
+  gPad->SetGrid(1,1);
+  //
+  canvFin->cd(2);
+  gPad->SetLeftMargin(0.15);
+  hbins->Draw();
+  hbins->SetMinimum(1e-6);
+  hbins->SetMarkerStyle(20);
+  hbins->SetMarkerColor(kRed);
+  hbins->SetLineColor(kRed);
+  hbins->GetYaxis()->SetTitle("accepted events");
+  hbins->GetYaxis()->SetTitleOffset(1.8);
+  gPad->SetGrid(1,1);
+  //
+  canvFin->cd(0);
+  canvFin->Print(psnm1.Data());
+  //
+  const TArrayD &binArr = *hbins->GetXaxis()->GetXbins();
+  //
+  for (int i=0;i<nCentBins;i++) {
+    //
+    sprintf(outTitle,"%s, %d<c<%d, |#eta|<%.1f, %.1f<Z_{V}<%.1f,  Bg.:%s, UseMCLB=%d, CutVar:%s, |sig|<%.2f, %.2f<|bg.nrm|<%.2f",
+           uniqueName.Data(),
+           (int)binArr[i],(int)binArr[i+1],
+           hstat->GetBinContent(kEtaCut)/myMergeFactor,
+           hstat->GetBinContent(kZVMin)/myMergeFactor,
+           hstat->GetBinContent(kZVMax)/myMergeFactor,   
+           useBgType.Data(),
+           useMCLB,
+           useShapeType==kNormShapeDist ? "#Delta":"#Delta#varphi-#delta_{#varphi}",
+           useShapeType==kNormShapeDist ? kWDistSgCut:kdPhiSgCut,
+           useShapeType==kNormShapeDist ? kWDistBgTailMin : kdPhiBgTailMin,
+           useShapeType==kNormShapeDist ? kWDistBgTailMax : kdPhiBgTailMax       
+           );
+    //
+    PlotDNDEta(i);
+    canvFin->Print(psnm1.Data());
+    PlotAlphaBeta(i);
+    canvFin->Print(psnm1.Data());
+  }
+  PlotSpecies();
+  canvFin->Print(psnm1.Data());
+  //
+  canvFin->Print(psnm2.Data());    
+}
+
+void PlotDNDEta(int bin)
+{
+  //
+  TObjArray *res = &resArr;
+  TString prefN = "bin"; prefN += bin; prefN+="_";
+  int shift = bin*kNHistos;
+  //
+  char buff[1000];
+  // eta range
+  gStyle->SetOptFit(0);
+  gStyle->SetOptStat(0);
+  gStyle->SetOptTitle(0);
+  double mn = 1e6,mx = -1e6;
+  if (!canvFin) canvFin = new TCanvas("canvFin", "canvFin",0,50,700,1000);
+  canvFin->Clear();
+  canvFin->Divide(1,2);
+  canvFin->cd(1);
+  gPad->SetLeftMargin(0.15);
+  //
+  // corrected data
+  TH1* hsigCorr = ((TH2F*)res->At(shift + kSigCorr))->ProjectionX(prefN+"DataCorrSignal");
+  SetHStyle(hsigCorr,kRed,20,1.0);
+  hsigCorr->Scale(1./hsigCorr->GetBinWidth(1));
+  hsigCorr->Draw();
+  mx = TMath::Max(mx, hsigCorr->GetMaximum());
+  mn = TMath::Min(mn, hsigCorr->GetMinimum());
+  char ftres[1000];
+  sprintf(ftres,"dN/d#eta_{|#eta|<%.1f} = %.1f #pm %.1f",kEtaFitRange,dNdEta[bin],dNdEtaErr[bin]);
+  TLatex *txfit = new TLatex(-0.2,hsigCorr->GetMinimum()*0.9, ftres);
+  txfit->SetTextSize(0.04);
+  txfit->Draw();
+  //
+  // raw data
+  TH1* hraw = ((TH2F*)res->At(shift+kRawDtCut))->ProjectionX(prefN+"DataRaw");
+  SetHStyle(hraw,kRed,21,1.0);
+  hraw->Scale(1./hraw->GetBinWidth(1));
+  hraw->Draw("same");
+  mn = TMath::Min(mn, hraw->GetMinimum());
+  mx = TMath::Max(mx, hraw->GetMaximum());
+  //  
+  // raw data bg sub
+  TH1* hraws = ((TH2F*)res->At(shift+kSignalEst))->ProjectionX(prefN+"DataRawSub");
+  SetHStyle(hraws,kRed,23,1.0);
+  hraws->Scale(1./hraw->GetBinWidth(1));
+  hraws->Draw("same");
+  mn = TMath::Min(mn, hraw->GetMinimum());
+  mx = TMath::Max(mx, hraw->GetMaximum());
+  //
+  // bg
+  TH1* hbg = ((TH2F*)res->At(shift+kBgEst))->ProjectionX(prefN+"BgEst");
+  SetHStyle(hbg,kMagenta,22,1.0);
+  hbg->Scale(1./hbg->GetBinWidth(1));
+  hbg->Draw("same");
+  mn = TMath::Min(mn, hbg->GetMinimum());
+  mx = TMath::Max(mx, hbg->GetMaximum());
+  //
+  // mc part ----------------------------
+  // raw data
+  TH1* hrawMC = ((TH2F*)res->At(shift+kRawDtCut+kMCShift))->ProjectionX(prefN+"DataRawMC");
+  SetHStyle(hrawMC,kBlue,24,1.0);
+  hrawMC->Scale(1./hrawMC->GetBinWidth(1));
+  hrawMC->Draw("same");
+  mn = TMath::Min(mn, hrawMC->GetMinimum());
+  mx = TMath::Max(mx, hrawMC->GetMaximum());
+  //  
+  // raw data bg sub
+  TH1* hrawsMC = ((TH2F*)res->At(shift+kSignalEst+kMCShift))->ProjectionX(prefN+"DataRawSubMC");
+  SetHStyle(hrawsMC,kBlue,26,1.0);
+  hrawsMC->Scale(1./hrawMC->GetBinWidth(1));
+  hrawsMC->Draw("same");
+  mn = TMath::Min(mn, hrawMC->GetMinimum());
+  mx = TMath::Max(mx, hrawMC->GetMaximum());
+  //
+  // raw data bgMClabels sub
+  TH1* hrawsMCLB = ((TH2F*)res->At(shift+kSignalEstMC+kMCShift))->ProjectionX(prefN+"DataRawSubMCLB");
+  SetHStyle(hrawsMCLB,kGreen+2,30,1.0);
+  hrawsMCLB->Scale(1./hrawsMCLB->GetBinWidth(1));
+  hrawsMCLB->Draw("same");
+  mn = TMath::Min(mn, hrawsMCLB->GetMinimum());
+  mx = TMath::Max(mx, hrawsMCLB->GetMaximum());
+  //
+  // bg est
+  TH1* hbgMCEst = ((TH2F*)res->At(shift+kBgEst+kMCShift))->ProjectionX(prefN+"BgEstMC");
+  SetHStyle(hbgMCEst,kBlue,26,1.0);
+  hbgMCEst->Scale(1./hbgMCEst->GetBinWidth(1));
+  hbgMCEst->Draw("same");
+  mn = TMath::Min(mn, hbgMCEst->GetMinimum());
+  mx = TMath::Max(mx, hbgMCEst->GetMaximum());
+  //  
+  // bg MC
+  TH1* hbgMC = ((TH2F*)res->At(shift+kBgMC+kMCShift))->ProjectionX(prefN+"BgMC");
+  SetHStyle(hbgMC,kGreen+2,25,1.0);
+  hbgMC->Scale(1./hbgMC->GetBinWidth(1));
+  hbgMC->Draw("same");
+  mn = TMath::Min(mn, hbgMC->GetMinimum());
+  mx = TMath::Max(mx, hbgMC->GetMaximum());
+  //
+  mn = 0;
+  hsigCorr->SetMinimum(mn);
+  hsigCorr->SetMaximum(mx + 0.4*(mx-mn));
+  gPad->Modified();
+  //
+  TLegend *legDnDeta = new TLegend(0.15,0.75, 0.45,0.95);
+  legDnDeta->SetFillColor(kWhite);
+  legDnDeta->SetHeader("Data");
+  legDnDeta->AddEntry(hsigCorr,"Corrected","pl");
+  legDnDeta->AddEntry(hraw,    "Reconstructed","pl");
+  sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+  legDnDeta->AddEntry(hraws,   buff,"pl");
+  sprintf(buff,"Background %s.",useBgType.Data());
+  legDnDeta->AddEntry(hbg,     buff,"pl");
+  legDnDeta->Draw();
+  //
+  TLegend *legDnDetaMC = new TLegend(0.60,0.72, 0.95,0.95);
+  legDnDetaMC->SetFillColor(kWhite);
+  legDnDetaMC->SetHeader("MC");
+  legDnDetaMC->AddEntry(hrawMC,    "Reconstructed","pl");
+  sprintf(buff,"Reconstructed - Bckg.%s.",useBgType.Data());
+  legDnDetaMC->AddEntry(hrawsMC,   buff,"pl");
+  sprintf(buff,"Reconstructed - Bckg.%s.","MC.Labels");
+  legDnDetaMC->AddEntry(hrawsMCLB,   buff,"pl");
+  sprintf(buff,"Background %s.",useBgType.Data());
+  legDnDetaMC->AddEntry(hbgMCEst,     buff,"pl");
+  sprintf(buff,"Background %s.","MC Labels");
+  legDnDetaMC->AddEntry(hbgMC,     buff,"pl");
+  //
+  legDnDetaMC->Draw();
+  //
+  gPad->SetGrid(1.1);
+  gPad->Modified();
+  AddLabel(outTitle,0.1,0.97, kBlack,0.025);
+  //
+  canvFin->cd();
+  //
+  //---------------- dsitributions
+  canvFin->cd(2);
+  //
+  TH1* mcdst = (TH1*)res->At(shift+kDataDist+kMCShift);
+  TH1* mcdstbg = (TH1*)res->At(shift+kBgDist+kMCShift);
+  TH1* mcdstbgLB = (TH1*)res->At(shift+kBgMCDist+kMCShift);
+  TH1* dtdst = (TH1*)res->At(shift+kDataDist);
+  TH1* dtdstbg = (TH1*)res->At(shift+kBgDist);
+  //
+  TH1* mcDstN     = (TH1*)FindObject(bin,HName("Data", useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+  TH1* mcDstSec   = (TH1*)FindObject(bin,HName("Sec",  useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+  TH1* mcDstCombU = (TH1*)FindObject(bin,HName("CombU",useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+  TH1* mcDstCombC = (TH1*)FindObject(bin,HName("Comb", useShapeType==kNormShapeDist ? "WDist":"DPhiS"), listMC );
+  //  
+  double scl,sclE;
+  mcDstN = NormalizeBg(mcdst,mcDstN,scl,sclE);
+  mcDstSec->Scale(scl);
+  mcDstCombU->Scale(scl);
+  mcDstCombC->Scale(scl);
+  mcDstCombC->Add(mcDstCombU,-1);
+
+  dtdst->Draw("");
+  gPad->Modified();
+  dtdst->GetXaxis()->SetLabelSize(0.03);
+  dtdst->GetXaxis()->SetTitleSize(0.03);
+  dtdst->GetXaxis()->SetTitleOffset(2);
+  dtdstbg->Draw("same");
+  //
+  mcdst->Draw("same");
+  mcDstSec->Draw("same");
+  mcdstbgLB->Draw("same");
+  mcdstbg->Draw("same");
+  mcDstCombC->Draw("same");
+  //
+
+  SetHStyle(mcdst,kBlue, 25,0.7);
+  SetHStyle(mcdstbgLB,kGreen, 7/*32*/,0.5);
+  SetHStyle(mcdstbg,kCyan, 7/*26*/,0.5);
+  SetHStyle(mcDstCombC,kGreen+2, 21,0.7);
+  SetHStyle(mcDstSec,kBlue+2, 22,0.7);
+  //
+  SetHStyle(dtdst,kRed, 20,0.7);
+  SetHStyle(dtdstbg,kBlue, 34,0.7);
+  //
+  double vmcTot,vmcTotE;
+  double vmcSec,vmcSecE, ratSec,ratSecE;  
+  double vmcCmbEst,vmcCmbEstE, ratCmbEst,ratCmbEstE;
+  double vmcCmb,vmcCmbE, ratCmb,ratCmbE;
+  double vmcCmbC,vmcCmbCE, ratCmbC,ratCmbCE;  
+  double cutSgMin,cutSgMax;
+  double cutBgMin,cutBgMax;
+  if (useShapeType==kNormShapeDist) {
+    cutSgMin = 0;
+    cutSgMax = kWDistSgCut;
+    cutBgMin = kWDistBgTailMin;
+    cutBgMax = kWDistBgTailMax;
+  }
+  else {
+    cutSgMin =  0;
+    cutSgMax =  kdPhiSgCut;
+    cutBgMin =  kdPhiBgTailMin;
+    cutBgMax =  kdPhiBgTailMax;
+  }  
+  Integrate(mcdst,    cutSgMin,cutSgMax, vmcTot,vmcTotE);     
+  Integrate(mcDstSec, cutSgMin,cutSgMax, vmcSec,vmcSecE);
+  GetRatE(vmcSec,vmcSecE, vmcTot,vmcTotE, ratSec,ratSecE);
+  //
+  Integrate(mcdstbgLB, cutSgMin,cutSgMax, vmcCmb,vmcCmbE);  
+  GetRatE(vmcCmb,vmcCmbE, vmcTot,vmcTotE, ratCmb,ratCmbE);
+  //
+  Integrate(mcdstbg,  cutSgMin,cutSgMax, vmcCmbEst,vmcCmbEstE); 
+  GetRatE(vmcCmbEst,vmcCmbEstE, vmcTot,vmcTotE, ratCmbEst,ratCmbEstE);
+  //
+  Integrate(mcDstCombC,  cutSgMin,cutSgMax, vmcCmbC,vmcCmbCE);  
+  GetRatE(vmcCmbC,vmcCmbCE, vmcTot,vmcTotE, ratCmbC,ratCmbCE);
+  //
+  double vdtTot,vdtTotE;
+  double vdtBg,vdtBgE, ratdtBg,ratdtBgE;  
+  //  
+  Integrate(dtdst,    cutSgMin,cutSgMax, vdtTot,vdtTotE);     
+  Integrate(dtdstbg,  cutSgMin,cutSgMax, vdtBg,vdtBgE);     
+  GetRatE( vdtBg,vdtBgE,  vdtTot,vdtTotE, ratdtBg,ratdtBgE);
+  //
+  //
+  double dmn = mcdst->GetMinimum();
+  double dmx = mcdst->GetMaximum();
+  TLine *ln = new TLine(cutSgMax, dmn, cutSgMax, dmx);
+  ln->SetLineColor(kBlack);
+  ln->Draw();
+  TLine *lnc = new TLine(cutBgMin, dmn, cutBgMin, dmx);
+  lnc->SetLineColor(kRed);
+  lnc->Draw();
+  if (useShapeType==kNormShapeDPhi) {
+    ln = new TLine(-cutSgMax, dmn, -cutSgMax, dmx);
+    ln->SetLineColor(kBlack);
+    ln->Draw();
+    //
+    lnc = new TLine(-cutBgMin, dmn, -cutBgMin, dmx);
+    lnc->SetLineColor(kRed);
+    lnc->Draw();
+  }
+  //
+  TLegend *legDstMC1 = new TLegend(0.60,0.72, 0.95,0.95);
+  legDstMC1->SetFillColor(kWhite);
+
+  //
+  legDstMC1->AddEntry(dtdst,    "Data raw","pl");
+  sprintf(buff,"Data Comb. %s. : %.1f%%",useBgType.Data(),ratdtBg*100);
+  legDstMC1->AddEntry(dtdstbg,  buff,"pl");
+  //
+
+
+  legDstMC1->AddEntry(mcdst,    "MC raw","pl");
+  sprintf(buff,"MC Comb. %s. : %.1f%%",useBgType.Data(),ratCmbEst*100);
+  legDstMC1->AddEntry(mcdstbg,  buff,"pl");
+  //
+  sprintf(buff,"MC Comb. %s. : %.1f%%","MC Lbl.",ratCmb*100);
+  legDstMC1->AddEntry(mcdstbgLB,  buff,"pl");
+
+  sprintf(buff,"MC Comb.Uncorr %s. : %.1f%%","MC Lbl.",ratCmbC*100);
+  legDstMC1->AddEntry(mcDstCombC,  buff,"pl");
+
+  sprintf(buff,"MC Sec.   : %.1f%%",ratSec*100);
+  legDstMC1->AddEntry(mcDstSec,  buff,"pl");
+
+  legDstMC1->Draw();
+
+  if (useShapeType==kNormShapeDist) gPad->SetLogx();
+  gPad->SetLogy();
+  gPad->SetGrid(1,1);
+  gPad->Modified();
+  //
+  canvFin->cd();
+  //
+  if (creatDnDEtaCMacro) {
+    sprintf(buff,"%s/%s_b%d_dNdEta_%s",figDir,uniqueName.Data(),bin,outStr);
+    SaveCanvas(canvFin,buff,"cg");
+  }
+  //
+}
+//
+void PlotAlphaBeta(int bin) 
+{
+  char buff[1000];
+  int shift = bin*kNHistos;
+  gStyle->SetOptFit(0);
+  gStyle->SetOptStat(0);
+  gStyle->SetOptTitle(0);
+  TObjArray* res = &resArr;
+  //------------------------------------------------------
+  if (!canvFin) canvFin = new TCanvas("canvFin","canvFin",10,10,700,1000);
+  canvFin->Clear();
+  canvFin->Divide(2,3,0.01,0.01);
+  canvFin->cd(1);
+  TH1* dtBet = (TH1*)res->At(shift + k1MBeta);
+  TH1* mcBet = (TH1*)res->At(shift + k1MBeta+kMCShift);
+  TH1* mcBetLB = (TH1*)res->At(shift + k1MBetaMC+kMCShift);
+  double mn,mx,mnt,mxt;
+  GetRealMinMax(dtBet,mn,mx);
+  GetRealMinMax(mcBet,mnt,mxt);
+  if (mnt<mn) mn = mnt;
+  if (mxt>mx) mx = mxt;
+  GetRealMinMax(mcBetLB,mnt,mxt);
+  if (mnt<mn) mn = mnt;
+  if (mxt>mx) mx = mxt;
+  //
+  dtBet->SetMinimum(mn - 0.05*(mx-mn));
+  dtBet->SetMaximum(mx + 0.05*(mx-mn));
+  mcBet->SetMinimum(mn - 0.05*(mx-mn));
+  mcBet->SetMaximum(mx + 0.05*(mx-mn));
+  mcBetLB->SetMinimum(mn - 0.05*(mx-mn));
+  mcBetLB->SetMaximum(mx + 0.05*(mx-mn));
+  //
+  canvFin->cd(1);
+  gPad->SetRightMargin(0.15);
+  dtBet->Draw("colz");
+  AddLabel("#beta Data",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  dtBet->GetYaxis()->SetTitleOffset(1.4);
+  TPaletteAxis *p = (TPaletteAxis*)dtBet->FindObject("palette");
+  if (p) p->SetX1NDC(0.85);
+  canvFin->cd(2);
+  gPad->SetRightMargin(0.15);
+  mcBet->Draw("colz");
+  AddLabel("#beta MC (bckg.estimated)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  mcBet->GetYaxis()->SetTitleOffset(1.4);
+  p = (TPaletteAxis*)mcBet->FindObject("palette");
+  if (p) p->SetX1NDC(0.85);
+  canvFin->cd(3);
+  gPad->SetRightMargin(0.15);
+  mcBetLB->Draw("colz");
+  AddLabel("#beta MC (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  mcBetLB->GetYaxis()->SetTitleOffset(1.4);
+  p = (TPaletteAxis*)mcBetLB->FindObject("palette");
+  if (p) p->SetX1NDC(0.85);
+  //
+  //------------------------------------------------------
+  TH1* dtAlp = (TH1*)res->At(shift + kAlpha);
+  TH1* mcAlp = (TH1*)res->At(shift + kAlphaMC);
+  GetRealMinMax(dtAlp,mn,mx);
+  GetRealMinMax(mcAlp,mnt,mxt);
+  if (mnt<mn) mn = mnt;
+  if (mxt>mx) mx = mxt;
+  dtAlp->SetMinimum(mn - 0.05*(mx-mn));
+  dtAlp->SetMaximum(mx + 0.05*(mx-mn));
+  mcAlp->SetMinimum(mn - 0.05*(mx-mn));
+  mcAlp->SetMaximum(mx + 0.05*(mx-mn));
+  //
+  canvFin->cd(4);
+  gPad->SetRightMargin(0.15);
+  dtAlp->Draw("colz");
+  AddLabel("#alpha (bckg.estimated)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  dtAlp->GetYaxis()->SetTitleOffset(1.4);
+  TPaletteAxis *pa = (TPaletteAxis*)dtBet->FindObject("palette");
+  if (pa) pa->SetX1NDC(0.85);
+  canvFin->cd(5);
+  gPad->SetRightMargin(0.15);
+  mcAlp->Draw("colz");
+  AddLabel("#alpha (bckg.from MC labels)",0.2,0.95,kBlack,0.05);
+  gPad->Modified();
+  mcAlp->GetYaxis()->SetTitleOffset(1.4);
+  pa = (TPaletteAxis*)mcBet->FindObject("palette");
+  if (pa) pa->SetX1NDC(0.85);
+  gPad->Modified();
+  canvFin->cd(6);
+  AddLabel(outTitle,0.1,0.5, kBlack, 0.025);
+  //
+  if (creatAlphaBetaCMacro) {
+    sprintf(buff,"%s/%sAlphaBeta_%s",figDir,uniqueName.Data(),outStr);
+    SaveCanvas(canvFin,buff,"cg");
+  }
+  //
+}
+
+void PlotSpecies() 
+{
+  char buff[1000];
+  gStyle->SetOptFit(0);
+  gStyle->SetOptStat(0);
+  gStyle->SetOptTitle(0);
+  //------------------------------------------------------
+  TH2F* hSpecPrim  = (TH2F*)FindObject(-1, "pdgPrim", listMC,kFALSE);
+  TH2F* hSpecSec   = (TH2F*)FindObject(-1, "pdgSec", listMC,kFALSE);
+  TH2F* hSpecPrimP = (TH2F*)FindObject(-1, "pdgPrimPar", listMC,kFALSE);
+  TH2F* hSpecSecP  = (TH2F*)FindObject(-1, "pdgSecPar", listMC,kFALSE);
+  int nbd = hSpecPrim->GetXaxis()->GetNbins();
+  //
+  TH1* hSpecPrimAll = hSpecPrim->ProjectionX("specPrimAll",1,nbd+1,"e");
+  hSpecPrimAll->Scale(100./hSpecPrimAll->Integral());
+  hSpecPrimAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimAll->GetXaxis()->SetLabelSize(0.06);
+  hSpecPrimAll->GetXaxis()->LabelsOption("v");
+  //
+  TH1* hSpecSecAll  = hSpecSec->ProjectionX("specSecAll",1,nbd+1,"e");
+  hSpecSecAll->Scale(100./hSpecSecAll->Integral());
+  hSpecSecAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecAll->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecPrimPAll = hSpecPrimP->ProjectionX("specPrimPAll",1,nbd+1,"e");
+  hSpecPrimPAll->Scale(100./hSpecPrimPAll->Integral());
+  hSpecPrimPAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimPAll->GetXaxis()->SetLabelSize(0.06);
+  hSpecPrimPAll->GetXaxis()->LabelsOption("v");
+
+  //
+  TH1* hSpecSecPAll  = hSpecSecP->ProjectionX("specSecPAll",1,nbd+1,"e");
+  hSpecSecPAll->Scale(100./hSpecSecPAll->Integral());
+  hSpecSecPAll->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecPAll->GetXaxis()->SetLabelSize(0.05);
+  //
+  int binCut = hSpecPrim->GetXaxis()->FindBin(kWDistSgCut-kEps);
+  TH1* hSpecPrimSel = hSpecPrim->ProjectionX("specPrimSel",1,binCut,"e");
+  hSpecPrimSel->Scale(100./hSpecPrimSel->Integral());
+  hSpecPrimSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimSel->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecSecSel  = hSpecSec->ProjectionX("specSecSel",1,binCut,"e");
+  hSpecSecSel->Scale(100./hSpecSecSel->Integral());
+  hSpecSecSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecSel->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecPrimPSel = hSpecPrimP->ProjectionX("specPrimPSel",1,binCut,"e");
+  hSpecPrimPSel->Scale(100./hSpecPrimPSel->Integral());
+  hSpecPrimPSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecPrimPSel->GetXaxis()->SetLabelSize(0.05);
+  //
+  TH1* hSpecSecPSel  = hSpecSecP->ProjectionX("specSecPSel",1,binCut,"e");
+  hSpecSecPSel->Scale(100./hSpecSecPSel->Integral());
+  hSpecSecPSel->GetYaxis()->SetTitle("Fraction,%");
+  hSpecSecPSel->GetXaxis()->SetLabelSize(0.05);
+  //
+  if (!canvFin) canvFin = new TCanvas("canvFin","canvFin",10,10,1100,800);
+  canvFin->Clear();
+  canvFin->Divide(1,2,0.01,0.01);
+  canvFin->cd(1);
+  hSpecPrimAll->Draw();
+  SetHStyle(hSpecPrimAll,kBlue,25,1.1);
+  hSpecPrimSel->Draw("same");
+  SetHStyle(hSpecPrimSel,kRed,20,1);
+  //
+  hSpecSecAll->Draw("same");
+  SetHStyle(hSpecSecAll,kGreen,32,1.1);
+  hSpecSecSel->Draw("same");
+  SetHStyle(hSpecSecSel,kBlack,22,1);
+  //
+  TLegend *legPart = new TLegend(0.8,0.72, 0.999,0.999);
+  legPart->SetFillColor(kWhite);
+  legPart->SetHeader("Tracklet PDG");
+  //
+  legPart->AddEntry(hSpecPrimAll,    "Prim., before #Delta cut","pl");
+  legPart->AddEntry(hSpecPrimSel,    "Prim., after #Delta cut","pl");
+  legPart->AddEntry(hSpecSecAll,     "Sec., before #Delta cut","pl");
+  legPart->AddEntry(hSpecSecSel,     "Sec., after #Delta cut","pl");
+  //
+  legPart->Draw();
+  gPad->SetLogy();
+  gPad->SetGrid(1,1);
+  gPad->Modified();
+  //
+  canvFin->cd(2);
+  hSpecPrimPAll->Draw();
+  SetHStyle(hSpecPrimPAll,kBlue,25,1.1);
+  hSpecPrimPSel->Draw("same");
+  SetHStyle(hSpecPrimPSel,kRed,20,1);
+  //
+  hSpecSecPAll->Draw("same");
+  SetHStyle(hSpecSecPAll,kGreen,32,1.1);
+  hSpecSecPSel->Draw("same");
+  SetHStyle(hSpecSecPSel,kBlack,22,1);
+  //
+  TLegend *legPartP = new TLegend(0.8,0.72, 0.999,0.999);
+  legPartP->SetFillColor(kWhite);
+  legPartP->SetHeader("Tracklet Parents PDG");
+  //
+  legPartP->AddEntry(hSpecPrimPAll,    "Prim., before #Delta cut","pl");
+  legPartP->AddEntry(hSpecPrimPSel,    "Prim., after #Delta cut","pl");
+  legPartP->AddEntry(hSpecSecPAll,     "Sec., before #Delta cut","pl");
+  legPartP->AddEntry(hSpecSecPSel,     "Sec., after #Delta cut","pl");
+  //
+  legPartP->Draw();
+  gPad->SetLogy();
+  gPad->SetGrid(1,1);
+  gPad->Modified();
+  //
+  canvFin->cd(1);
+  //  AddLabel(outTitle,0.1,0.97, kBlack, 0.025);
+  canvFin->cd();
+  //
+  if (creatSpeciesCMacro) {
+    sprintf(buff,"%s/%sSpecies_%s",figDir,uniqueName.Data(),outStr);
+    SaveCanvas(canvFin,buff,"cg");
+  }
+}
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, int bx0, int bx1, int by0, int by1)        
+{
+  // fill 0 to all bins outside defined range
+  TAxis *xax = histo->GetXaxis();
+  int nbx = xax->GetNbins(); 
+  double vmn=1e16,vmx=-1e16;
+  if (histo->InheritsFrom(TH2::Class())) {
+    TAxis *yax = histo->GetYaxis();
+    int nby = yax->GetNbins();
+    for (int ix=nbx+2;ix--;) {
+      for (int iy=nby+2;iy--;) {
+       if ((ix<bx0||ix>bx1)||(iy<by0||iy>by1)) {
+         histo->SetBinContent(ix,iy,0);
+         histo->SetBinError(ix,iy,0);
+       }
+       else {
+         double vl = histo->GetBinContent(ix,iy);
+         if (vl<vmn) vmn = vl;
+         if (vl>vmx) vmx = vl;
+       }
+      }
+    }
+  }
+  else {
+    for (int ix=nbx+2;ix--;) {
+      if ((ix<bx0||ix>bx1)) {
+       histo->SetBinContent(ix,0);
+       histo->SetBinError(ix,0);
+      }
+      else {
+       double vl = histo->GetBinContent(ix);
+       if (vl<vmn) vmn = vl;
+       if (vl>vmx) vmx = vl;
+      }
+    }
+  }
+  //
+  if (vmn==vmx) {
+    vmn = 0.95*vmn;
+    vmx = 1.05*vmx;
+  }
+  histo->SetMaximum(vmx);
+  histo->SetMinimum(vmn);
+}
+
+//______________________________________________________________________
+void CropHisto(TH1* histo, double vx0, double vx1, double vy0, double vy1)            
+{
+  // fill 0 to all bins outside defined range
+  TAxis *xax = histo->GetXaxis();
+  int bx0,bx1,by0=-1,by1=-1;
+  bx0 = xax->FindBin(vx0+kEps);
+  bx1 = xax->FindBin(vx1-kEps);
+  if (histo->InheritsFrom(TH2::Class())) {
+    TAxis *yax = histo->GetYaxis();
+    by0 = yax->FindBin(vy0+kEps);
+    by1 = yax->FindBin(vy1-kEps);
+  }
+  CropHisto(histo,bx0,bx1,by0,by1);
+}
+
+//______________________________________________________________________
+TH1* NormalizeBg(TH1* dataH, TH1* bgH, double &scl, double &sclE)
+{
+  // match generated bg and data tails, calculate normalization, return normalized bg copy
+  //
+  TAxis* xax = dataH->GetXaxis();
+  int nbtot = xax->GetNbins();
+  int bgBins[2][2] = {{0}}; // limiting bins for tails integration
+  Int_t ntails; // 0 for dphi plot, 1 for weighted dist plot  
+  if  (useShapeType == kNormShapeDist) { // only positive tail
+    bgBins[0][0] = xax->FindBin(kWDistBgTailMin+kEps); // positive tail min bin
+    bgBins[0][1] = xax->FindBin(kWDistBgTailMax-kEps); // positive tail max bin
+    ntails = 1;
+  }
+  else if (useShapeType == kNormShapeDPhi) {         // both tails
+    bgBins[0][0] = xax->FindBin( kdPhiBgTailMin+kEps); // positive tail min bin
+    bgBins[0][1] = xax->FindBin( kdPhiBgTailMax-kEps); // positive tail max bin
+    bgBins[1][0] = xax->FindBin(-kdPhiBgTailMax+kEps); // negative tail min bin
+    bgBins[1][1] = xax->FindBin(-kdPhiBgTailMin-kEps); // positive tail max bin    
+    ntails = 2;
+  }
+  else {printf("NormalizeBg: unknown shape type %d\n",useShapeType);exit(1);}
+  printf("NormalizeBg: bins for tails: right: %d:%d / left: %d:%d\n",bgBins[0][0],bgBins[0][1],bgBins[1][0],bgBins[1][1]);
+  // 
+  double meanR=0,meanRE=0,meanRE2=0;
+  double meanD=0,meanDE2=0;
+  double meanB=0,meanBE2=0;
+  double meanRI=0,meanRIE=0;
+  for (int itp=0;itp<=ntails;itp++) {
+    for (int ib=bgBins[itp][0];ib<=bgBins[itp][1];ib++) {
+      if (ib<1||ib>nbtot) continue;
+      double vD = dataH->GetBinContent(ib);
+      double vB = bgH->GetBinContent(ib);
+      double eD = dataH->GetBinError(ib);
+      double eB = bgH->GetBinError(ib);
+      meanD += vD; meanDE2 += eD*eD;
+      meanB += vB; meanBE2 += eB*eB;
+      if (vD<=0 || vB<=0 || eD<=0 || eB<=0) continue;
+      double rat = vD/vB;
+      double ratE2 = rat*rat*(eD*eD/vD/vD + eB*eB/vB/vB); 
+      meanR   += rat/ratE2; meanRE2 += 1.0/ratE2;
+    }
+  }
+  //
+  if (meanRE2>0) {
+    meanR  /= meanRE2;
+    meanRE2 = 1./meanRE2;
+    meanRE = TMath::Sqrt(meanRE2);
+  }
+  if (meanDE2>0 && meanBE2>0) {
+    meanRI  = meanD/meanB;
+    meanRIE =  meanRI*TMath::Sqrt(meanDE2/meanD/meanD + meanBE2/meanB/meanB);
+  }
+  printf("NormalizeBg: Tails scaling %s wrt %s: Wgh.Mean:%.4f(%.4f) / Integral:%.4f(%.4f)\n",
+        bgH->GetName(),dataH->GetName(), meanR,meanRE, meanRI,meanRIE);
+  printf("NormalizeBg: Select scaling type %s\n",useScaleType==kSclWghMean ? "Wgh.Mean":"Integral");
+  //
+  scl  = useScaleType==kSclWghMean ? meanR  : meanRI;
+  sclE = useScaleType==kSclWghMean ? meanRE : meanRIE;
+  //
+  // rescaled bg
+  char buff[1000];
+  sprintf(buff,"%s_bgNorm",bgH->GetName());
+  bgH = (TH1*)bgH->Clone(buff);
+  sprintf(buff,"%s bgNorm%d %.4f+-%.4f",bgH->GetName(),useScaleType,scl,sclE);
+  TH1* dumH = (TH1*)bgH->Clone("dummySCL$"); dumH->Reset();
+  for (int i=1;i<=nbtot;i++) {
+    dumH->SetBinContent(i,scl);
+    dumH->SetBinError(i,sclE);
+  }
+  bgH->Multiply(dumH);
+  delete dumH;
+  return bgH;
+}
+
+//______________________________________________________________________
+TObject* FindObject(int bin, const char* nameH, const TList* lst, Bool_t normPerEvent)
+{
+  // get histo, optionally normalizing it per processed event
+  if (!lst) {printf("FindObject %s: No list provided\n",nameH); exit(1);}
+  int nent = lst->GetEntries();
+  //
+  char buff[200];
+  if (bin>=0) sprintf(buff,"b%d_%s",bin,nameH);
+  else  sprintf(buff,"%s",nameH);
+  TString nm;
+  TObject *hst = 0;
+  for (int i=nent;i--;) {
+    nm = lst->At(i)->GetName();
+    if (nm.EndsWith(buff)) {hst = lst->At(i); break;}
+  }
+  if (!hst) {printf("FindObject: No bin %d %s histo in list %s\n",bin,nameH,lst->GetName()); exit(1);}
+  if (!normPerEvent || hst->TestBit(kBitNormPerEvent)) return hst; // already normalized
+  TString nameHS = nameH;
+  if (nameHS==kHStatName) return hst;                              // never scale stat. histo
+  //
+  TH1* hstat = (TH1*)FindObject(-1,kHStatName,lst,kFALSE);
+  double nrm = hstat->GetBinContent(kBinEntries + kEvProcInj+bin*kEntriesPerBin);
+  //  double nrm = hstat->GetBinContent(kBinEntries + kEvProcData+bin*kEntriesPerBin); // HACK
+  if (nrm<1) {printf("FindObject %s: Anomaluous %d number of events processed in bin %d of list %p\n",
+                    buff,int(nrm),bin,lst); return 0;}
+  //
+  if      (hst->InheritsFrom(TH1::Class())) ((TH1*)hst)->Scale(1./nrm);
+  else if (hst->InheritsFrom(THnSparse::Class())) {
+    THnSparse* spr = (THnSparse*) hst;
+    spr->Sumw2();
+    int coord[3] = {0,0,0};
+    for (Long64_t i = 0; i < spr->GetNbins(); ++i) {
+      // Get the content of the bin from the current histogram
+      Double_t v = spr->GetBinContent(i, coord);
+      spr->SetBinContent(coord, v/nrm);
+      spr->SetBinError(coord,TMath::Sqrt(v)/nrm);
+    }    
+  }
+  //
+  hst->SetBit(kBitNormPerEvent);
+  return hst;
+}
+
+//______________________________________________________________________
+TList* LoadList(const char* flName, const char* addPref, const char* nameL)
+{
+  // load list with histos
+  TString nms = flName;
+  gSystem->ExpandPathName(nms);
+  TFile* fl = TFile::Open(nms.Data());
+  if (!fl) {printf("LoadList: No file %s\n",nms.Data()); exit(1);}
+  TList* lst = (TList*)fl->Get(nameL);
+  if (!lst) {printf("LoadList: No list %s in file %s\n",nameL,nms.Data()); exit(1);}
+  lst->SetName(flName);
+  //
+  int nEnt = lst->GetSize();
+  TString nm;
+  for (int i=0;i<nEnt;i++) {
+    TNamed* ob = (TNamed*)lst->At(i);
+    nm = addPref;
+    nm += ob->GetName();
+    ob->SetName(nm.Data());
+  }
+  //
+  return lst;
+}
+
+//____________________________________________________________________________
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate)
+{
+  rat = 0; rate = 0;
+  if (TMath::Abs(y)<1e-16 || TMath::Abs(x)<1e-16) return;
+  rat = x/y;
+  rate = rat*TMath::Sqrt( xe*xe/(x*x) + ye*ye/(y*y));
+}
+
+//____________________________________________________________________________
+void Integrate(TH1* hist, double xmn,double xmx, double &val, double& err)
+{
+  // integrate 1d histo within given limits
+  TAxis* xax = hist->GetXaxis();
+  int bmn = xax->FindBin(xmn+kEps); if (bmn<1) bmn = 0; // include 
+  int bmx = xax->FindBin(xmx-kEps);
+  val = hist->IntegralAndError(bmn,bmx,err);
+  // is this histo with symmetric axis ? then integrate also negative half axis
+  if (TMath::Abs( xax->GetXmin() + xax->GetXmax() )<1e-6) {
+    bmn = xax->FindBin(-xmx+kEps); 
+    bmx = xax->FindBin(-xmn-kEps); 
+    double errn;
+    val += hist->IntegralAndError(bmn,bmx,errn);
+    err = TMath::Sqrt(err*err + errn*errn);
+  }
+}
+
+
+//____________________________________________________________________________
+const char* HName(const char* prefix,const char* htype)
+{
+  // compose the name of histo in the clist
+  static TString strh;
+  strh = "Tr"; strh += prefix; strh += "_"; strh += htype;
+  return strh.Data();
+}
+
+//____________________________________________________________________________
+Int_t CheckStat(const TList* lst, const char* dtType)
+{
+  // check if needed bg was generated
+  TH1* hstat = (TH1*)FindObject(-1,kHStatName,lst);
+  TString dts = dtType;
+  if (dts=="Data") return int( hstat->GetBinContent(kEvProcData) );
+  if (dts=="Mix")  return int( hstat->GetBinContent(kEvProcMix) );
+  if (dts=="Inj")  return int( hstat->GetBinContent(kEvProcInj) );
+  if (dts=="Rot")  return int( hstat->GetBinContent(kEvProcRot) );
+  printf("Unknown process %s statistics is checked. Alowed: Data,Mix,Inj,Rot",dtType);
+  return 0;
+}
+
+
+void GetRealMinMax(TH1* histo, double &vmn, double &vmx)
+{
+  TAxis *xax = histo->GetXaxis();
+  int nbx = xax->GetNbins(); 
+  vmn=1e6, vmx=-1e6;
+  if (histo->InheritsFrom(TH2::Class())) {
+    TAxis *yax = histo->GetYaxis();
+    int nby = yax->GetNbins();
+    for (int ix=nbx+2;ix--;) {
+      for (int iy=nby+2;iy--;) {
+       double vl = histo->GetBinContent(ix,iy);
+       if (vl<kEps) continue;
+       if (vl<vmn) vmn = vl;
+       if (vl>vmx) vmx = vl;
+      }
+    }
+  }
+  //
+  else {
+    for (int ix=nbx+2;ix--;) {
+      double vl = histo->GetBinContent(ix);
+      if (vl<vmn) vmn = vl;
+      if (vl>vmx) vmx = vl;
+    }
+  }
+  //
+}
diff --git a/PWG0/multVScentPbPb/DrawMult.C b/PWG0/multVScentPbPb/DrawMult.C
new file mode 100755 (executable)
index 0000000..f0e04fc
--- /dev/null
@@ -0,0 +1,449 @@
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "TMath.h"
+#include "TH1F.h"
+#include "TStyle.h"
+#include "TCanvas.h"
+#include "TLegend.h"
+#include "TGraphErrors.h"
+#endif
+
+void    GetRatE(double x,double xe, double y,double ye, double &rat, double &rate);
+TGraphErrors* CreateGraph(const char* nm, int np, const double *x,const double *xe, const double* y,const double *ye,Bool_t rat=kFALSE,int col=kBlack,int mrk=20,double sz=1.2,int lst=1);
+
+double Npart_Geom[11] =  {383.851,331.921,262.756,188.639,130.721 ,86.5384,54.0822,31.1483,16.0198,7.75875,3.8324};
+double Npart_rms_Geom[11] = {16.2332,17.7241,26.9529,22.2198,19.1009,15.9985,13.4516,10.7482,7.93099,4.90297,2.52505};
+//
+double Npart_Geom_4b[4]     = {396.624,371.028,344.477,319.018};
+double Npart_rms_Geom_4b[4] = {8.84252,11.016,12.1732,12.4974};
+//
+
+//double v0SelNov21[11] = 0,79,247,577,1185,2155,3565,5527,8203,12167,15073,19889
+double Npart_V0CSelNov21[11] ={380.692,328.323,259.018,185.05,128.121,84.9204,52.6411,29.79,15.1951,6.73934,2.95315};
+double Npart2_V0CSelNov21[11]={379.112,323.171,253.417,183.054,129.116,86.9088,54.2474,30.2884,15.1553,6.7094,2.95315};
+double Npart_rms_V0CSelNov21[11] = { 18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575};
+
+//double spdSelNov21[11] = 0,21,69,165,345,637,1069,1683,2511,3721,4585,6213}
+double Npart_spdSelNov21[11] ={378.888,324.787,254.892,183.689,128.448,85.0047,52.3777,28.8656,14.3408,6.70305,3.16337};
+double Npart2_spdSelNov21[11]={379.973,328.414,259.244,185.094,128.309,84.9333,52.7138,29.9245,15.3195,6.98915,3.16337};
+double Npart_rms_spdSelNov21[11] = { 21.8302, 25.7908,30.7147, 24.5131,19.7898,15.9204,12.1924,8.81696,6.18204,3.78075,1.76665 };
+
+//double spdSel[11] = {0,29,85,191,385,687,1133,1743,2567,3765,4611,6213}; 
+double Npart_spdSel[11] ={379.393,328.651,259.304,185.004,128.265,84.8281,52.7315,29.0842,15.0519,6.876,3.14467};
+double Npart2_spdSel[11]={378.367,322.458,248.503,176.048,121.769,80.3259,49.7426,28.1977,14.5535,6.88646,3.19064};
+double Npart_rms_spdSel[11] = { 21.8302, 25.7908,30.7147, 24.5131,19.7898,15.9204,12.1924,8.81696,6.18204,3.78075,1.76665 };
+//
+//double v0Sel[11]  = {0,107,297,659,1305,2301,3747,5715,8361,12307,15153,19889 };
+double Npart_V0CSel[11]  ={381.040,328.781,259.314,185.197,128.160,84.8531,52.6495,29.7634,15.0721,6.67109,2.93958};
+double Npart2_V0CSel[11] ={375.596,313.697,240.935,170.22,118.96,79.1409,49.3726,28.2845,14.6765,6.62758,2.91953};
+double Npart_rms_V0CSel[11] = {18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575};
+//
+//double v0rSel[11]  = {0,32.5,89.5,198.5,396.5,700.5,1140.5,1744.5,2562.5,3767.5,4647.5,6367.5};
+double Npart_V0CRSel[11]  ={379.114,329.655,260.318,185.996,130.454,87.0497,54.7531,31.4739,15.9883,7.28226,3.23659};
+double Npart2_V0CRSel[11] ={376.795,319.268,244.685,172.492,120.471,80.0706,49.9794,28.5653,14.7274,7.13181,3.27423};
+double Npart_rms_V0CRSel[11] = {18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575};
+//
+//double tpcSel[11]  = {0,13,37,85,171,307,507,783,1157,1685,2055,2787}; // these are  tracks 
+double Npart_TPCSel[11]  ={378.667,329.234,259.17,185.129,128.221,84.7075,52.6338,29.7764,15.1032,6.98597,3.22604}; // these are  tracks 
+double Npart2_TPCSel[11] ={378.513,325.472,251.739,178.55,123.373,81.187,50.2066,28.4005,14.466,6.92418,3.30427};
+double Npart_rms_TPCSel[11] = {18.4857,19.5242,27.0422,21.1484,16.5675,12.8486,9.64889,6.81264,4.5665,2.72584,1.2575}; // wrong
+//
+
+//double spdSelNov21[11] = 0,21,69,165,345,637,1069,1683,2511,3721,4585,6213}
+double Npart_spdSelNov21_4b[4] ={396.624,371.02,344.477,319.018};
+double Npart_rms_spdSelNov21_4b[11] = {8.84252,11.016,12.1732,12.4974};
+//
+
+//----------------------------------------------------------------------------------
+double mltV0Ch11Nov27[] = {1590.09,1272.03,951.40,640.01,419.10,256.36,146.50,75.01,34.15,13.10,3.37};
+double mltV0Ch11eNov27[] = {2.29,1.98,1.17,0.94,0.75,0.56,0.41,0.28,0.19,0.11,0.05};
+
+// new baseline with ZDC TDC cleanup
+double mltV0Ch11Nov29[]  = {1600.98,1293.63,966.21,649.30,426.09,260.65,149.44,76.23,34.75,13.28,3.38};
+double mltV0Ch11eNov29[] = {2.34,1.96,1.17,0.93,0.74,0.55,0.41,0.28,0.19,0.11,0.05};
+
+// new baseline with ZDC TDC cleanup
+double mltV0Ch11Nov29_4b[4]  = {1693.65,1512.59,1365.12,1222.52};
+double mltV0Ch11Nov29_4be[4] = {3.69,3.04,2.91,2.66};
+
+
+//ZDC vs V0C, LHC10h_000137161_ZDCV0_24Nov10RS
+// result from setting ZDC&V0 to 80% in the same V0 as V01D
+////double mltZDCV0Ch8Nov24RS[11]={1599.53,1278.17,941.59,625.66,402.07,240.92,130.04,56.54,29.69,15.04,8.12};
+////double mltZDCV0Ch8eNov24RS[11]={2.31,1.89,1.13,0.89,0.69,0.51,0.35,0.22,0.16,0.12,0.11};
+// result from setting ZDC&V0 to have the same excess at 0 as V01D
+double mltZDCV0Ch8Nov24RS[11]={1606.24,1294.40,964.34,651.15,427.81,264.23,149.39,72.52,34.75,18.79,8.92};
+double mltZDCV0Ch8eNov24RS[11]={2.34,1.93,1.16,0.92,0.74,0.55,0.40,0.27,0.18,0.14,0.12};
+
+//----------------------------------------------------------------------------------
+//V0C, LHC10h8_000137161_V0C
+double mltV0Ch8Nov21[11]={1606.14,1293.78,963.88,650.18,427.15,263.20,151.27,77.95,36.07,13.72,4.19};
+double mltV0Ch8eNov21[11]={2.34,1.93,1.16,0.92,0.74,0.55,0.40,0.28,0.19,0.11,0.06};
+
+
+//-----------------------------------
+//SPD, LHC10h8_000137161_SPD
+double mltSPDh8Nov21[11]={1608.81,1293.03,962.20,647.64,424.17,259.92,149.15,75.83,34.56,12.68,3.40};
+double mltSPDh8eNov21[11]={2.31,1.96,1.15,0.91,0.72,0.54,0.40,0.28,0.19,0.11,0.06};
+
+
+//SPD, LHC10h6_000137161_SPD (off-vertex primaries removed)
+double mltSPDh6[11]={1603.99,1298.08,972.26,661.06,441.62,276.34,163.10,86.02,40.75,16.28,4.13};
+double mltSPDh6e[11]={2.54,2.11,1.26,1.01,0.80,0.61,0.46,0.33,0.23,0.14,0.06};
+
+//-----------------------------------
+//SPD, LHC10h8_000137161_SPD
+double mltSPDh8[11]={1613.30,1304.45,977.46,665.32,442.60,277.46,163.26,86.15,40.97,16.36,4.17};
+double mltSPDh8e[11]={2.35,1.99,1.18,0.94,0.76,0.57,0.43,0.31,0.21,0.13,0.06};
+
+//-----------------------
+//V0C, LHC10h8_000137161_V0C
+double mltV0Ch8[11]={1610.21,1304.62,977.99,667.33,444.72,279.27,164.76,87.79,42.34,17.53,4.89};
+double mltV0Ch8e[11] = {2.38,1.97,1.18,0.95,0.76,0.57,0.43,0.31,0.21,0.13,0.06};
+
+//-----------------------
+//V0CR, LHC10h8_000137161_V0CR
+double mltV0CRh8[11]={1611.13,1304.76,994.16,678.31,449.72,282.53,166.06,87.97,42.40,17.49,4.99};
+double mltV0CRh8e[11]={2.38,1.98,1.19,0.97,0.77,0.58,0.43,0.31,0.21,0.13,0.06};
+
+//-----------------------
+//TPC, LHC10h8_000137161_TPC
+double mltTPCh8[11]={1616.65,1304.32,957.72,656.67,435.59,273.39,160.58,86.09,40.96,16.58,4.16};
+double mltTPCh8e[11]={2.44,2.01,1.15,0.92,0.74,0.56,0.42,0.31,0.21,0.13,0.06};
+
+//--------------------------
+//137366, SPD, LHC10h8_000137366_SPD
+double mlt366SPDh8[11]={1574.05,1278.00,955.98,651.66,432.23,272.50,158.64,84.24,39.71,16.16,4.01};
+double mlt366SPDh8e[11]={1.96,1.69,0.98,0.81,0.62,0.48,0.36,0.25,0.17,0.10,0.05};
+
+//--------------------------
+//SPD, LHC10h2_000137161_SPD  DPMJET
+double  mltSPDdpmjh2[11]={1624.52,1304.84,976.87,664.33,443.03,277.41,163.68,85.95,40.76,16.58,4.25};
+double  mltSPDdpmjh2e[11]={2.12,2.46,1.53,1.29,1.06,0.81,0.62,0.43,0.29,0.19,0.09};
+
+//-------------------------------------------------------------------------
+// top 4x2.5% bins in SPD 
+double mltSPDh8_4b[4] = {1702.89,1516.20,1362.55,1221.55}; // w.means: 1587.4, 1259.0
+double mltSPDh8_4be[4] = {3.55,3.06,2.91,2.65};
+//double mltSPDh8_4b[4] = {1681.25,1480.93,1322.75,1188.11}; // w.means: 1587.4, 1259.0
+//double mltSPDh8_4be[4] = {3.51,3.01,2.83,2.59};
+
+//-------------------------------------------------------------------------
+// top 4x2.5% bins in V0
+double mltV0Ch8_4b[4]  = {1692.60,1514.45,1363.53,1221.21};
+double mltV0Ch8_4be[4] = {3.69,3.02,2.85,2.61};
+//double mltSPDh8_4b[4] = {1681.25,1480.93,1322.75,1188.11}; // w.means: 1587.4, 1259.0
+//double mltSPDh8_4be[4] = {3.51,3.01,2.83,2.59};
+
+
+
+TGraphErrors *MV0Ch11Nov27A=0,*RV0Ch11Nov27A=0;
+
+TGraphErrors *MV0Ch11Nov29=0,*RV0Ch11Nov29=0;
+
+TGraphErrors *MzdcV0CNov24=0,*RzdcV0CNov24=0;
+//
+TGraphErrors *Mspdh8Nov21=0,*Mspdh8aNov21=0,*Rspdh8Nov21=0,*Rspdh8aNov21=0;
+TGraphErrors *MV0Ch8Nov21=0,*MV0Ch8aNov21=0,*RV0Ch8Nov21=0,*RV0Ch8aNov21=0;
+
+TGraphErrors *Mspdh6=0,*Mspdh6a=0,*Rspdh6=0,*Rspdh6a=0;
+TGraphErrors *Mspdh8=0,*Mspdh8a=0,*Rspdh8=0,*Rspdh8a=0;
+TGraphErrors *MV0Ch8=0,*MV0Ch8a=0,*RV0Ch8=0,*RV0Ch8a=0;
+TGraphErrors *MV0CRh8=0,*MV0CRh8a=0,*RV0CRh8=0,*RV0CRh8a=0;
+TGraphErrors *Mtpch8=0,*Mtpch8a=0,*Rtpch8=0,*Rtpch8a=0;
+TGraphErrors *Mspd366h8=0,*Mspd366h8a=0,*Rspd366h8=0,*Rspd366h8a=0;
+TGraphErrors *MspdDPMJh2=0,*MspdDPMJh2a=0,*RspdDPMJh2=0,*RspdDPMJh2a=0;
+
+TGraphErrors *Mspd4b=0,*Rspd4b=0;
+TGraphErrors *MV0C4b=0,*RV0C4b=0;
+
+TGraphErrors *MV0C29Nov4b=0,*RV0C29Nov4b=0;
+
+TCanvas *cnvMult=0;
+TCanvas *cnvMultR=0;
+TH1F *frMlt,*frMltR=0;
+
+void DrawMult()
+{
+  gStyle->SetOptStat(0);
+
+  /*
+  Mspd4b       =  CreateGraph("Mspd4b" ,4,Npart_spdSelNov21_4b,Npart_rms_spdSelNov21_4b, mltSPDh8_4b,mltSPDh8_4be ,kFALSE, kGreen, 20,1.2,1);
+  Rspd4b       =  CreateGraph("Rspd4b" ,4,Npart_spdSelNov21_4b,Npart_rms_spdSelNov21_4b, mltSPDh8_4b,mltSPDh8_4be ,kTRUE,  kGreen, 20,1.2,1);
+  //
+  Mspdh8Nov21  = CreateGraph("Mspdh8Nov21" ,11,Npart_spdSelNov21 ,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kFALSE, kRed, 20,1.2,1);
+  Mspdh8aNov21 = CreateGraph("Mspdh8aNov21",11,Npart2_spdSelNov21,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kFALSE, kRed, 24,1.42,2);
+  Rspdh8Nov21  = CreateGraph("Rspdh8Nov21" ,11,Npart_spdSelNov21 ,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kTRUE,  kRed, 20,1.2,1);
+  Rspdh8aNov21 = CreateGraph("Rspdh8aNov21",11,Npart2_spdSelNov21,Npart_rms_spdSelNov21,mltSPDh8Nov21,mltSPDh8eNov21, kTRUE,  kRed, 24,1.42,2);
+  //
+  MV0Ch8Nov21  = CreateGraph("MV0Ch8Nov21" ,11,Npart_V0CSelNov21 ,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kFALSE, kBlue, 20,1.2, 1);
+  MV0Ch8aNov21 = CreateGraph("MV0Ch8aNov21",11,Npart2_V0CSelNov21,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kFALSE, kBlue, 24,1.42, 2);
+  RV0Ch8Nov21  = CreateGraph("RV0Ch8Nov21" ,11,Npart_V0CSelNov21 ,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kTRUE,  kBlue, 20,1.2, 1);
+  RV0Ch8aNov21 = CreateGraph("RV0Ch8aNov21",11,Npart2_V0CSelNov21,Npart_rms_V0CSelNov21,mltV0Ch8Nov21,mltV0Ch8eNov21, kTRUE,  kBlue, 24,1.42, 2);
+  //
+  Mtpch8  = CreateGraph("Mtpch8" ,11,Npart_TPCSel ,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kFALSE, kBlack, 23, 1.2, 1);
+  Mtpch8a = CreateGraph("Mtpch8a",11,Npart2_TPCSel,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kFALSE, kBlack, 32, 1.2, 2);
+  Rtpch8  = CreateGraph("Rtpch8" ,11,Npart_TPCSel ,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kTRUE,  kBlack, 23, 1.2, 1);
+  Rtpch8a = CreateGraph("Rtpch8a",11,Npart2_TPCSel,Npart_rms_TPCSel,mltTPCh8,mltTPCh8e, kTRUE,  kBlack, 32, 1.2, 2);
+  //  //
+  */
+  Mspd4b       =  CreateGraph("Mspd4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltSPDh8_4b,mltSPDh8_4be ,kFALSE, kGreen, 20,1.2,1);
+  Rspd4b       =  CreateGraph("Rspd4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltSPDh8_4b,mltSPDh8_4be ,kTRUE,  kGreen, 20,1.2,1);
+  //
+  MV0C4b       =  CreateGraph("MV0C4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch8_4b,mltV0Ch8_4be ,kFALSE, kMagenta, 21,1.2,1);
+  RV0C4b       =  CreateGraph("RV0C4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch8_4b,mltV0Ch8_4be ,kTRUE,  kMagenta, 21,1.2,1);
+  //
+  MV0C29Nov4b  =  CreateGraph("MV0C29Nov4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch11Nov29_4b,mltV0Ch11Nov29_4be ,kFALSE, kGreen+1, 26,1.2,1);
+  RV0C29Nov4b  =  CreateGraph("RV0C29Nov4b" ,4,Npart_Geom_4b,Npart_rms_Geom_4b, mltV0Ch11Nov29_4b,mltV0Ch11Nov29_4be ,kTRUE,  kGreen+1, 26,1.2,1);
+  //
+  MzdcV0CNov24 = CreateGraph("MzdcV0CNov24" ,11,Npart_Geom ,Npart_rms_Geom,mltZDCV0Ch8Nov24RS,mltZDCV0Ch8eNov24RS, kFALSE, kBlack, 25,1.4,1);
+  RzdcV0CNov24 = CreateGraph("RzdcV0CNov24" ,11,Npart_Geom ,Npart_rms_Geom,mltZDCV0Ch8Nov24RS,mltZDCV0Ch8eNov24RS, kTRUE,  kBlack, 25,1.4,1);
+  //
+  Mspdh8Nov21  = CreateGraph("Mspdh8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltSPDh8Nov21,mltSPDh8eNov21, kFALSE, kRed, 20,1.4,1);
+  Rspdh8Nov21  = CreateGraph("Rspdh8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltSPDh8Nov21,mltSPDh8eNov21, kTRUE,  kRed, 20,1.4,1);
+  //
+  MV0Ch8Nov21  = CreateGraph("MV0Ch8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch8Nov21,mltV0Ch8eNov21, kFALSE, kBlue, 20,1.2, 1);
+  RV0Ch8Nov21  = CreateGraph("RV0Ch8Nov21" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch8Nov21,mltV0Ch8eNov21, kTRUE,  kBlue, 20,1.2, 1);
+  //
+  //
+  MV0Ch11Nov27A  = CreateGraph("MV0Ch8Nov27A" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov27,mltV0Ch11eNov27, kFALSE, kCyan, 20,1.2, 1);
+  RV0Ch11Nov27A  = CreateGraph("RV0Ch8Nov27A" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov27,mltV0Ch11eNov27, kTRUE,  kCyan, 20,1.2, 1);
+  //
+  MV0Ch11Nov29  = CreateGraph("MV0Ch8Nov29" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov29,mltV0Ch11eNov29, kFALSE, kGreen+1, 22,1., 1);
+  RV0Ch11Nov29  = CreateGraph("RV0Ch8Nov29" ,11,Npart_Geom ,Npart_rms_Geom,mltV0Ch11Nov29,mltV0Ch11eNov29, kTRUE,  kGreen+1, 22,1., 1);
+  //
+  Mtpch8  = CreateGraph("Mtpch8" ,11,Npart_Geom ,Npart_rms_Geom,mltTPCh8,mltTPCh8e, kFALSE, kBlack, 23, 1.2, 1);
+  Rtpch8  = CreateGraph("Rtpch8" ,11,Npart_Geom ,Npart_rms_Geom,mltTPCh8,mltTPCh8e, kTRUE,  kBlack, 23, 1.2, 1);
+  //
+  Mspdh6  = CreateGraph("Mspdh6" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kFALSE, kRed, 29, 1.0,1);
+  Mspdh6a = CreateGraph("Mspdh6a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kFALSE, kRed, 30, 1.0,2);
+  Rspdh6  = CreateGraph("Rspdh6" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kTRUE,  kRed, 29, 1.0,1);
+  Rspdh6a = CreateGraph("Rspdh6a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh6,mltSPDh6e, kTRUE,  kRed, 30, 1.0,2);
+  //
+  Mspdh8  = CreateGraph("Mspdh8" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kFALSE, kMagenta, 20,1.02,1);
+  Mspdh8a = CreateGraph("Mspdh8a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kFALSE, kMagenta, 24,1.02,2);
+  Rspdh8  = CreateGraph("Rspdh8" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kTRUE,  kMagenta, 20,1.02,1);
+  Rspdh8a = CreateGraph("Rspdh8a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDh8,mltSPDh8e, kTRUE,  kMagenta, 24,1.02,2);
+  //
+  MV0Ch8  = CreateGraph("MV0Ch8" ,11,Npart_V0CSel ,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kFALSE, kCyan, 21,1.02, 1);
+  MV0Ch8a = CreateGraph("MV0Ch8a",11,Npart2_V0CSel,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kFALSE, kCyan, 25,1.02, 2);
+  RV0Ch8  = CreateGraph("RV0Ch8" ,11,Npart_V0CSel ,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kTRUE,  kCyan, 21,1.02, 1);
+  RV0Ch8a = CreateGraph("RV0Ch8a",11,Npart2_V0CSel,Npart_rms_V0CSel,mltV0Ch8,mltV0Ch8e, kTRUE,  kCyan, 25,1.02, 2);
+  //
+  MV0CRh8  = CreateGraph("MV0CRh8" ,11,Npart_V0CRSel ,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kFALSE, kGreen, 22,1.2, 1);
+  MV0CRh8a = CreateGraph("MV0CRh8a",11,Npart2_V0CRSel,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kFALSE, kGreen, 26,1.2, 2);
+  RV0CRh8  = CreateGraph("RV0CRh8" ,11,Npart_V0CRSel ,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kTRUE,  kGreen, 22,1.2, 1);
+  RV0CRh8a = CreateGraph("RV0CRh8a",11,Npart2_V0CRSel,Npart_rms_V0CRSel,mltV0CRh8,mltV0CRh8e, kTRUE,  kGreen, 26,1.2, 2);
+  //
+  Mspd366h8  = CreateGraph("Mspd366h8" ,11,Npart_spdSel ,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kFALSE, kRed, 27, 1.0, 1);
+  Mspd366h8a = CreateGraph("Mspd366h8a",11,Npart2_spdSel,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kFALSE, kRed, 33, 1.0, 2);
+  Rspd366h8  = CreateGraph("Rspd366h8" ,11,Npart_spdSel ,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kTRUE,  kRed, 27, 1.0, 1);
+  Rspd366h8a = CreateGraph("Rspd366h8a",11,Npart2_spdSel,Npart_rms_spdSel,mlt366SPDh8,mlt366SPDh8e, kTRUE,  kRed, 33, 1.0, 2);
+  //
+  MspdDPMJh2  = CreateGraph("MspdDPMJh2" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kFALSE, kRed, 28, 1.0, 1);
+  MspdDPMJh2a = CreateGraph("MspdDPMJh2a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kFALSE, kRed, 34, 1.0, 2);
+  RspdDPMJh2  = CreateGraph("RspdDPMJh2" ,11,Npart_spdSel ,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kTRUE,  kRed, 28, 1.0, 1);
+  RspdDPMJh2a = CreateGraph("RspdDPMJh2a",11,Npart2_spdSel,Npart_rms_spdSel,mltSPDdpmjh2,mltSPDdpmjh2e, kTRUE,  kRed, 34, 1.0, 2);
+  //
+  TLegend *lg = new TLegend(0.4,0.2,0.65,0.5);
+  lg->SetFillColor(kWhite);
+  lg->SetHeader("N_{part} Glauber");
+  //  lg->AddEntry(Rspdh8,"SPD corr","pl");
+  //  lg->AddEntry(RV0Ch8,"V0 corr","pl");
+  //  lg->AddEntry(RV0CRh8,"V0 corr resc","pl");
+  //  lg->AddEntry(Rtpch8,"TPC","pl");
+  //
+  //  lg->AddEntry(Rspdh6,"SPD corr, old hijing","pl");
+  //  lg->AddEntry(Rspd366h8,"SPD corr, 137366","pl");
+  //  lg->AddEntry(RspdDPMJh2,"SPD corr, dpmjet","pl");
+  //
+  //  lg->AddEntry(Rspdh8Nov21,"SPD corr, 21/11/10","pl");
+  lg->AddEntry(RV0Ch8Nov21,"V0  corr, 21/11/10","pl");
+  //  lg->AddEntry(RzdcV0CNov24,"ZDC & V0 corr","pl");
+  //  lg->AddEntry(Rspd4b,"SPD corr, 4#times2.5%","pl");
+  lg->AddEntry(RV0C4b,"V0 corr, 4#times2.5%","pl");
+  //  lg->AddEntry(RV0Ch11Nov27A,"V0 corr, 5+ 27/11/10","pl");
+  lg->AddEntry(RV0Ch11Nov29,"V0 corr, 5+ 29/11/10","pl");
+  lg->AddEntry(RV0C29Nov4b,"V0 corr, 5+ 29/11/10, 4#times2.5%","pl");
+  //
+  TLegend *lga = new TLegend(0.65,0.2,0.8,0.5);
+  lga->SetFillColor(kWhite);
+  lga->SetHeader("N_{part} data");
+  lga->AddEntry(Rspdh8a," ","pl");
+  lga->AddEntry(RV0Ch8a," ","pl");
+  //  lga->AddEntry(RV0CRh8a, " ","pl");
+  //  lga->AddEntry(Rtpch8a," ","pl");
+  //
+  //  lga->AddEntry(Rspdh6a," ","pl");
+  //  lga->AddEntry(Rspd366h8a," ","pl");
+  //  lga->AddEntry(RspdDPMJh2a," ","pl");
+  //
+  lga->AddEntry(Rspdh8aNov21,"SPD corr, 21/11/10","pl");
+  lga->AddEntry(RV0Ch8aNov21,"V0  corr, 21/11/10","pl");
+  //
+
+
+  frMlt = new TH1F("dndeta","dN/d#eta",86,1,430);
+  frMlt->SetMinimum(1e-3);
+  frMlt->SetMaximum(2000);
+  frMlt->GetXaxis()->SetTitle("N_{part}");
+  frMlt->GetYaxis()->SetTitle("dN/d#eta_{|#eta|<0.5}");
+  
+  frMltR = new TH1F("dndetaperpart","dN/d#eta / part.pair",86,1,430);
+  frMltR->SetMinimum(1e-3);
+  frMltR->SetMaximum(10);
+  frMltR->GetXaxis()->SetTitle("N_{part}");
+  frMltR->GetYaxis()->SetTitle("dN/d#eta_{|#eta|<0.5} / part.pair");
+  
+  cnvMult  = new TCanvas("cnvMult","",10,10,1000,700);
+  cnvMultR = new TCanvas("cnvMultR","",20,20,1000,700);
+  //
+  cnvMult->cd();
+  gPad->Clear();
+  gPad->SetLeftMargin(0.15);
+  gPad->SetBottomMargin(0.15);
+  frMlt->Draw();
+  frMlt->GetYaxis()->SetTitleOffset(1.6);
+  frMlt->GetYaxis()->SetLabelSize(0.03);
+  frMlt->GetXaxis()->SetTitleOffset(1.6);
+  frMlt->GetXaxis()->SetLabelSize(0.03);
+  gPad->SetGrid(1,1);
+  //
+  //  Mspdh6->Draw("p");
+  //  Mspdh6a->Draw("p");
+  //
+  //  Mspd366h8->Draw("p");
+  //  Mspd366h8a->Draw("p");
+  //
+  //  MspdDPMJh2->Draw("p");
+  //  MspdDPMJh2a->Draw("p");
+  //
+  //  Mspdh8->Draw("p");
+  //  Mspdh8a->Draw("p");
+  //
+  //  Mspd4b->Draw("p");
+  MV0C4b->Draw("p");
+  MV0C29Nov4b->Draw("p");
+  //
+  //  MV0Ch8->Draw("p");
+  //  MV0Ch8a->Draw("p");
+  //
+  //  MV0CRh8->Draw("p");
+  //  MV0CRh8a->Draw("p");
+  //
+  //  Mtpch8->Draw("p");
+  //  Mtpch8a->Draw("p");
+  //
+  //
+  //  Mspdh8Nov21->Draw("p");
+  //  Mspdh8aNov21->Draw("p");
+  //
+  MV0Ch8Nov21->Draw("p");
+  //  MV0Ch8aNov21->Draw("p");
+  //
+  //  MzdcV0CNov24->Draw("p");
+  //
+
+  //  MV0Ch11Nov27A->Draw("p");
+  MV0Ch11Nov29->Draw("p");
+
+  lg->Draw();
+  //  lga->Draw();
+  //----------------------------------------
+  //
+  cnvMultR->cd();
+  gPad->Clear();
+  gPad->SetLeftMargin(0.15);
+  gPad->SetBottomMargin(0.15);
+  frMltR->Draw();
+  frMltR->GetYaxis()->SetTitleOffset(1.6);
+  frMltR->GetYaxis()->SetLabelSize(0.03);
+  frMltR->GetXaxis()->SetTitleOffset(1.6);
+  frMltR->GetXaxis()->SetLabelSize(0.03);
+  gPad->SetGrid(1,1);
+  //
+  //  /*
+  //  Rspdh6->Draw("p");
+  //  Rspdh6a->Draw("p");
+  //
+  //  Rspd366h8->Draw("p");
+  //  Rspd366h8a->Draw("p");
+  //
+  //  RspdDPMJh2->Draw("p");
+  //  RspdDPMJh2a->Draw("p");
+  //
+  //  */
+  //  Rspdh8->Draw("p");
+  //  Rspdh8a->Draw("p");
+  //
+  //  Rspd4b->Draw("p");
+  RV0C4b->Draw("p");
+  //
+  //  RV0Ch8->Draw("p");
+  //  RV0Ch8a->Draw("p");
+  //
+  //  RV0CRh8->Draw("p");
+  //  RV0CRh8a->Draw("p");
+  //
+  //  Rtpch8->Draw("p");
+  //  Rtpch8a->Draw("p");
+  //
+  //  Rspdh8Nov21->Draw("p");
+  //  Rspdh8aNov21->Draw("p");
+  //
+  RV0Ch8Nov21->Draw("p");
+  //  RV0Ch8aNov21->Draw("p");
+  //  RzdcV0CNov24->Draw("p");
+
+  //  RV0Ch11Nov27A->Draw("p");
+  RV0Ch11Nov29->Draw("p");
+  RV0C29Nov4b->Draw("p");
+  //
+  lg->Draw();
+  //  lga->Draw();
+  //
+}
+
+
+
+TGraphErrors* CreateGraph(const char* nm, int np, const double *x,const double *xe, const double* y,const double *ye,Bool_t rat,int col,int mrk,double sz,int lst)
+{
+  TGraphErrors* gr = new TGraphErrors(np);
+  gr->SetName(nm);
+  gr->SetTitle(nm);
+  gr->SetMarkerStyle(mrk);
+  gr->SetMarkerSize(sz);
+  gr->SetMarkerColor(col);
+  gr->SetLineColor(col);
+  gr->SetLineStyle(lst);
+  int ip=0;
+  for (int i=0;i<np;i++) {
+    double px  = x[i];
+    double pxe = xe[i];
+    double py = y[i];
+    double pye = ye[i];
+    if (rat) {
+      double rt,rte;
+      GetRatE(py,pye, px/2, 0, rt,rte);
+      py = rt;
+      pye = rte;
+    }
+    gr->SetPoint(ip, px,py);
+    gr->SetPointError(ip, pxe,pye);
+    ip++;
+  }
+  //
+  return gr;
+}
+
+
+
+
+//____________________________________________________________________________
+void GetRatE(double x,double xe, double y,double ye, double &rat, double &rate)
+{
+  rat = 0; rate = 0;
+  if (TMath::Abs(y)<1e-16 || TMath::Abs(x)<1e-16) return;
+  rat = x/y;
+  rate = rat*TMath::Sqrt( xe*xe/(x*x) + ye*ye/(y*y));
+  //  printf("RAT %e %e / %e %e -> %e %e\n",x,xe,y,ye,rat,rate);
+}
diff --git a/PWG0/multVScentPbPb/MyAnalysisMacro.C b/PWG0/multVScentPbPb/MyAnalysisMacro.C
new file mode 100755 (executable)
index 0000000..03b50d6
--- /dev/null
@@ -0,0 +1,256 @@
+void MyAnalysisMacro(TString dataset="/alice/sim/LHC10f8f_130844",
+                    TString outFName="trbg.root",
+                    Bool_t doRec  = kTRUE,
+                    Bool_t doInj  = kTRUE,
+                    Bool_t doRot  = kTRUE,
+                    Bool_t doMix  = kFALSE,
+                    Bool_t useMC  = kTRUE,
+                    Bool_t checkReconstructables = kTRUE,
+                    // 
+                    Float_t etaCut     = 2.5,
+                    //
+                    // specific parameters for reconstruction
+                    //----------------------- Zv selection parameters important for mixing, to be tuned
+                    Float_t zMin       = -20,
+                    Float_t zMax       =  20,
+                    Float_t zMixBinSz  =  5, //0.1,
+                    //---------------------------------------------------------------------------------
+                    //
+                    //----------------------- Ntracklets selection parameters important for mixing, to be tuned
+                    Float_t ntMin      =   1,
+                    Float_t ntMax      = 15000,
+                    Float_t ntMixBinSz =  5000, 
+                    //---------------------------------------------------------------------------------
+                    //
+                    float  phiRot      = 3.14159e+00,
+                    float  injScale    = 0.7,
+                    Bool_t scaleDTheta = kTRUE,
+                    float  nStdDev     = 25.,
+                    float  dphi        = 0.08, 
+                    float  dtht        = 0.025, 
+                    float  phishift    = 0.0045, 
+                    Bool_t remOvl      = kTRUE, 
+                    float  ovlPhiCut   = 0.005, 
+                    float  ovlZetaCut  = 0.05,
+                    Int_t  nEvents     = 50000,
+                    Int_t  nEventsSkip = 0) 
+{
+  //  
+  TString format = GetFormatFromDataSet(dataset);
+  //
+  // ALICE stuff
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) mgr = new AliAnalysisManager("Test train");
+  //
+  InputHandlerSetup(format,useMC);
+  if (doMix) MixHandlerSetup(ntMin,ntMax,ntMixBinSz, zMin,zMax,zMixBinSz);
+  // compile our task
+  gProof->Load("AliITSMultRecBg.cxx++");
+  gProof->Load("AliTrackletTaskUni.cxx++");
+  //
+  // load and run AddTask macro
+  gROOT->LoadMacro("AddMultTaskRS.C");
+  //
+  // create our task
+  AliTrackletTaskUni *mltTask = AddMultTaskRS(outFName.Data());
+  //
+  mltTask->SetDoNormalReco(doRec);
+  mltTask->SetDoInjection(doInj);
+  mltTask->SetDoRotation(doRot);
+  mltTask->SetDoMixing(doMix);  
+  //
+  mltTask->SetUseMC(useMC);
+  mltTask->SetCheckReconstructables(checkReconstructables);
+  //
+  mltTask->SetEtaCut(etaCut);
+  mltTask->SetZVertexMin(zMin);
+  mltTask->SetZVertexMax(zMax);
+  mltTask->SetMultCutMin(ntMin);
+  mltTask->SetMultCutMax(ntMax);
+  //
+  mltTask->SetScaleDThetaBySin2T(scaleDTheta);
+  mltTask->SetNStdDev(nStdDev);
+  mltTask->SetPhiWindow(dphi);
+  mltTask->SetThetaWindow(dtht);
+  mltTask->SetPhiShift(phishift);
+  mltTask->SetPhiOverlapCut(ovlPhiCut);
+  mltTask->SetZetaOverlapCut(ovlZetaCut);
+  mltTask->SetPhiRot(phiRot);
+  mltTask->SetInjScale(injScale);
+  mltTask->SetRemoveOverlaps(remOvl);
+  //
+  printf("new Task: %p\n",mltTask);
+  //
+  AddPhysicsSelection(useMC);
+  mltTask->SelectCollisionCandidates(useMC ? (AliVEvent::kMB) : (AliVEvent::kUserDefined) );
+  //
+  // Run analysis
+  mgr->InitAnalysis();
+  // process dataset  
+  mgr->StartAnalysis("proof", dataset.Data(), nEvents, nEventsSkip); 
+  //
+  TString evstCmd = "if [ -e event_stat.root ]; then \nmv event_stat.root evstat_"; 
+  evstCmd += outFName;  evstCmd += " \nfi";
+  gSystem->Exec( evstCmd.Data() );
+  
+}
+
+
+TString GetFormatFromDataSet(TString dataset) {
+  
+//   Info("runAAF.C","Detecting format from dataset (may take while, depends on network connection)...");
+  TString dsTreeName;
+  if (dataset.Contains("#")) {
+    Info("runAAF.C",Form("Detecting format from dataset name '%s' ...",dataset.Data()));
+    dsTreeName=dataset(dataset.Last('#'),dataset.Length());
+  } else {
+    Info("runAAF.C",Form("Detecting format from dataset '%s' (may take while, depends on network connection) ...",dataset.Data()));
+    TFileCollection *ds = gProof->GetDataSet(dataset.Data());
+    if (!ds) {
+      Error(Form("Dataset %s doesn't exist on proof cluster!!!!",dataset.Data()));
+      return "";
+    }
+    dsTreeName = ds->GetDefaultTreeName();
+  }
+
+  if (dsTreeName.Contains("esdTree")) {
+    Info("runAAF.C","ESD input format detected ...");
+    return "ESD";
+  } else if (dsTreeName.Contains("aodTree"))  {
+    Info("runAAF.C","AOD input format detected ...");
+    return "AOD";
+  } else {
+    Error("runAAF.C",Form("Tree %s is not supported !!!",dsTreeName.Data()));
+    Error("runAAF.C",Form("Maybe set your DS to %s#esdTree or %s#aodTree",dataset.Data(),dataset.Data()));
+  }
+  
+  return "";
+}
+
+Bool_t InputHandlerSetup(TString format = "esd", Bool_t useKine = kTRUE)
+{
+  format.ToLower();
+
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+
+  AliAnalysisDataContainer *cin = mgr->GetCommonInputContainer();
+
+  if (cin) return;
+
+  if (!format.CompareTo("esd"))
+  {
+    AliESDInputHandler *esdInputHandler = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+    if (!esdInputHandler)
+    {
+      Info("CustomAnalysisTaskInputSetup", "Creating esdInputHandler ...");
+      esdInputHandler = new AliESDInputHandlerRP();
+      mgr->SetInputEventHandler(esdInputHandler);
+    }
+
+    if (useKine)
+    {
+      AliMCEventHandler* mcInputHandler = dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+
+      if (!mcInputHandler)
+      {
+        Info("CustomAnalysisTaskInputSetup", "Creating mcInputHandler ...");
+        AliMCEventHandler* mcInputHandler = new AliMCEventHandler();
+        mgr->SetMCtruthEventHandler(mcInputHandler);
+      }
+    }
+
+  }
+  else if (!format.CompareTo("aod"))
+  {
+    AliAODInputHandler *aodInputHandler = dynamic_cast<AliAODInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+    if (!aodInputHandler)
+    {
+      Info("CustomAnalysisTaskInputSetup", "Creating aodInputHandler ...");
+      aodInputHandler = new AliAODInputHandler();
+      mgr->SetInputEventHandler(aodInputHandler);
+    }
+  }
+  else
+  {
+    Info("Wrong input format!!! Only ESD and AOD are supported. Skipping Task ...");
+    return kFALSE;
+  }
+
+  return kTRUE;
+}
+
+void MixHandlerSetup(float ntMin,float ntMax,float ntMixBinSz,
+                    float zMin, float zMax, float zMixBinSz)
+{
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) return;
+  int bufferSize = 1;
+  AliESDInputHandlerRP *esdH = dynamic_cast<AliESDInputHandlerRP*>(mgr->GetInputEventHandler());
+  if (!esdH) return;
+  //
+  AliMixEventInputHandler *esdMixH = new AliMixEventInputHandler(bufferSize);
+  esdMixH->SetInputHandlerForMixing(esdH);
+  AliMixEventPool *evPool = new AliMixEventPool("MyPool");
+  AliMixEventCutObj *tracklets = new AliMixEventCutObj(AliMixEventCutObj::kNumberTracklets, ntMin,ntMax,ntMixBinSz);
+  AliMixEventCutObj *zvertex = new AliMixEventCutObj(AliMixEventCutObj::kZVertex, zMin,zMax, zMixBinSz);
+  //  evPool->AddCut(tracklets);
+  evPool->AddCut(zvertex);
+  //evPool->Init();
+  evPool->Print();
+  esdMixH->SetEventPool(evPool);
+  esdH->SetMixingHandler(esdMixH);
+}
+
+void AddPhysicsSelection(Bool_t isMC)
+{
+  // physics selection a la Michele
+  printf("Requesting physics selection in %s mode\n",isMC ? "MC":"Data");
+  gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+  //isMC is true when processing monte carlo, the second 0 disables the cluster vs tracklets
+  AliPhysicsSelectionTask* physicsSelectionTask = AddTaskPhysicsSelection(isMC,0);
+  if(!isMC) {
+    AliPhysicsSelection * physSel = physicsSelectionTask->GetPhysicsSelection();
+    physSel->AddCollisionTriggerClass("+CMBAC-B-NOPF-ALL");
+    /*
+    physSel->AddCollisionTriggerClass("+CMBS1C-B-NOPF-ALL");
+    physSel->AddCollisionTriggerClass("+CMBS1A-B-NOPF-ALL");
+    */
+    //
+    physSel->AddCollisionTriggerClass("+CMBS2C-B-NOPF-ALL");
+    physSel->AddCollisionTriggerClass("+CMBS2A-B-NOPF-ALL");
+    //
+    // This are needed only to fill the statistics tables
+    physSel->AddBGTriggerClass("+CMBAC-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBAC-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBAC-E-NOPF-ALL");
+    //
+    /*
+    physSel->AddBGTriggerClass("+CMBS1C-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1C-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1C-E-NOPF-ALL");
+    //
+    physSel->AddBGTriggerClass("+CMBS1A-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1A-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1A-E-NOPF-ALL");
+    //
+    */
+    /*
+    //
+    physSel->AddBGTriggerClass("+CMBS2C-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2C-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2C-E-NOPF-ALL");
+    //
+    physSel->AddBGTriggerClass("+CMBS2A-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2A-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2A-E-NOPF-ALL");
+    */
+  } 
+  // if you use the following line, your task only gets the selected events
+  //  task->SelectCollisionCandidates(AliVEvent::kUserDefined);
+  //
+  //Alternatively, in the UserExec of your task:
+  //Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kUserDefined);
+  //
+}
diff --git a/PWG0/multVScentPbPb/MyAnalysisMacroTrackletMulti.C b/PWG0/multVScentPbPb/MyAnalysisMacroTrackletMulti.C
new file mode 100755 (executable)
index 0000000..9a04488
--- /dev/null
@@ -0,0 +1,288 @@
+void MyAnalysisMacroTrackletMulti
+(TString dataset="/alice/sim/LHC10f8c_130844",
+ TString outFName = "trbg.root",
+ Int_t   nEvents   = -1,
+ Float_t etaCut     = 0.5,        // max |eta| range to fill in histos
+ Float_t zMin       = -7,         // process events with Z vertex min
+ Float_t zMax       =  7,         //                     max positions
+ Int_t   useCentVar = 0,          // centrality variable to use: 0=V0, 1=SPD2corr
+ //
+ Float_t cutSigNStd  = 1.5,        // cut on weighed distance used to extract signal
+ Float_t cutSigDPhiS = -1,        // cut on dPhi-phiBent used to extract signal (if negative -> dphi*sqrt(cutSigNStd)
+ Bool_t  useMC  = kTRUE,          // fill MC info (doRec=kTRUE)
+ Float_t scaleMCV0 = 0.7520,      // rescale MC V0 to match the data
+ //
+ Bool_t doRec  = kTRUE,           // fill data histos from new reco
+ Bool_t doInj  = kTRUE,           // create Inj. bg
+ Bool_t doRot  = kFALSE,          // create Rot. bg
+ Bool_t doMix  = kFALSE,//kTRUE,  // create Mix. bg
+ // 
+ // specific parameters for reconstruction
+ float  phiRot      = 3.14159e+00, // angle for bg. generation with rotation
+ float  injScale    = 1.,//0.7,    // inject injScale*Ncl(Lr1/Lr2) hits
+ Bool_t scaleDTheta = kTRUE,       // scale dTheta by 1/sin^2(theta) in trackleting
+ float  nStdDev     = 25.,         // number of st.dev. for tracklet cut to keep
+ float  dphi        = 0.06,        // dphi window (sigma of tracklet cut)
+ float  dtht        = 0.025,       // dtheta .... (if negative, abs will be used with additional cut on |dthetaX|, apart from w.distance
+ float  phishift    = 0.0045,      // bending shift
+ Bool_t remOvl      = kTRUE,       
+ float  ovlPhiCut   = 0.005, 
+ float  ovlZetaCut  = 0.05,
+ Int_t  nEventsSkip = 0,
+ //----------------------- Ntracklets selection parameters important for mixing, to be tuned
+ Float_t ntMin      =   1,         // process events with ESDmult 
+ Float_t ntMax      = 20000,       // within this range
+ Float_t ntMixBinSz = 20000,       // ESDMult bin size for mixing
+ //----------------------- Zv selection parameters important for mixing, to be tuned
+ Float_t zMixBinSz  =  14,       //0.1,  // Zv. bin for mixing
+ //---------------------------------------------------------------------------------
+ //
+ Bool_t checkReconstructables = kFALSE//kTRUE, // fill histos for reconstructable (needs useMC and doRec) 
+ //
+ )
+{
+  //  
+  if (cutSigDPhiS<0) cutSigDPhiS = TMath::Sqrt(cutSigNStd)*dphi;
+  //
+  printf("Start Analysis for %s, max %d Events skipping %d, Event Cuts: |eta|<%.1f, %.2f<Zv<%.2f\n",
+        dataset.Data(),nEvents,nEventsSkip,etaCut,zMin,zMax);
+  printf("Centrality variable: %d\n",useCentVar);
+  printf("Tracklet cuts: dPhi:%.3f dTheta:%.3f phiShift:%.4f | Keep %.1f NstDev\n"
+        "Scale dTheta: %s | Signal Selection: NstDev:%.1f, dPhiS: %.3f\n", 
+        dphi,dtht,phishift,nStdDev,scaleDTheta ? "ON":"OFF",
+        cutSigNStd,cutSigDPhiS);
+  //
+  printf("UseMC: %s. V0 scale: %.4f\n",useMC ? "ON":"OFF",scaleMCV0);
+  printf("Operations:  \n"
+        "Reco:%s (RemOvl:%s phi:%.3f zeta:%.3f)\n"
+        "Inj:%s (scale: %.2f)\n"
+        "Rot:%s (phi: %.4f)\n"
+        "Mix:%s (Nt:%.1f:%.1f:%.1f Zv:%.1f:%.1f:%.2f)\n", 
+        doRec ? "ON":"OFF",remOvl? "ON":"OFF",ovlPhiCut,ovlZetaCut,
+        doInj ? "ON":"OFF",injScale,
+        doRot ? "ON":"OFF",phiRot,
+        doMix ? "ON":"OFF",ntMin,ntMax,ntMixBinSz, zMin,zMax,zMixBinSz);
+  //
+  if (nEvents<0) nEvents = int(1e9);
+  TString format = GetFormatFromDataSet(dataset);
+  //
+  // ALICE stuff
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) mgr = new AliAnalysisManager("Test train");
+  //
+  InputHandlerSetup(format,useMC);
+  if (doMix) MixHandlerSetup(ntMin,ntMax,ntMixBinSz, zMin,zMax,zMixBinSz);
+  // compile our task
+  gProof->Load("AliITSMultRecBg.cxx++");
+  gProof->Load("AliTrackletTaskMulti.cxx++");
+  //
+  // load and run AddTask macro
+  gROOT->LoadMacro("AddMultTaskTrackletMulti.C");
+  //
+  // create our task
+  AliTrackletTaskMulti *mltTask = AddMultTaskTrackletMulti(outFName.Data());
+  //
+  mltTask->SetUseCentralityVar(useCentVar);
+  mltTask->SetDoNormalReco(doRec);
+  mltTask->SetDoInjection(doInj);
+  mltTask->SetDoRotation(doRot);
+  mltTask->SetDoMixing(doMix);  
+  //
+  mltTask->SetUseMC(useMC);
+  mltTask->SetCheckReconstructables(checkReconstructables);
+  //
+  mltTask->SetEtaCut(etaCut);
+  mltTask->SetZVertexMin(zMin);
+  mltTask->SetZVertexMax(zMax);
+  //
+  mltTask->SetDPhiSCut(cutSigDPhiS);
+  mltTask->SetNStdCut(cutSigNStd);
+  mltTask->SetScaleMCV0(scaleMCV0);
+  //
+  mltTask->SetScaleDThetaBySin2T(scaleDTheta);
+  mltTask->SetNStdDev(nStdDev);
+  mltTask->SetPhiWindow(dphi);
+  mltTask->SetThetaWindow(dtht);
+  mltTask->SetPhiShift(phishift);
+  mltTask->SetPhiOverlapCut(ovlPhiCut);
+  mltTask->SetZetaOverlapCut(ovlZetaCut);
+  mltTask->SetPhiRot(phiRot);
+  mltTask->SetInjScale(injScale);
+  mltTask->SetRemoveOverlaps(remOvl);
+  //
+  printf("new Task: %p\n",mltTask);
+  //
+  AddPhysicsSelection(useMC);
+  mltTask->SelectCollisionCandidates(useMC ? (AliVEvent::kMB) : (AliVEvent::kUserDefined) );
+  //mltTask->SelectCollisionCandidates();//AliVEvent::kMB);
+  //
+  // Run analysis
+  mgr->InitAnalysis();
+  // process dataset  
+  mgr->StartAnalysis("proof", dataset.Data(), nEvents, nEventsSkip); 
+  //
+  TString evstCmd = "if [ -e event_stat.root ]; then \nmv event_stat.root evstat_"; 
+  evstCmd += outFName;  evstCmd += " \nfi";
+  gSystem->Exec( evstCmd.Data() );
+  
+}
+
+
+TString GetFormatFromDataSet(TString dataset) {
+  
+//   Info("runAAF.C","Detecting format from dataset (may take while, depends on network connection)...");
+  TString dsTreeName;
+  if (dataset.Contains("#")) {
+    Info("runAAF.C",Form("Detecting format from dataset name '%s' ...",dataset.Data()));
+    dsTreeName=dataset(dataset.Last('#'),dataset.Length());
+  } else {
+    Info("runAAF.C",Form("Detecting format from dataset '%s' (may take while, depends on network connection) ...",dataset.Data()));
+    TFileCollection *ds = gProof->GetDataSet(dataset.Data());
+    if (!ds) {
+      Error(Form("Dataset %s doesn't exist on proof cluster!!!!",dataset.Data()));
+      return "";
+    }
+    dsTreeName = ds->GetDefaultTreeName();
+  }
+
+  if (dsTreeName.Contains("esdTree")) {
+    Info("runAAF.C","ESD input format detected ...");
+    return "ESD";
+  } else if (dsTreeName.Contains("aodTree"))  {
+    Info("runAAF.C","AOD input format detected ...");
+    return "AOD";
+  } else {
+    Error("runAAF.C",Form("Tree %s is not supported !!!",dsTreeName.Data()));
+    Error("runAAF.C",Form("Maybe set your DS to %s#esdTree or %s#aodTree",dataset.Data(),dataset.Data()));
+  }
+  
+  return "";
+}
+
+Bool_t InputHandlerSetup(TString format = "esd", Bool_t useKine = kTRUE)
+{
+  format.ToLower();
+
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+
+  AliAnalysisDataContainer *cin = mgr->GetCommonInputContainer();
+
+  if (cin) return;
+
+  if (!format.CompareTo("esd"))
+  {
+    AliESDInputHandler *esdInputHandler = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+    if (!esdInputHandler)
+    {
+      Info("CustomAnalysisTaskInputSetup", "Creating esdInputHandler ...");
+      esdInputHandler = new AliESDInputHandlerRP();
+      mgr->SetInputEventHandler(esdInputHandler);
+    }
+
+    if (useKine)
+    {
+      AliMCEventHandler* mcInputHandler = dynamic_cast<AliMCEventHandler*>(AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+
+      if (!mcInputHandler)
+      {
+        Info("CustomAnalysisTaskInputSetup", "Creating mcInputHandler ...");
+        AliMCEventHandler* mcInputHandler = new AliMCEventHandler();
+        mgr->SetMCtruthEventHandler(mcInputHandler);
+      }
+    }
+
+  }
+  else if (!format.CompareTo("aod"))
+  {
+    AliAODInputHandler *aodInputHandler = dynamic_cast<AliAODInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+
+    if (!aodInputHandler)
+    {
+      Info("CustomAnalysisTaskInputSetup", "Creating aodInputHandler ...");
+      aodInputHandler = new AliAODInputHandler();
+      mgr->SetInputEventHandler(aodInputHandler);
+    }
+  }
+  else
+  {
+    Info("Wrong input format!!! Only ESD and AOD are supported. Skipping Task ...");
+    return kFALSE;
+  }
+
+  return kTRUE;
+}
+
+void MixHandlerSetup(float ntMin,float ntMax,float ntMixBinSz,
+                    float zMin, float zMax, float zMixBinSz)
+{
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if (!mgr) return;
+  int bufferSize = 1;
+  AliESDInputHandlerRP *esdH = dynamic_cast<AliESDInputHandlerRP*>(mgr->GetInputEventHandler());
+  if (!esdH) return;
+  //
+  AliMixEventInputHandler *esdMixH = new AliMixEventInputHandler(bufferSize);
+  esdMixH->SetInputHandlerForMixing(esdH);
+  AliMixEventPool *evPool = new AliMixEventPool("MyPool");
+  AliMixEventCutObj *tracklets = new AliMixEventCutObj(AliMixEventCutObj::kNumberTracklets, ntMin,ntMax,ntMixBinSz);
+  AliMixEventCutObj *zvertex = new AliMixEventCutObj(AliMixEventCutObj::kZVertex, zMin,zMax, zMixBinSz);
+  //  evPool->AddCut(tracklets);
+  evPool->AddCut(zvertex);
+  //evPool->Init();
+  evPool->Print();
+  esdMixH->SetEventPool(evPool);
+  esdH->SetMixingHandler(esdMixH);
+}
+
+void AddPhysicsSelection(Bool_t isMC)
+{
+  // physics selection a la Michele
+  printf("Requesting physics selection in %s mode\n",isMC ? "MC":"Data");
+  gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
+  //isMC is true when processing monte carlo, the second 0 disables the cluster vs tracklets
+  AliPhysicsSelectionTask* physicsSelectionTask = AddTaskPhysicsSelection(isMC,0);
+  if(!isMC) {
+    AliPhysicsSelection * physSel = physicsSelectionTask->GetPhysicsSelection();
+    physSel->AddCollisionTriggerClass("+CMBAC-B-NOPF-ALL");
+    /*
+    physSel->AddCollisionTriggerClass("+CMBS1C-B-NOPF-ALL");
+    physSel->AddCollisionTriggerClass("+CMBS1A-B-NOPF-ALL");
+    */
+    //
+    physSel->AddCollisionTriggerClass("+CMBS2C-B-NOPF-ALL");
+    physSel->AddCollisionTriggerClass("+CMBS2A-B-NOPF-ALL");
+    //
+    // This are needed only to fill the statistics tables
+    physSel->AddBGTriggerClass("+CMBAC-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBAC-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBAC-E-NOPF-ALL");
+    //
+    /*
+    physSel->AddBGTriggerClass("+CMBS1C-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1C-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1C-E-NOPF-ALL");
+    //
+    physSel->AddBGTriggerClass("+CMBS1A-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1A-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS1A-E-NOPF-ALL");
+    //
+    */
+    /*
+    //
+    physSel->AddBGTriggerClass("+CMBS2C-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2C-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2C-E-NOPF-ALL");
+    //
+    physSel->AddBGTriggerClass("+CMBS2A-C-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2A-A-NOPF-ALL");
+    physSel->AddBGTriggerClass("+CMBS2A-E-NOPF-ALL");
+    */
+  } 
+  // if you use the following line, your task only gets the selected events
+  //  task->SelectCollisionCandidates(AliVEvent::kUserDefined);
+  //
+  //Alternatively, in the UserExec of your task:
+  //Bool_t isSelected = (((AliInputEventHandler*)(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()))->IsEventSelected() & AliVEvent::kUserDefined);
+  //
+}
diff --git a/PWG0/multVScentPbPb/README b/PWG0/multVScentPbPb/README
new file mode 100644 (file)
index 0000000..0dd0f72
--- /dev/null
@@ -0,0 +1,42 @@
+dN/dEta analysis can be done in 2 ways:
+
+1) For single centrality bin:
+Using AliTrackletTaskUni.{h,cxx} steered by the
+runAAF.C and MyAnalysisMacro.C
+
+It will produce a file with 3D (sparse) histos "delta" vs Zv vs eta
+where delta is either "weigted distance" and/or "dphi - bend", which is used
+both the match the tails and to define the signal cut.
+The exact value of cut can be decided at the stage of processing the histos,
+so different signal and tail matching thresholds can be tested 
+
+Note that wide Zv eta range can be processed and then restricted at 
+the correction stage.
+
+One has to run runAAF.C for over the data and MC datasets and then analyse them
+using the CorrectSpectra.C macro (the cuts/variables use... must be set 
+beforehand)
+
+
+2) Mor multiple centrality bins at once:
+AliTrackletTaskMulti.{h,cxx} steered by the 
+runAAFMulti.C and MyAnalysisMacroTrackletMulti.C
+
+It produces for each centrality bin a set of histos, particularly 2D histos for
+Zv vs eta with the signal cut on "distance" already applied (by defaults one for 
+"w.dist" another for "dphi-bend" + 1D histo of "distance" for selected Zv,eta
+range (to be used for the bg matching the tails of data"
+
+Note: Zv, eta ranges must be defined at data processing stage, as well as the 
+signal cut (cutSigNStd in the runAAFMulti) and number of st.dev to keep (nStdDev)
+
+One has to runAAFMulti.C for over the data and MC datasets and then analyse them
+using the CorrectSpectraMulti.C macro 
+
+--------------------------------
+Both methods can use 3 types of generated bg: injection, rotation and mixing.
+Simultaneous eployment of all these methods is also possible, but may create 
+a memory problem.
+
+The corresponding CorrectSpectra... macros must be tuned for the bg.type used.
+
diff --git a/PWG0/multVScentPbPb/runAAF.C b/PWG0/multVScentPbPb/runAAF.C
new file mode 100755 (executable)
index 0000000..cc47f5d
--- /dev/null
@@ -0,0 +1,114 @@
+//
+void runAAF(TString dataset="/alice/sim/LHC10f8c_130844",
+           TString outFName = "trbg.root",
+           Bool_t doRec  = kTRUE,           // fill data histos from new reco
+           Bool_t doInj  = kTRUE,           // create Inj. bg
+           Bool_t doRot  = kTRUE,           // create Rot. bg
+           Bool_t doMix  = kFALSE,//kTRUE,  // create Mix. bg
+           Bool_t useMC  = kTRUE,           // fill MC info (doRec=kTRUE)
+           Bool_t checkReconstructables = kFALSE,//kTRUE, // fill histos for reconstructable (needs useMC and doRec) 
+           // 
+           Float_t etaCut     = 3.0,        // max |eta| range to fill in histos
+           //
+           // specific parameters for reconstruction
+           //----------------------- Zv selection parameters important for mixing, to be tuned
+           Float_t zMin       = -20,        // process events with Z vertex min
+           Float_t zMax       =  20,        //                     max positions
+           Float_t zMixBinSz  =  20, //0.1,  // Zv. bin for mixing
+           //---------------------------------------------------------------------------------
+           //
+           //----------------------- Ntracklets selection parameters important for mixing, to be tuned
+           Float_t ntMin      =   1,         // process events with ESDmult 
+           Float_t ntMax      = 20000,       // within this range
+           Float_t ntMixBinSz = 20000,       // ESDMult bin size for mixing
+           //---------------------------------------------------------------------------------
+           float  phiRot      = 3.14159e+00, // angle for bg. generation with rotation
+           float  injScale    = 1.,//0.7,    // inject injScale*Ncl(Lr1/Lr2) hits
+           Bool_t scaleDTheta = kTRUE,       // scale dTheta by 1/sin^2(theta) in trackleting
+           float  nStdDev     = 25.,         // number of st.dev. for tracklet cut to keep
+           float  dphi        = 0.06,        // dphi window (sigma of tracklet cut)
+           float  dtht        = 0.025,       // dtheta .... (if negative, abs will be used with additional cut on |dthetaX|, apart from w.distance
+           float  phishift    = 0.0045,      // bending shift
+           Bool_t remOvl      = kTRUE,       
+           float  ovlPhiCut   = 0.005, 
+           float  ovlZetaCut  = 0.05,
+            Int_t  nEvents     = 50000000,
+           Int_t  nEventsSkip = 0,
+           TString alirootVer = "VO_ALICE@AliRoot::v4-21-05-AN",
+           TString rootVer    = "default",//"VO_ALICE@ROOT::v5-27-06b",
+           //
+           TString proofCluster="shahoian@alice-caf.cern.ch"
+           ) 
+{ 
+  //  
+  Bool_t runLocal = kFALSE; // true only for local test mode
+  if (runLocal) {
+    dataset = "/default/shahoian/test_pp";
+    //dataset = "/default/shahoian/test";
+    proofCluster = "";
+    alirootVer = "AliRootProofLite";
+    nEvents = 500;
+  }
+  //
+  if (dataset.Contains("alice/data") && useMC) {
+    printf("Running with read data dataset, switching OFF useMC\n");
+    useMC = kFALSE;
+  }
+  //
+  printf("Start Analysis for %s, max %d Events skipping %d\n"
+        "Event Cuts: |eta|<%.1f, %.2f<Zv<%.2f (Mix.Bin:%.2f), %.0f<Mult<%0.f (Mix.Bin:%.0f)\n"
+        "Reco:%d Inj:%d Rot:%d Mix:%d | MCinfo:%d CheckReconstructables:%d\n"
+        "PhiRot:%.4f InjScale:%.2f ScaleDTheta:%d NStdDev:%.1f DPhi:%.4f DTheta:%.4f PhiShift:%.4f\n"
+        "RemoveOverlaps:%d PhiOvl:%.4f ZEtaOvl:%.4f\n",
+        dataset.Data(),nEvents,nEventsSkip,
+        etaCut,zMin,zMax,zMixBinSz,ntMin,ntMax,ntMixBinSz,
+        doRec,doInj,doRot,doMix,useMC,checkReconstructables,
+        phiRot,injScale,scaleDTheta,nStdDev,dphi,dtht,phishift,
+        remOvl,ovlPhiCut,ovlZetaCut);
+  //
+  printf("Requested: %s %s\n",alirootVer.Data(), rootVer.Data());
+  printf("Output expected in %s\n",outFName.Data());
+  //
+  gEnv->SetValue("XSec.GSI.DelegProxy","2");
+  //
+  TString alirootMode="REC";
+  TString extraLibs = "ITSrec:CDB:Geom:"; // not needed in default aliroot mode
+  //extraLibs+= "ANALYSIS:ANALYSISalice";
+  extraLibs+= "ANALYSIS:ANALYSISalice:EventMixing";
+  TList *list = new TList();
+  // sets $ALIROOT_MODE on each worker to let proof to know to run in special mode
+  list->Add(new TNamed("ALIROOT_MODE"      , alirootMode.Data()));
+  list->Add(new TNamed("ALIROOT_EXTRA_LIBS", extraLibs.Data()));
+  list->Add(new TNamed("ALIROOT_ENABLE_ALIEN","1"));
+  //
+  //REM: same version of AliRoot on client!!!!! Otherwise error!! 
+  TProof::Mgr(proofCluster.Data())->SetROOTVersion(rootVer.Data());
+  TProof::Open(proofCluster.Data());//,"workers=10x");
+  //  TProof::Open(proofCluster.Data(),"workers=1x");
+  if (!gProof) {
+    Error("runAAF.C","Connection to AF failed.");
+    return;
+  }
+  gProof->Exec("TObject *o = gEnv->GetTable()->FindObject(\"Proof.UseMergers\");"
+              "gEnv->GetTable()->Remove(o);", kTRUE);
+  //  gProof->SetParameter("PROOF_UseMergers", 0);
+  // Lets enable aliroot + extra libs on proof cluster
+  if (runLocal) gProof->UploadPackage(alirootVer.Data());
+  gProof->EnablePackage(alirootVer.Data(), list);
+  //
+  gROOT->LoadMacro("MyAnalysisMacro.C");
+
+  if (runLocal) {
+    Int_t numWorkers = gProof->GetParallel();
+    if (numWorkers<1) {printf("No workers\n"); return;}
+    gProof->SetParameter("PROOF_PacketizerStrategy", (Int_t)0);
+    int frac = (Int_t) 5 / numWorkers;
+    if (frac<1) frac = 1;
+    gProof->SetParameter("PROOF_PacketAsAFraction", frac);
+  }
+  MyAnalysisMacro(dataset,outFName,doRec,doInj,doRot,doMix,useMC,checkReconstructables,
+                 etaCut,zMin,zMax,zMixBinSz,ntMin,ntMax,ntMixBinSz,
+                 phiRot,injScale,scaleDTheta,nStdDev,dphi,dtht,
+                 phishift,remOvl,ovlPhiCut,ovlZetaCut,nEvents,nEventsSkip);
+  //
+}
diff --git a/PWG0/multVScentPbPb/runAAFMulti.C b/PWG0/multVScentPbPb/runAAFMulti.C
new file mode 100755 (executable)
index 0000000..f958a98
--- /dev/null
@@ -0,0 +1,117 @@
+//
+void runAAFMulti(TString dataset="/alice/sim/LHC10h6_000137161",
+                TString outFName = "trbg.root",
+                Int_t   nEvents    = -1,//3000,
+                Float_t etaCut     = 0.5,        // max |eta| range to fill in histos
+                Float_t zMin       = -7,         // process events with Z vertex min
+        &nb