]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGHF/vertexingHF/AliRDHFCuts.cxx
Set specific flag to decide whether to use the multiplicity distributions or their...
[u/mrichter/AliRoot.git] / PWGHF / vertexingHF / AliRDHFCuts.cxx
index 2b92869eaca5ecd41e37df1600762687bc4774b4..ace5f0bc8b2a499520822247508b7076fce8b655 100644 (file)
 #include "AliAnalysisManager.h"
 #include "AliInputEventHandler.h"
 #include "AliPIDResponse.h"
+#include "AliAnalysisUtils.h"
+#include "TRandom.h"
+#include <TF1.h>
+
+using std::cout;
+using std::endl;
 
 ClassImp(AliRDHFCuts)
 
@@ -56,7 +62,6 @@ fMaxVtxZ(10.),
 fMinSPDMultiplicity(0),
 fTriggerMask(AliVEvent::kAnyINT),
 fUseOnlyOneTrigger(kFALSE),
-fTriggerClass("CINT1"),
 fTrackCuts(0),
 fnPtBins(1),
 fnPtBinLimits(1),
@@ -88,13 +93,28 @@ fIsSelectedCuts(0),
 fIsSelectedPID(0),
 fMinPtCand(-1.),
 fMaxPtCand(100000.),
+fMaxRapidityCand(-999.),
 fKeepSignalMC(kFALSE),
 fIsCandTrackSPDFirst(kFALSE),
-fMaxPtCandTrackSPDFirst(0.)
+fMaxPtCandTrackSPDFirst(0.),
+fApplySPDDeadPbPb2011(kFALSE),
+fApplySPDMisalignedPP2012(kFALSE),
+fMaxDiffTRKV0Centr(-1.),
+fRemoveTrackletOutliers(kFALSE),
+fCutOnzVertexSPD(0),
+fKinkReject(kFALSE),
+fUseTrackSelectionWithFilterBits(kTRUE),
+fUseCentrFlatteningInMC(kFALSE),
+fHistCentrDistr(0x0),
+fCutRatioClsOverCrossRowsTPC(0),
+fCutRatioSignalNOverCrossRowsTPC(0),
+fCutMinCrossedRowsTPCPtDep(""),
+f1CutMinNCrossedRowsTPCPtDep(0x0)
 {
   //
   // Default Constructor
   //
+  fTriggerClass[0]="CINT1"; fTriggerClass[1]="";
 }
 //--------------------------------------------------------------------------
 AliRDHFCuts::AliRDHFCuts(const AliRDHFCuts &source) :
@@ -106,7 +126,7 @@ AliRDHFCuts::AliRDHFCuts(const AliRDHFCuts &source) :
   fMinSPDMultiplicity(source.fMinSPDMultiplicity),
   fTriggerMask(source.fTriggerMask),
   fUseOnlyOneTrigger(source.fUseOnlyOneTrigger),
-  fTriggerClass(source.fTriggerClass),
+  fTriggerClass(),
   fTrackCuts(0),
   fnPtBins(source.fnPtBins),
   fnPtBinLimits(source.fnPtBinLimits),
@@ -138,20 +158,39 @@ AliRDHFCuts::AliRDHFCuts(const AliRDHFCuts &source) :
   fIsSelectedPID(source.fIsSelectedPID),
   fMinPtCand(source.fMinPtCand),
   fMaxPtCand(source.fMaxPtCand),
+  fMaxRapidityCand(source.fMaxRapidityCand),
   fKeepSignalMC(source.fKeepSignalMC),
   fIsCandTrackSPDFirst(source.fIsCandTrackSPDFirst),
-  fMaxPtCandTrackSPDFirst(source.fMaxPtCandTrackSPDFirst)
+  fMaxPtCandTrackSPDFirst(source.fMaxPtCandTrackSPDFirst),
+  fApplySPDDeadPbPb2011(source.fApplySPDDeadPbPb2011),
+  fApplySPDMisalignedPP2012(source.fApplySPDMisalignedPP2012),
+  fMaxDiffTRKV0Centr(source.fMaxDiffTRKV0Centr),
+  fRemoveTrackletOutliers(source.fRemoveTrackletOutliers),
+  fCutOnzVertexSPD(source.fCutOnzVertexSPD),
+  fKinkReject(source.fKinkReject),
+  fUseTrackSelectionWithFilterBits(source.fUseTrackSelectionWithFilterBits),
+  fUseCentrFlatteningInMC(source.fUseCentrFlatteningInMC),
+  fHistCentrDistr(0x0),
+  fCutRatioClsOverCrossRowsTPC(source.fCutRatioClsOverCrossRowsTPC),
+  fCutRatioSignalNOverCrossRowsTPC(source.fCutRatioSignalNOverCrossRowsTPC),
+  fCutMinCrossedRowsTPCPtDep(""),
+  f1CutMinNCrossedRowsTPCPtDep(0x0)
 {
   //
   // Copy constructor
   //
   cout<<"Copy constructor"<<endl;
+  fTriggerClass[0] = source.fTriggerClass[0]; 
+  fTriggerClass[1] = source.fTriggerClass[1];
   if(source.GetTrackCuts()) AddTrackCuts(source.GetTrackCuts());
   if(source.fPtBinLimits) SetPtBins(source.fnPtBinLimits,source.fPtBinLimits);
   if(source.fVarNames) SetVarNames(source.fnVars,source.fVarNames,source.fIsUpperCut);
   if(source.fCutsRD) SetCuts(source.fGlobalIndex,source.fCutsRD);
   if(source.fVarsForOpt) SetVarsForOpt(source.fnVarsForOpt,source.fVarsForOpt);
   if(source.fPidHF) SetPidHF(source.fPidHF);
+  if(source.fHistCentrDistr) fHistCentrDistr=(TH1F*)(source.fHistCentrDistr->Clone());
+  if(source.fCutMinCrossedRowsTPCPtDep) fCutMinCrossedRowsTPCPtDep=source.fCutMinCrossedRowsTPCPtDep;
+  if(source.f1CutMinNCrossedRowsTPCPtDep) f1CutMinNCrossedRowsTPCPtDep=new TFormula(*(source.f1CutMinNCrossedRowsTPCPtDep));
   PrintAll();
 
 }
@@ -172,7 +211,8 @@ AliRDHFCuts &AliRDHFCuts::operator=(const AliRDHFCuts &source)
   fMinSPDMultiplicity=source.fMinSPDMultiplicity;
   fTriggerMask=source.fTriggerMask;
   fUseOnlyOneTrigger=source.fUseOnlyOneTrigger;
-  fTriggerClass=source.fTriggerClass;
+  fTriggerClass[0]=source.fTriggerClass[0];
+  fTriggerClass[1]=source.fTriggerClass[1];
   fnPtBins=source.fnPtBins;
   fnPtBinLimits=source.fnPtBinLimits;
   fnVars=source.fnVars;
@@ -199,15 +239,32 @@ AliRDHFCuts &AliRDHFCuts::operator=(const AliRDHFCuts &source)
   fIsSelectedPID=source.fIsSelectedPID;
   fMinPtCand=source.fMinPtCand;
   fMaxPtCand=source.fMaxPtCand;
+  fMaxRapidityCand=source.fMaxRapidityCand;
   fKeepSignalMC=source.fKeepSignalMC;
   fIsCandTrackSPDFirst=source.fIsCandTrackSPDFirst;
   fMaxPtCandTrackSPDFirst=source.fMaxPtCandTrackSPDFirst;
+  fApplySPDDeadPbPb2011=source.fApplySPDDeadPbPb2011;
+  fApplySPDMisalignedPP2012=source.fApplySPDMisalignedPP2012;
+  fMaxDiffTRKV0Centr=source.fMaxDiffTRKV0Centr;
+  fRemoveTrackletOutliers=source.fRemoveTrackletOutliers;
+  fCutOnzVertexSPD=source.fCutOnzVertexSPD;
+  fKinkReject=source.fKinkReject;
+  fUseTrackSelectionWithFilterBits=source.fUseTrackSelectionWithFilterBits;
+  if(fHistCentrDistr) delete fHistCentrDistr;
+  fUseCentrFlatteningInMC=source.fUseCentrFlatteningInMC;
+  if(source.fHistCentrDistr)fHistCentrDistr=(TH1F*)(source.fHistCentrDistr->Clone());
 
   if(source.GetTrackCuts()) {delete fTrackCuts; fTrackCuts=new AliESDtrackCuts(*(source.GetTrackCuts()));}
   if(source.fPtBinLimits) SetPtBins(source.fnPtBinLimits,source.fPtBinLimits);
   if(source.fVarNames) SetVarNames(source.fnVars,source.fVarNames,source.fIsUpperCut);
   if(source.fCutsRD) SetCuts(source.fGlobalIndex,source.fCutsRD);
   if(source.fVarsForOpt) SetVarsForOpt(source.fnVarsForOpt,source.fVarsForOpt);
+  
+  if(fCutMinCrossedRowsTPCPtDep) fCutMinCrossedRowsTPCPtDep=source.fCutMinCrossedRowsTPCPtDep;
+  if(f1CutMinNCrossedRowsTPCPtDep) delete f1CutMinNCrossedRowsTPCPtDep;
+  if(source.f1CutMinNCrossedRowsTPCPtDep) f1CutMinNCrossedRowsTPCPtDep=new TFormula(*(source.f1CutMinNCrossedRowsTPCPtDep));
+  fCutRatioClsOverCrossRowsTPC=source.fCutRatioClsOverCrossRowsTPC;
+  fCutRatioSignalNOverCrossRowsTPC=source.fCutRatioSignalNOverCrossRowsTPC;
   PrintAll();
 
   return *this;
@@ -217,6 +274,7 @@ AliRDHFCuts::~AliRDHFCuts() {
   //  
   // Default Destructor
   //
+  if(fTrackCuts) { delete fTrackCuts; fTrackCuts=0; }
   if(fPtBinLimits) {delete [] fPtBinLimits; fPtBinLimits=0;}
   if(fVarNames) {delete [] fVarNames; fVarNames=0;}
   if(fVarsForOpt) {delete [] fVarsForOpt; fVarsForOpt=0;}
@@ -229,6 +287,13 @@ AliRDHFCuts::~AliRDHFCuts() {
     delete fPidHF;
     fPidHF=0;
   }
+  if(fHistCentrDistr)delete fHistCentrDistr;
+
+  if(f1CutMinNCrossedRowsTPCPtDep) {
+    delete f1CutMinNCrossedRowsTPCPtDep;
+    f1CutMinNCrossedRowsTPCPtDep = 0;
+  }
+
 }
 //---------------------------------------------------------------------------
 Int_t AliRDHFCuts::IsEventSelectedInCentrality(AliVEvent *event) {
@@ -245,11 +310,142 @@ Int_t AliRDHFCuts::IsEventSelectedInCentrality(AliVEvent *event) {
     }else{      
       if (centvalue<fMinCentrality || centvalue>fMaxCentrality){
        return 2;      
-      }    
+      }
+      // selection to flatten the centrality distribution
+      if(fHistCentrDistr){
+       if(!IsEventSelectedForCentrFlattening(centvalue))return 4;     
+      }
     } 
   }  
   return 0;
 }
+
+
+//-------------------------------------------------
+void AliRDHFCuts::SetHistoForCentralityFlattening(TH1F *h,Double_t minCentr,Double_t maxCentr,Double_t centrRef,Int_t switchTRand){
+  // set the histo for centrality flattening 
+  // the centrality is flatten in the range minCentr,maxCentr
+  // if centrRef is zero, the minimum in h within (minCentr,maxCentr) defines the reference 
+  //                positive, the value of h(centrRef) defines the reference (-> the centrality distribution might be not flat in the whole desired range)
+  //                negative, h(bin with max in range)*centrRef is used to define the reference (-> defines the maximum loss of events, also in this case the distribution might be not flat) 
+  // switchTRand is used to set the unerflow bin of the histo: if it is < -1 in the analysis the random event selection will be done on using TRandom 
+  
+  if(maxCentr<minCentr){
+    AliWarning("AliRDHFCuts::Wrong centralities values while setting the histogram for centrality flattening");
+  }
+  
+  if(fHistCentrDistr)delete fHistCentrDistr;
+  fHistCentrDistr=(TH1F*)h->Clone("hCentralityFlat");
+  fHistCentrDistr->SetTitle("Reference histo for centrality flattening");
+  Int_t minbin=fHistCentrDistr->FindBin(minCentr*1.00001); // fast if fix bin width
+  Int_t maxbin=fHistCentrDistr->FindBin(maxCentr*0.9999);
+  fHistCentrDistr->GetXaxis()->SetRange(minbin,maxbin);
+  Double_t ref=0.,bincont=0.,binrefwidth=1.;
+  Int_t binref=0;
+  if(TMath::Abs(centrRef)<0.0001){
+    binref=fHistCentrDistr->GetMinimumBin();
+    binrefwidth=fHistCentrDistr->GetBinWidth(binref);
+    ref=fHistCentrDistr->GetBinContent(binref)/binrefwidth;   
+  }
+  else if(centrRef>0.){
+    binref=h->FindBin(centrRef);
+    if(binref<1||binref>h->GetNbinsX()){
+      AliWarning("AliRDHFCuts::Wrong centrality reference value while setting the histogram for centrality flattening");
+    }
+    binrefwidth=fHistCentrDistr->GetBinWidth(binref);
+    ref=fHistCentrDistr->GetBinContent(binref)/binrefwidth;
+  }
+  else{
+    if(centrRef<-1) AliWarning("AliRDHFCuts: with this centrality reference no flattening will be applied");
+    binref=fHistCentrDistr->GetMaximumBin();
+    binrefwidth=fHistCentrDistr->GetBinWidth(binref);
+    ref=fHistCentrDistr->GetMaximum()*TMath::Abs(centrRef)/binrefwidth;   
+  }
+  
+  for(Int_t j=1;j<=h->GetNbinsX();j++){// Now set the "probabilities"
+    if(h->GetBinLowEdge(j)*1.0001>=minCentr&&h->GetBinLowEdge(j+1)*0.9999<=maxCentr){
+      bincont=h->GetBinContent(j);
+      fHistCentrDistr->SetBinContent(j,ref/bincont*h->GetBinWidth(j));
+      fHistCentrDistr->SetBinError(j,h->GetBinError(j)*ref/bincont);
+    }
+    else{
+      h->SetBinContent(j,1.1);// prob > 1 to assure that events will not be rejected
+    }
+  }
+
+  fHistCentrDistr->SetBinContent(0,switchTRand);
+  return;
+
+}
+
+//-------------------------------------------------
+Bool_t AliRDHFCuts::IsEventSelectedForCentrFlattening(Float_t centvalue){
+  //
+  //  Random event selection, based on fHistCentrDistr, to flatten the centrality distribution
+  //  Can be faster if it was required that fHistCentrDistr covers
+  //  exactly the desired centrality range (e.g. part of the lines below should be done during the 
+  // setting of the histo) and TH1::SetMinimum called 
+  //
+
+  if(!fHistCentrDistr) return kTRUE;
+  // Int_t maxbin=fHistCentrDistr->FindBin(fMaxCentrality*0.9999);
+  //   if(maxbin>fHistCentrDistr->GetNbinsX()){
+  //     AliWarning("AliRDHFCuts: The maximum centrality exceeds the x-axis limit of the histogram for centrality flattening");
+  //   }
+  
+  Int_t bin=fHistCentrDistr->FindBin(centvalue); // Fast if the histo has a fix bin
+  Double_t bincont=fHistCentrDistr->GetBinContent(bin);
+  Double_t centDigits=centvalue-(Int_t)(centvalue*100.)/100.;// this is to extract a random number between 0 and 0.01
+  
+  if(fHistCentrDistr->GetBinContent(0)<-0.9999){
+    if(gRandom->Uniform(1.)<bincont)return kTRUE;
+    return kFALSE;
+  }
+
+  if(centDigits*100.<bincont)return kTRUE;
+  return kFALSE;   
+
+}
+//---------------------------------------------------------------------------
+void AliRDHFCuts::SetupPID(AliVEvent *event) {
+  // Set the PID response object in the AliAODPidHF
+  // in case of old PID sets the TPC dE/dx BB parameterization
+
+  if(fPidHF){
+    if(fPidHF->GetPidResponse()==0x0){
+      AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+      AliInputEventHandler *inputHandler=(AliInputEventHandler*)mgr->GetInputEventHandler();
+      AliPIDResponse *pidResp=inputHandler->GetPIDResponse();
+      fPidHF->SetPidResponse(pidResp);
+    }
+    if(fPidHF->GetUseCombined()) fPidHF->SetUpCombinedPID();
+    if(fPidHF->GetOldPid()) {
+
+      Bool_t isMC=kFALSE;
+      TClonesArray *mcArray = (TClonesArray*)((AliAODEvent*)event)->GetList()->FindObject(AliAODMCParticle::StdBranchName());
+      if(mcArray) {isMC=kTRUE;fUseAOD049=kFALSE;}
+
+      // pp, from LHC10d onwards
+      if((event->GetRunNumber()>121693 && event->GetRunNumber()<136851) ||
+        event->GetRunNumber()>139517) fPidHF->SetOnePad(kTRUE);
+      // pp, 2011 low energy run
+      if((event->GetRunNumber()>=146686 && event->GetRunNumber()<=146860)){
+       fPidHF->SetppLowEn2011(kTRUE);
+       fPidHF->SetOnePad(kFALSE);
+      }
+      // PbPb LHC10h
+      if(event->GetRunNumber()>=136851 && event->GetRunNumber()<=139517) fPidHF->SetPbPb(kTRUE);
+      // MC
+      if(isMC) fPidHF->SetMC(kTRUE);
+      if(isMC && (event->GetRunNumber()>=146686 && event->GetRunNumber()<=146860))
+       fPidHF->SetMClowenpp2011(kTRUE);
+      fPidHF->SetBetheBloch();
+    }else{
+      // check that AliPIDResponse object was properly set in case of using OADB
+      if(fPidHF->GetPidResponse()==0x0) AliFatal("AliPIDResponse object not set");
+    }
+  }
+}
 //---------------------------------------------------------------------------
 Bool_t AliRDHFCuts::IsEventSelected(AliVEvent *event) {
   //
@@ -257,6 +453,8 @@ Bool_t AliRDHFCuts::IsEventSelected(AliVEvent *event) {
   // 
   //if(fTriggerMask && event->GetTriggerMask()!=fTriggerMask) return kFALSE;
 
+
+
   fWhyRejection=0;
   fEvRejectionBits=0;
   Bool_t accept=kTRUE;
@@ -274,45 +472,28 @@ Bool_t AliRDHFCuts::IsEventSelected(AliVEvent *event) {
   TClonesArray *mcArray = (TClonesArray*)((AliAODEvent*)event)->GetList()->FindObject(AliAODMCParticle::StdBranchName());
   if(mcArray) {isMC=kTRUE;fUseAOD049=kFALSE;}
 
-  // settings for the TPC dE/dx BB parameterization
-  if(fPidHF && fPidHF->GetOldPid()) {
-    // pp, from LHC10d onwards
-    if((event->GetRunNumber()>121693 && event->GetRunNumber()<136851) ||
-       event->GetRunNumber()>139517) fPidHF->SetOnePad(kTRUE);
-    // pp, 2011 low energy run
-    if((event->GetRunNumber()>=146686 && event->GetRunNumber()<=146860)){
-      fPidHF->SetppLowEn2011(kTRUE);
-      fPidHF->SetOnePad(kFALSE);
-    }
-    // PbPb LHC10h
-    if(event->GetRunNumber()>=136851 && event->GetRunNumber()<=139517) fPidHF->SetPbPb(kTRUE);
-    // MC
-    if(isMC) fPidHF->SetMC(kTRUE);
-    if(isMC && (event->GetRunNumber()>=146686 && event->GetRunNumber()<=146860))
-      fPidHF->SetMClowenpp2011(kTRUE);
-    fPidHF->SetBetheBloch();
-  } 
-  else if(fPidHF && !fPidHF->GetOldPid()) {
-   if(fPidHF->GetPidResponse()==0x0){
-    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
-    AliInputEventHandler *inputHandler=(AliInputEventHandler*)mgr->GetInputEventHandler();
-    AliPIDResponse *pidResp=inputHandler->GetPIDResponse();
-    fPidHF->SetPidResponse(pidResp);
-   }
-  }
 
+  SetupPID(event);
 
   // trigger class
   TString firedTriggerClasses=((AliAODEvent*)event)->GetFiredTriggerClasses();
   // don't do for MC and for PbPb 2010 data
   if(!isMC && (event->GetRunNumber()<136851 || event->GetRunNumber()>139517)) {
-    if(!firedTriggerClasses.Contains(fTriggerClass.Data())) {
+    if(!firedTriggerClasses.Contains(fTriggerClass[0].Data()) && 
+       (fTriggerClass[1].CompareTo("")==0 || !firedTriggerClasses.Contains(fTriggerClass[1].Data())) ) {
       fWhyRejection=5;
       fEvRejectionBits+=1<<kNotSelTrigger;
       accept=kFALSE;
     }
   }
 
+  // TEMPORARY FIX FOR GetEvent
+  Int_t nTracks=((AliAODEvent*)event)->GetNTracks();
+  for(Int_t itr=0; itr<nTracks; itr++){
+    AliAODTrack* tr=(AliAODTrack*)((AliAODEvent*)event)->GetTrack(itr);
+    tr->SetAODEvent((AliAODEvent*)event);
+  }
+
   // TEMPORARY FIX FOR REFERENCES
   // Fix references to daughter tracks
   //  if(fFixRefs) {
@@ -369,6 +550,26 @@ Bool_t AliRDHFCuts::IsEventSelected(AliVEvent *event) {
     } 
   }
 
+  if(fCutOnzVertexSPD>0){
+    const AliVVertex *vSPD = ((AliAODEvent*)event)->GetPrimaryVertexSPD();
+    if(!vSPD || (vSPD && vSPD->GetNContributors()<fMinVtxContr)){
+      accept=kFALSE;
+      fEvRejectionBits+=1<<kBadSPDVertex;
+    }else{
+      if(fCutOnzVertexSPD==1 && TMath::Abs(vSPD->GetZ())>12.) {
+       fEvRejectionBits+=1<<kZVtxSPDOutFid;
+       if(accept) fWhyRejection=6;
+       accept=kFALSE;
+      } 
+      if(fCutOnzVertexSPD==2 && vertex){
+       if(TMath::Abs(vSPD->GetZ()-vertex->GetZ())>0.5) {
+         fEvRejectionBits+=1<<kZVtxSPDOutFid;
+         if(accept) fWhyRejection=6;
+         accept=kFALSE;
+       } 
+      }
+    }
+  }
 
   // pile-up rejection
   if(fOptPileup==kRejectPileupEvent){
@@ -376,7 +577,16 @@ Bool_t AliRDHFCuts::IsEventSelected(AliVEvent *event) {
     Double_t cutz=(Double_t)fMinDzPileup;
     if(event->IsPileupFromSPD(cutc,cutz,3.,2.,10.)) {
       if(accept) fWhyRejection=1;
-      fEvRejectionBits+=1<<kPileupSPD;
+      fEvRejectionBits+=1<<kPileup;
+      accept=kFALSE;
+    }
+  }
+  else if(fOptPileup==kRejectMVPileupEvent){
+    AliAnalysisUtils utils;
+    Bool_t isPUMV = utils.IsPileUpMV(event);
+    if(isPUMV) {
+      if(accept) fWhyRejection=1;
+      fEvRejectionBits+=1<<kPileup;
       accept=kFALSE;
     }
   }
@@ -384,17 +594,48 @@ Bool_t AliRDHFCuts::IsEventSelected(AliVEvent *event) {
   // centrality selection
   if (fUseCentrality!=kCentOff) {  
     Int_t rejection=IsEventSelectedInCentrality(event);    
-    if(rejection>1){      
+    Bool_t okCent=kFALSE;
+    if(rejection==0) okCent=kTRUE;
+    if(isMC && rejection==4 && !fUseCentrFlatteningInMC) okCent=kTRUE;
+    if(!okCent){      
       if(accept) fWhyRejection=rejection;      
-      fEvRejectionBits+=1<<kOutsideCentrality;
+      if(fWhyRejection==4)fEvRejectionBits+=1<<kCentralityFlattening;
+      else fEvRejectionBits+=1<<kOutsideCentrality;
       accept=kFALSE;
     }
+   
   }
 
+  // PbPb2011 outliers in tracklets vs. VZERO and centTRK vs. centV0
+  if(event->GetRunNumber()>=167693 && event->GetRunNumber()<=170593){
+    if(fRemoveTrackletOutliers){
+      Double_t v0cent=GetCentrality((AliAODEvent*)event,kCentV0M);
+      Double_t ntracklets=((AliAODEvent*)event)->GetTracklets()->GetNumberOfTracklets();
+      Double_t cutval=60.-0.08*ntracklets+1./50000.*ntracklets*ntracklets;
+      if(ntracklets<1000. && v0cent<cutval){
+       if(accept) fWhyRejection=2;      
+       fEvRejectionBits+=1<<kOutsideCentrality;
+        accept=kFALSE;
+      }
+    }
+    if(fMaxDiffTRKV0Centr>0.){
+      Double_t v0cent=GetCentrality((AliAODEvent*)event,kCentV0M);
+      Double_t trkcent=GetCentrality((AliAODEvent*)event,kCentTRK);
+      if(TMath::Abs(trkcent-v0cent)>fMaxDiffTRKV0Centr){
+       if(accept) fWhyRejection=1;
+       fEvRejectionBits+=1<<kBadTrackV0Correl;
+       accept=kFALSE;  
+      }
+    }
+  }
+
+  // Correcting PP2012 flag to remoce tracks crossing SPD misaligned staves for periods 12def
+  if(fApplySPDMisalignedPP2012 && !(event->GetRunNumber()>=195681 && event->GetRunNumber()<=197388)) fApplySPDMisalignedPP2012=false;
+
   return accept;
 }
 //---------------------------------------------------------------------------
-Bool_t AliRDHFCuts::AreDaughtersSelected(AliAODRecoDecayHF *d) const {
+Bool_t AliRDHFCuts::AreDaughtersSelected(AliAODRecoDecayHF *d) const{
   //
   // Daughter tracks selection
   // 
@@ -424,7 +665,44 @@ Bool_t AliRDHFCuts::AreDaughtersSelected(AliAODRecoDecayHF *d) const {
   return retval;
 }
 //---------------------------------------------------------------------------
-Bool_t AliRDHFCuts::IsDaughterSelected(AliAODTrack *track,const AliESDVertex *primary,AliESDtrackCuts *cuts) const {
+Bool_t AliRDHFCuts::CheckPtDepCrossedRows(TString rows,Bool_t print) const {
+  //
+  // Check the correctness of the string syntax
+  //
+  Bool_t retval=kTRUE;
+
+  if(!rows.Contains("pt")) {
+    if(print) AliError("string must contain \"pt\"");
+    retval= kFALSE;
+  }
+  return retval;
+}
+//---------------------------------------------------------------------------
+void AliRDHFCuts::SetMinCrossedRowsTPCPtDep(const char *rows){
+  //
+  //Create the TFormula from TString for TPC crossed rows pT dependent cut 
+  //
+
+
+  // setting data member that describes the TPC crossed rows pT dependent cut 
+  fCutMinCrossedRowsTPCPtDep = rows;
+
+  // creating TFormula from TString
+   if(f1CutMinNCrossedRowsTPCPtDep){
+     delete f1CutMinNCrossedRowsTPCPtDep;
+     // resetting TFormula
+     f1CutMinNCrossedRowsTPCPtDep = 0;
+   }
+   if(!CheckPtDepCrossedRows(rows,kTRUE))return;   
+   
+   TString tmp(rows);
+   tmp.ReplaceAll("pt","x");
+   f1CutMinNCrossedRowsTPCPtDep = new TFormula("f1CutMinNCrossedRowsTPCPtDep",tmp.Data());
+
+   
+}
+//---------------------------------------------------------------------------
+Bool_t AliRDHFCuts::IsDaughterSelected(AliAODTrack *track,const AliESDVertex *primary,AliESDtrackCuts *cuts) const{
   //
   // Convert to ESDtrack, relate to vertex and check cuts
   //
@@ -432,7 +710,6 @@ Bool_t AliRDHFCuts::IsDaughterSelected(AliAODTrack *track,const AliESDVertex *pr
 
   if(cuts->GetFlagCutTOFdistance()) cuts->SetFlagCutTOFdistance(kFALSE);
 
-  Bool_t retval=kTRUE;
 
   // convert to ESD track here
   AliESDtrack esdTrack(track);
@@ -441,16 +718,156 @@ Bool_t AliRDHFCuts::IsDaughterSelected(AliAODTrack *track,const AliESDVertex *pr
   esdTrack.SetTPCSharedMap(track->GetTPCSharedMap());
   esdTrack.SetTPCPointsF(track->GetTPCNclsF());
   // needed to calculate the impact parameters
-  esdTrack.RelateToVertex(primary,0.,3.); 
+  esdTrack.RelateToVertex(primary,0.,3.);
+
+  //applying ESDtrackCut
+  if(!cuts->IsSelected(&esdTrack)) return kFALSE; 
+
+  //appliyng kink rejection
+  if(fKinkReject){
+   AliAODVertex *maybeKink=track->GetProdVertex();
+   if(maybeKink->GetType()==AliAODVertex::kKink) return kFALSE;
+  }
+
+  //appliyng TPC crossed rows pT dependent cut
+  if(f1CutMinNCrossedRowsTPCPtDep){
+    Float_t nCrossedRowsTPC = esdTrack.GetTPCCrossedRows();
+    if(nCrossedRowsTPC<f1CutMinNCrossedRowsTPCPtDep->Eval(esdTrack.Pt())) return kFALSE;
+  }
+  
+  //appliyng NTPCcls/NTPCcrossedRows cut
+  if(fCutRatioClsOverCrossRowsTPC){
+    Float_t nCrossedRowsTPC = esdTrack.GetTPCCrossedRows();
+    Float_t nClustersTPC = esdTrack.GetTPCNcls();
+    if(nCrossedRowsTPC!=0){ 
+      Float_t ratio = nClustersTPC/nCrossedRowsTPC;
+      if(ratio<fCutRatioClsOverCrossRowsTPC) return kFALSE;
+    }
+    else return kFALSE;
+  }
+
+  //appliyng TPCsignalN/NTPCcrossedRows cut
+  if(fCutRatioSignalNOverCrossRowsTPC){
+    Float_t nCrossedRowsTPC = esdTrack.GetTPCCrossedRows();
+    Float_t nTPCsignal = esdTrack.GetTPCsignalN();
+    if(nCrossedRowsTPC!=0){
+      Float_t ratio = nTPCsignal/nCrossedRowsTPC;
+      if(ratio<fCutRatioSignalNOverCrossRowsTPC) return kFALSE;
+    }
+    else return kFALSE;
+  }
 
-  if(!cuts->IsSelected(&esdTrack)) retval = kFALSE;
  
   if(fOptPileup==kRejectTracksFromPileupVertex){
     // to be implemented
     // we need either to have here the AOD Event, 
     // or to have the pileup vertex object
   }
-  return retval; 
+
+  if(fApplySPDDeadPbPb2011){
+    Bool_t deadSPDLay1PbPb2011[20][4]={
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE}
+    };
+    Bool_t deadSPDLay2PbPb2011[40][4]={
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kTRUE,kTRUE,kFALSE,kFALSE},
+      {kTRUE,kTRUE,kTRUE,kTRUE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE},
+      {kFALSE,kFALSE,kFALSE,kFALSE}     
+    };
+    Double_t xyz1[3],xyz2[3];
+    esdTrack.GetXYZAt(3.9,0.,xyz1);
+    esdTrack.GetXYZAt(7.6,0.,xyz2);
+    Double_t phi1=TMath::ATan2(xyz1[1],xyz1[0]);
+    if(phi1<0) phi1+=2*TMath::Pi();
+    Int_t lad1=(Int_t)(phi1/(2.*TMath::Pi()/20.));
+    Double_t phi2=TMath::ATan2(xyz2[1],xyz2[0]);
+    if(phi2<0) phi2+=2*TMath::Pi();
+    Int_t lad2=(Int_t)(phi2/(2.*TMath::Pi()/40.));
+    Int_t mod1=(Int_t)((xyz1[2]+14)/7.);
+    Int_t mod2=(Int_t)((xyz2[2]+14)/7.);
+    Bool_t lay1ok=kFALSE;
+    if(mod1>=0 && mod1<4 && lad1<20){
+      lay1ok=deadSPDLay1PbPb2011[lad1][mod1];
+    }
+    Bool_t lay2ok=kFALSE;
+    if(mod2>=0 && mod2<4 && lad2<40){
+      lay2ok=deadSPDLay2PbPb2011[lad2][mod2];
+    }
+    if(!lay1ok && !lay2ok) return kFALSE;
+  }
+
+  if(fApplySPDMisalignedPP2012) {
+    // Cut tracks crossing the SPD at 5.6<phi<2pi
+    Double_t xyz1[3],xyz2[3];
+    esdTrack.GetXYZAt(3.9,0.,xyz1);
+    esdTrack.GetXYZAt(7.6,0.,xyz2);
+    Double_t phi1=TMath::ATan2(xyz1[1],xyz1[0]);
+    if(phi1<0) phi1+=2*TMath::Pi();
+    Double_t phi2=TMath::ATan2(xyz2[1],xyz2[0]);
+    if(phi2<0) phi2+=2*TMath::Pi();
+    Bool_t lay1ok=kTRUE;
+    if(phi1>5.6 && phi1<2.*TMath::Pi()) lay1ok=kFALSE;
+    Bool_t lay2ok=kTRUE;
+    if(phi2>5.6 && phi2<2.*TMath::Pi()) lay2ok=kFALSE;
+    if(!lay1ok || !lay2ok) return kFALSE;
+  }
+
+  return kTRUE; 
 }
 //---------------------------------------------------------------------------
 void AliRDHFCuts::SetPtBins(Int_t nPtBinLimits,Float_t *ptBinLimits) {
@@ -594,7 +1011,7 @@ void AliRDHFCuts::PrintAll() const {
   printf("Minimum vtx contr %d\n",fMinVtxContr);
   printf("Max vtx red chi2 %f\n",fMaxVtxRedChi2);
   printf("Min SPD mult %d\n",fMinSPDMultiplicity);
-  printf("Use PID %d\n",(Int_t)fUsePID);
+  printf("Use PID %d  OldPid=%d\n",(Int_t)fUsePID,fPidHF ? fPidHF->GetOldPid() : -1);
   printf("Remove daughters from vtx %d\n",(Int_t)fRemoveDaughtersFromPrimary);
   printf("Recompute primary vertex %d\n",(Int_t)fRecomputePrimVertex);
   printf("Physics selection: %s\n",fUsePhysicsSelection ? "Yes" : "No");
@@ -607,10 +1024,17 @@ void AliRDHFCuts::PrintAll() const {
     if(fUseCentrality==2) estimator = "Tracks";
     if(fUseCentrality==3) estimator = "Tracklets";
     if(fUseCentrality==4) estimator = "SPD clusters outer"; 
-    printf("Centrality class considered: %.1f-%.1f, estimated with %s",fMinCentrality,fMaxCentrality,estimator.Data());
+    if(fUseCentrality==5) estimator = "ZNA"; 
+    if(fUseCentrality==6) estimator = "ZPA"; 
+    if(fUseCentrality==7) estimator = "V0A"; 
+    printf("Centrality class considered: %.1f-%.1f, estimated with %s\n",fMinCentrality,fMaxCentrality,estimator.Data());
   }
   if(fIsCandTrackSPDFirst) printf("Check for candidates with pt < %2.2f, that daughters fullfill kFirst criteria\n",fMaxPtCandTrackSPDFirst);
 
+  if(fCutRatioClsOverCrossRowsTPC) printf("N TPC Clusters > %f N TPC Crossed Rows\n", fCutRatioClsOverCrossRowsTPC);
+  if(fCutRatioSignalNOverCrossRowsTPC) printf("N TPC Points for dE/dx > %f N TPC Crossed Rows\n", fCutRatioSignalNOverCrossRowsTPC);
+  if(f1CutMinNCrossedRowsTPCPtDep) printf("N TPC Crossed Rows pT-dependent cut: %s\n", fCutMinCrossedRowsTPCPtDep.Data());
+
   if(fVarNames){
     cout<<"Array of variables"<<endl;
     for(Int_t iv=0;iv<fnVars;iv++){
@@ -649,11 +1073,15 @@ void AliRDHFCuts::PrintAll() const {
    }
    cout<<endl;
   }
+  if(fPidHF) fPidHF->PrintAll();
   return;
 }
 
 //--------------------------------------------------------------------------
 void AliRDHFCuts::PrintTrigger() const{
+  // print the trigger selection 
+
+  printf("Selected trigger classes: %s %s\n",fTriggerClass[0].Data(),fTriggerClass[1].Data());
 
   cout<<" Trigger selection pattern: ";
   if( fTriggerMask & AliVEvent::kAny ) cout<<" kAny ";
@@ -761,7 +1189,7 @@ Float_t AliRDHFCuts::GetCentrality(AliAODEvent* aodEvent,AliRDHFCuts::ECentralit
       cent=(Float_t)(centrality->GetCentralityPercentile("V0M"));
       if(cent<0){
        Int_t quality = centrality->GetQuality();
-       if(quality<=1){
+       if(quality<=1){ // fQuality==1 means rejected by zVertex cut that we apply a part and we want to keep separate (Giacomo)
          cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0M");
        }else{
          Int_t runnum=aodEvent->GetRunNumber();
@@ -789,7 +1217,7 @@ Float_t AliRDHFCuts::GetCentrality(AliAODEvent* aodEvent,AliRDHFCuts::ECentralit
       }
     }
     else {
-      if (estimator==kCentTRK) {
+       if (estimator==kCentTRK) {
        cent=(Float_t)(centrality->GetCentralityPercentile("TRK"));
        if(cent<0){
          Int_t quality = centrality->GetQuality();
@@ -806,7 +1234,7 @@ Float_t AliRDHFCuts::GetCentrality(AliAODEvent* aodEvent,AliRDHFCuts::ECentralit
            if((quality==8||quality==9)&&isSelRun)cent=(Float_t)centrality->GetCentralityPercentileUnchecked("TRK");
          }
        }
-      }
+       }
       else{
        if (estimator==kCentTKL){
          cent=(Float_t)(centrality->GetCentralityPercentile("TKL"));
@@ -845,13 +1273,73 @@ Float_t AliRDHFCuts::GetCentrality(AliAODEvent* aodEvent,AliRDHFCuts::ECentralit
              }
            }
          }
+       else{
+         if (estimator==kCentZNA){
+           cent=(Float_t)(centrality->GetCentralityPercentile("ZNA"));
+           if(cent<0){
+             Int_t quality = centrality->GetQuality();
+             if(quality<=1){
+               cent=(Float_t)centrality->GetCentralityPercentileUnchecked("ZNA");
+             }else{
+               Int_t runnum=aodEvent->GetRunNumber();
+               for(Int_t ir=0;ir<5;ir++){
+                 if(runnum==selRun[ir]){
+                   isSelRun=kTRUE;
+                   break;
+                 }
+               }
+               if((quality==8||quality==9)&&isSelRun)cent=(Float_t)centrality->GetCentralityPercentileUnchecked("ZNA");
+             }
+           }
+         }
+       else{
+         if (estimator==kCentZPA){
+           cent=(Float_t)(centrality->GetCentralityPercentile("ZPA"));
+           if(cent<0){
+             Int_t quality = centrality->GetQuality();
+             if(quality<=1){
+               cent=(Float_t)centrality->GetCentralityPercentileUnchecked("ZPA");
+             }else{
+               Int_t runnum=aodEvent->GetRunNumber();
+               for(Int_t ir=0;ir<5;ir++){
+                 if(runnum==selRun[ir]){
+                   isSelRun=kTRUE;
+                   break;
+                 }
+               }
+               if((quality==8||quality==9)&&isSelRun)cent=(Float_t)centrality->GetCentralityPercentileUnchecked("ZPA");
+             }
+           }
+         }
+       else{
+         if (estimator==kCentV0A){
+           cent=(Float_t)(centrality->GetCentralityPercentile("V0A"));
+           if(cent<0){
+             Int_t quality = centrality->GetQuality();
+             if(quality<=1){
+               cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0A");
+             }else{
+               Int_t runnum=aodEvent->GetRunNumber();
+               for(Int_t ir=0;ir<5;ir++){
+                 if(runnum==selRun[ir]){
+                   isSelRun=kTRUE;
+                   break;
+                 }
+               }
+               if((quality==8||quality==9)&&isSelRun)cent=(Float_t)centrality->GetCentralityPercentileUnchecked("V0A");
+             }
+           }
+         }
          else {
            AliWarning("Centrality estimator not valid");
            
          }
        }
-      }
-    } 
+    }
+    }
+    }
+    }
+    }
   }
   return cent;
 }