]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - ANALYSIS/AliESDpidCuts.cxx
end-of-line normalization
[u/mrichter/AliRoot.git] / ANALYSIS / AliESDpidCuts.cxx
index 2970b5a815b278305ed857de02c2b4be3554007e..9f7bef18eedbbb4788444837828ce0f6b8e9fe81 100644 (file)
-/**************************************************************************\r
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *\r
- *                                                                        *\r
- * Author: The ALICE Off-line Project.                                    *\r
- * Contributors are mentioned in the code where appropriate.              *\r
- *                                                                        *\r
- * Permission to use, copy, modify and distribute this software and its   *\r
- * documentation strictly for non-commercial purposes is hereby granted   *\r
- * without fee, provided that the above copyright notice appears in all   *\r
- * copies and that both the copyright notice and this permission notice   *\r
- * appear in the supporting documentation. The authors make no claims     *\r
- * about the suitability of this software for any purpose. It is          *\r
- * provided "as is" without express or implied warranty.                  *\r
- **************************************************************************/\r
-#include <TCanvas.h>\r
-#include <TClass.h>\r
-#include <TCollection.h>\r
-#include <TDirectory.h>\r
-#include <TH1F.h>\r
-#include <TH1I.h>\r
-#include <TH2I.h>\r
-#include <TMath.h>\r
-#include <TIterator.h>\r
-#include <TString.h>\r
-#include <TList.h>\r
-\r
-#include "AliESDtrack.h"\r
-#include "AliESDEvent.h"\r
-#include "AliLog.h"\r
-#include "AliESDpid.h"\r
-\r
-#include "AliESDpidCuts.h"\r
-\r
-ClassImp(AliESDpidCuts)\r
-\r
-const Int_t AliESDpidCuts::kNcuts = 3;\r
-\r
-//_____________________________________________________________________\r
-AliESDpidCuts::AliESDpidCuts(const Char_t *name, const Char_t *title):\r
-    AliAnalysisCuts(name, title)\r
-  , fESDpid(NULL)\r
-  , fTPCsigmaCutRequired(0)\r
-  , fTOFsigmaCutRequired(0)\r
-  , fCutTPCclusterRatio(0.)\r
-  , fMinMomentumTOF(0.5)\r
-  , fHcutStatistics(NULL)\r
-  , fHcutCorrelation(NULL)\r
-{\r
-  //\r
-  // Default constructor\r
-  //\r
-  \r
-  fESDpid = new AliESDpid;\r
-  memset(fCutTPCnSigma, 0, sizeof(Float_t)* AliPID::kSPECIES * 2);\r
-  memset(fCutTOFnSigma, 0, sizeof(Float_t)* AliPID::kSPECIES * 2);\r
-\r
-  memset(fHclusterRatio, 0, sizeof(TH1F *) * 2);\r
-  memset(fHnSigmaTPC, 0, sizeof(TH1F *) * AliPID::kSPECIES * 2);\r
-  memset(fHnSigmaTOF, 0, sizeof(TH1F *) * AliPID::kSPECIES * 2);\r
-}\r
-\r
-//_____________________________________________________________________\r
-AliESDpidCuts::AliESDpidCuts(const AliESDpidCuts &ref):\r
-    AliAnalysisCuts(ref)\r
-  , fESDpid(NULL)\r
-  , fTPCsigmaCutRequired(ref.fTPCsigmaCutRequired)\r
-  , fTOFsigmaCutRequired(ref.fTOFsigmaCutRequired)\r
-  , fCutTPCclusterRatio(ref.fCutTPCclusterRatio)\r
-  , fMinMomentumTOF(ref.fMinMomentumTOF)\r
-  , fHcutStatistics(NULL)\r
-  , fHcutCorrelation(NULL)\r
-{\r
-  //\r
-  // Copy constructor\r
-  //\r
-  fESDpid = new AliESDpid(*ref.fESDpid);\r
-  memcpy(fCutTPCnSigma, ref.fCutTPCnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);\r
-  memcpy(fCutTOFnSigma, ref.fCutTOFnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);\r
-  \r
-  if(ref.fHcutStatistics) fHcutStatistics = dynamic_cast<TH1I *>(ref.fHcutStatistics->Clone());\r
-  if(ref.fHcutCorrelation) fHcutCorrelation = dynamic_cast<TH2I *>(ref.fHcutCorrelation->Clone());\r
-  for(Int_t imode = 0; imode < 2; imode++){\r
-    if(ref.fHclusterRatio[imode]) fHclusterRatio[imode] = dynamic_cast<TH1F *>(ref.fHclusterRatio[imode]->Clone());\r
-    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-      if(fHnSigmaTPC[ispec][imode]) fHnSigmaTPC[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTPC[ispec][imode]->Clone());\r
-      if(fHnSigmaTOF[ispec][imode]) fHnSigmaTOF[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTPC[ispec][imode]->Clone());\r
-    }\r
-  }\r
-}\r
-\r
-//_____________________________________________________________________\r
-AliESDpidCuts &AliESDpidCuts::operator=(const AliESDpidCuts &ref){\r
-  //\r
-  // Assignment operator\r
-  //\r
-  if(this != &ref)\r
-    ref.Copy(*this);\r
-  return *this;\r
-}\r
-\r
-//_____________________________________________________________________\r
-AliESDpidCuts::~AliESDpidCuts(){\r
-  //\r
-  // Destructor\r
-  //\r
-  delete fESDpid;\r
-\r
-  delete fHcutStatistics;\r
-  delete fHcutCorrelation;\r
-  for(Int_t imode = 0; imode < 2; imode++){\r
-    delete fHclusterRatio[imode];\r
-    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-      delete fHnSigmaTPC[ispec][imode];\r
-      delete fHnSigmaTOF[ispec][imode];\r
-    }\r
-  }\r
-}\r
-\r
-//_____________________________________________________________________\r
-Bool_t AliESDpidCuts::IsSelected(TObject *obj){\r
-  //\r
-  // Select Track\r
-  // \r
-  AliESDtrack * trk = dynamic_cast<AliESDtrack*>(obj);\r
-  if(!trk){\r
-    AliError("Provided object is not AliESDtrack!");\r
-    return kFALSE;\r
-  }\r
-  const AliESDEvent* evt = trk->GetESDEvent();\r
-  if(!evt){\r
-    AliError("No AliESDEvent!");\r
-    return kFALSE;\r
-  }\r
-  return AcceptTrack(trk, evt);\r
-}\r
-\r
-//_____________________________________________________________________\r
-void AliESDpidCuts::Copy(TObject &c) const {\r
-  //\r
-  // Copy function\r
-  //\r
-  AliESDpidCuts &target = dynamic_cast<AliESDpidCuts &>(c);\r
-\r
-  target.fESDpid = new AliESDpid(*fESDpid);\r
-\r
-  target.fCutTPCclusterRatio = fCutTPCclusterRatio;\r
-  target.fMinMomentumTOF = fMinMomentumTOF;\r
-\r
-  target.fTPCsigmaCutRequired = fTPCsigmaCutRequired;\r
-  target.fTOFsigmaCutRequired = fTOFsigmaCutRequired;\r
-  \r
-  if(fHcutStatistics) target.fHcutStatistics = dynamic_cast<TH1I *>(fHcutStatistics->Clone());\r
-  if(fHcutCorrelation) target.fHcutCorrelation = dynamic_cast<TH2I *>(fHcutCorrelation->Clone());\r
-  for(Int_t imode = 0; imode < 2; imode++){\r
-    if(fHclusterRatio[imode]) target.fHclusterRatio[imode] = dynamic_cast<TH1F *>(fHclusterRatio[imode]->Clone());\r
-    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-      if(fHnSigmaTPC[ispec][imode]) target.fHnSigmaTPC[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTPC[ispec][imode]->Clone());\r
-      if(fHnSigmaTOF[ispec][imode]) target.fHnSigmaTOF[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTOF[ispec][imode]->Clone());\r
-    }\r
-  }\r
\r
-  memcpy(target.fCutTPCnSigma, fCutTPCnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);\r
-  memcpy(target.fCutTOFnSigma, fCutTOFnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);\r
\r
-  AliESDpidCuts::Copy(c);\r
-}\r
-\r
-//_____________________________________________________________________\r
-Long64_t AliESDpidCuts::Merge(TCollection *coll){\r
-  //\r
-  // Merge Cut objects\r
-  //\r
-  if(!coll) return 0;\r
-  if(coll->IsEmpty())   return 1;\r
-  if(!HasHistograms())  return 0;\r
-  \r
-  TIterator *iter = coll->MakeIterator();\r
-  TObject *o = NULL; \r
-  AliESDpidCuts *ref = NULL;\r
-  Int_t counter = 0;\r
-  while((o = iter->Next())){\r
-    ref = dynamic_cast<AliESDpidCuts *>(o);\r
-    if(!ref) continue;\r
-    if(!ref->HasHistograms()) continue;\r
-\r
-    fHcutStatistics->Add(ref->fHcutStatistics);\r
-    fHcutCorrelation->Add(ref->fHcutCorrelation);\r
-    for(Int_t imode = 0; imode < 2; imode++){\r
-      fHclusterRatio[imode]->Add(ref->fHclusterRatio[imode]);\r
-      for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-        fHnSigmaTPC[ispec][imode]->Add(ref->fHnSigmaTPC[ispec][imode]);\r
-        fHnSigmaTOF[ispec][imode]->Add(ref->fHnSigmaTOF[ispec][imode]);\r
-      }\r
-    }\r
-    ++counter;\r
-  }\r
-  return ++counter;\r
-}\r
-\r
-//_____________________________________________________________________\r
-void AliESDpidCuts::DefineHistograms(Color_t color){\r
-  //\r
-  // Swich on QA and create the histograms\r
-  //\r
-  SetBit(kHasHistograms, kTRUE);\r
-  fHcutStatistics = new TH1I("fHcutStatistics", "Cut Statistics", kNcuts, 0, kNcuts);\r
-  fHcutStatistics->SetLineColor(color);\r
-  fHcutCorrelation = new TH2I("fHcutCorrelation", "Cut Correlation", kNcuts, 0, kNcuts, kNcuts, 0, kNcuts);\r
-  TString cutname[kNcuts] = {"TPCclusterRatio", "TPC sigma", "TOF sigma"};\r
-  for(Int_t icut = 0; icut < kNcuts; icut++){\r
-    fHcutStatistics->GetXaxis()->SetBinLabel(fHcutStatistics->GetXaxis()->GetFirst() + icut, cutname[icut].Data());\r
-    fHcutCorrelation->GetXaxis()->SetBinLabel(fHcutCorrelation->GetXaxis()->GetFirst() + icut, cutname[icut].Data());\r
-    fHcutCorrelation->GetYaxis()->SetBinLabel(fHcutCorrelation->GetYaxis()->GetFirst() + icut, cutname[icut].Data());\r
-  }\r
-  Char_t hname[256], htitle[256];\r
-  for(Int_t imode = 0; imode < 2; imode++){\r
-    snprintf(hname, 256, "fHclusterRatio%s", imode ? "After" : "Before");\r
-    snprintf(htitle, 256, "TPC cluster Ratio %s cuts;Ratio;Entries", imode ? "after" : "before");\r
-    fHclusterRatio[imode] = new TH1F(hname, htitle, 20, 0., 1.);\r
-    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-      snprintf(hname, 256, "fHnSigma%sTPC%s", AliPID::ParticleName(ispec), imode ? "after" : "before");\r
-      snprintf(htitle, 256, "TPC sigma for %s %s cuts;sigma;Entries", AliPID::ParticleName(ispec), imode ? "after" : "before");\r
-      fHnSigmaTPC[ispec][imode] = new TH1F(hname, htitle, 200, -10., 10.);\r
-      snprintf(hname, 256, "fHnSigma%sTOF%s", AliPID::ParticleName(ispec), imode ? "after" : "before");\r
-      snprintf(htitle, 256, "TOF sigma for %s %s cuts;sigma;Entries", AliPID::ParticleName(ispec), imode ? "after" : "before");\r
-      fHnSigmaTOF[ispec][imode] = new TH1F(hname, htitle, 200, -10., 10.);\r
-    }\r
-  }\r
-}\r
-\r
-//_____________________________________________________________________\r
-Bool_t AliESDpidCuts::AcceptTrack(const AliESDtrack *track, const AliESDEvent *event){\r
-  //\r
-  // Check whether the tracks survived the cuts\r
-  //\r
-  enum{\r
-    kCutClusterRatioTPC,\r
-    kCutNsigmaTPC,\r
-    kCutNsigmaTOF\r
-  };\r
-  Long64_t cutRequired=0, cutFullfiled = 0;\r
-  if(fTOFsigmaCutRequired && event == 0)  {\r
-    AliError("No event pointer. Need event pointer for T0 for TOF cut");\r
-    return (0);\r
-  }\r
-  Double_t clusterRatio = track->GetTPCNclsF() ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t>(track->GetTPCNclsF()) : 1.;\r
-  if(fCutTPCclusterRatio > 0.){\r
-    SETBIT(cutRequired, kCutClusterRatioTPC);\r
-    if(clusterRatio >= fCutTPCclusterRatio) \r
-      SETBIT(cutFullfiled, kCutClusterRatioTPC);\r
-  }\r
-  // check TPC nSigma cut\r
-  Float_t nsigmaTPC[AliPID::kSPECIES], nsigma;   // need all sigmas for QA plotting\r
-  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-    nsigmaTPC[ispec] = nsigma = fESDpid->NumberOfSigmasTPC(track,(AliPID::EParticleType)ispec);\r
-    if(!(fTPCsigmaCutRequired & 1 << ispec)) continue;\r
-    SETBIT(cutRequired, kCutNsigmaTPC); // We found at least one species where the n-Sigma Cut is required\r
-    if(nsigma >= fCutTPCnSigma[2*ispec] && nsigma <= fCutTPCnSigma[2*ispec+1]) SETBIT(cutFullfiled, kCutNsigmaTPC);    // Fullfiled for at least one species\r
-  }\r
-  // check TOF nSigma cut\r
-  Float_t nsigmaTOF[AliPID::kSPECIES];    // see above\r
-  Bool_t hasTOFpid = track->GetStatus() & AliESDtrack::kTOFpid; // only apply TOF n-sigma cut when PID Status Bit is set\r
-  Double_t times[AliPID::kSPECIES];\r
-  track->GetIntegratedTimes(times);\r
-  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-    \r
-    if(hasTOFpid && event) nsigmaTOF[ispec] = nsigma = fESDpid->NumberOfSigmasTOF(track,(AliPID::EParticleType)ispec, event->GetT0());\r
-    if(!(fTOFsigmaCutRequired && 1 << ispec)) continue;\r
-    SETBIT(cutRequired, kCutNsigmaTOF);\r
-    if(track->GetOuterParam()->P() >= fMinMomentumTOF){\r
-      if(hasTOFpid && nsigma <= fCutTOFnSigma[2*ispec] && nsigma >= fCutTOFnSigma[2*ispec+1]) SETBIT(cutFullfiled, kCutNsigmaTOF);\r
-    }\r
-  }\r
-\r
-  // Fill Histograms before cuts\r
-  if(HasHistograms()){\r
-    fHclusterRatio[0]->Fill(clusterRatio);\r
-    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-      fHnSigmaTPC[ispec][0]->Fill(nsigmaTPC[ispec]);\r
-      if(hasTOFpid) fHnSigmaTOF[ispec][0]->Fill(nsigmaTOF[ispec]);\r
-    }\r
-  }\r
-  if(cutRequired != cutFullfiled){\r
-    // Fill cut statistics\r
-    if(HasHistograms()){\r
-      for(Int_t icut = 0; icut < kNcuts; icut++){\r
-       if(TESTBIT(cutRequired, icut) && !TESTBIT(cutFullfiled, icut)){\r
-         // cut not fullfiled\r
-         fHcutStatistics->Fill(icut);\r
-         for(Int_t jcut = 0; jcut <= icut; jcut++)\r
-           if(TESTBIT(cutRequired, jcut) && !TESTBIT(cutFullfiled, jcut)) fHcutCorrelation->Fill(jcut, icut);\r
-       }\r
-      }\r
-    }\r
-    return kFALSE;    // At least one cut is not fullfiled\r
-  }\r
-\r
-  // Fill Histograms after cuts\r
-  if(HasHistograms()){\r
-    fHclusterRatio[1]->Fill(clusterRatio);\r
-    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-      fHnSigmaTPC[ispec][1]->Fill(nsigmaTPC[ispec]);\r
-      if(hasTOFpid) fHnSigmaTOF[ispec][1]->Fill(nsigmaTOF[ispec]);\r
-    }\r
-  }\r
-\r
-  return kTRUE;\r
-}\r
-\r
-//_____________________________________________________________________\r
-void AliESDpidCuts::SaveHistograms(const Char_t * location){\r
-  //\r
-  // Save the histograms to a file\r
-  //\r
-  if(!HasHistograms()){\r
-    AliError("Histograms not on - Exiting");\r
-    return;\r
-  }\r
-  if(!location) location = GetName();\r
-  gDirectory->mkdir(location);\r
-  gDirectory->cd(location);\r
-  fHcutStatistics->Write();\r
-  fHcutCorrelation->Write();\r
-\r
-  gDirectory->mkdir("before_cuts");\r
-  gDirectory->mkdir("after_cuts");\r
-\r
-  gDirectory->cd("before_cuts");\r
-  fHclusterRatio[0]->Write();\r
-  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-    fHnSigmaTPC[ispec][0]->Write();\r
-    fHnSigmaTOF[ispec][0]->Write();\r
-  }\r
-\r
-  gDirectory->cd("../after_cuts");\r
-  fHclusterRatio[1]->Write();\r
-  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-    fHnSigmaTPC[ispec][1]->Write();\r
-    fHnSigmaTOF[ispec][1]->Write();\r
-  }\r
-\r
-  gDirectory->cd("..");\r
-}\r
-\r
-//_____________________________________________________________________\r
-void AliESDpidCuts::DrawHistograms(){\r
-  //\r
-  // Draw the Histograms\r
-  //\r
-  TCanvas *stat = new TCanvas("cutStat", "Cut Statistics", 640, 480);\r
-  stat->cd();\r
-  fHcutStatistics->SetStats(kFALSE);\r
-  fHcutStatistics->Draw();\r
-  stat->SaveAs(Form("%s_%s.gif", GetName(), stat->GetName()));\r
-\r
-  TCanvas *correl = new TCanvas("cutCorrelation", "Cut Correlation", 640, 480);\r
-  correl->cd();\r
-  fHcutCorrelation->SetStats(kFALSE);\r
-  fHcutCorrelation->Draw("colz");\r
-  correl->SaveAs(Form("%s_%s.gif", GetName(), correl->GetName()));\r
-\r
-  TCanvas *cRatio = new TCanvas("ClusterRatioTPC", "TPC cluster Ratio", 640, 480);\r
-  cRatio->cd();\r
-  fHclusterRatio[0]->SetLineColor(kRed);\r
-  fHclusterRatio[0]->SetStats(kFALSE);\r
-  fHclusterRatio[0]->Draw();\r
-  fHclusterRatio[1]->SetLineColor(kBlue);\r
-  fHclusterRatio[1]->SetStats(kFALSE);\r
-  fHclusterRatio[1]->Draw("same");\r
-  cRatio->SaveAs(Form("%s_%s.gif",  GetName(), cRatio->GetName()));\r
-\r
-  TCanvas *cNsigTPC = new TCanvas("NsigmaTPC", "TPC n-sigma", 640, 480);\r
-  cNsigTPC->Divide(3,2);\r
-  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-    cNsigTPC->cd(ispec + 1);\r
-    fHnSigmaTPC[ispec][0]->SetLineColor(kRed);\r
-    fHnSigmaTPC[ispec][0]->SetStats(kFALSE);\r
-    fHnSigmaTPC[ispec][0]->Draw();\r
-    fHnSigmaTPC[ispec][1]->SetLineColor(kBlue);\r
-    fHnSigmaTPC[ispec][1]->SetStats(kFALSE);\r
-    fHnSigmaTPC[ispec][1]->Draw("same");\r
-  }\r
-  cNsigTPC->SaveAs(Form("%s_%s.gif", GetName(), cNsigTPC->GetName()));\r
-\r
-  TCanvas *cNsigTOF = new TCanvas("NsigmaTOF", "TOF n-sigma", 640, 480);\r
-  cNsigTOF->Divide(3,2);\r
-  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){\r
-    cNsigTOF->cd(ispec + 1);\r
-    fHnSigmaTOF[ispec][0]->SetLineColor(kRed);\r
-    fHnSigmaTOF[ispec][0]->SetStats(kFALSE);\r
-    fHnSigmaTOF[ispec][0]->Draw();\r
-    fHnSigmaTOF[ispec][1]->SetLineColor(kBlue);\r
-    fHnSigmaTOF[ispec][1]->SetStats(kFALSE);\r
-    fHnSigmaTOF[ispec][1]->Draw("same");\r
-  }\r
-  cNsigTOF->SaveAs(Form("%s_%s.gif", GetName(), cNsigTOF->GetName()));\r
-}\r
-\r
+/**************************************************************************
+ * Copyright(c) 1998-1999, 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.                  *
+ **************************************************************************/
+#include <TCanvas.h>
+#include <TClass.h>
+#include <TCollection.h>
+#include <TDirectory.h>
+#include <TH1F.h>
+#include <TH1I.h>
+#include <TH2I.h>
+#include <TMath.h>
+#include <TIterator.h>
+#include <TString.h>
+#include <TList.h>
+
+#include "AliAnalysisManager.h"
+#include "AliInputEventHandler.h"
+#include "AliESDtrack.h"
+#include "AliESDEvent.h"
+#include "AliLog.h"
+#include "AliPIDResponse.h"
+
+#include "AliESDpidCuts.h"
+
+ClassImp(AliESDpidCuts)
+
+const Int_t AliESDpidCuts::kNcuts = 3;
+
+//_____________________________________________________________________
+AliESDpidCuts::AliESDpidCuts(const Char_t *name, const Char_t *title):
+    AliAnalysisCuts(name, title)
+  , fPIDresponse(NULL)
+  , fTPCsigmaCutRequired(0)
+  , fTOFsigmaCutRequired(0)
+  , fCutTPCclusterRatio(0.)
+  , fMinMomentumTOF(0.5)
+  , fHcutStatistics(NULL)
+  , fHcutCorrelation(NULL)
+{
+  //
+  // Default constructor
+  //
+  
+  memset(fCutTPCnSigma, 0, sizeof(Float_t)* AliPID::kSPECIES * 2);
+  memset(fCutTOFnSigma, 0, sizeof(Float_t)* AliPID::kSPECIES * 2);
+
+  memset(fHclusterRatio, 0, sizeof(TH1F *) * 2);
+  memset(fHnSigmaTPC, 0, sizeof(TH1F *) * AliPID::kSPECIES * 2);
+  memset(fHnSigmaTOF, 0, sizeof(TH1F *) * AliPID::kSPECIES * 2);
+}
+
+//_____________________________________________________________________
+AliESDpidCuts::AliESDpidCuts(const AliESDpidCuts &ref):
+    AliAnalysisCuts(ref)
+  , fPIDresponse(NULL)
+  , fTPCsigmaCutRequired(ref.fTPCsigmaCutRequired)
+  , fTOFsigmaCutRequired(ref.fTOFsigmaCutRequired)
+  , fCutTPCclusterRatio(ref.fCutTPCclusterRatio)
+  , fMinMomentumTOF(ref.fMinMomentumTOF)
+  , fHcutStatistics(NULL)
+  , fHcutCorrelation(NULL)
+{
+  //
+  // Copy constructor
+  //
+  fPIDresponse = ref.fPIDresponse;
+  memcpy(fCutTPCnSigma, ref.fCutTPCnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);
+  memcpy(fCutTOFnSigma, ref.fCutTOFnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);
+  
+  if(ref.fHcutStatistics) fHcutStatistics = dynamic_cast<TH1I *>(ref.fHcutStatistics->Clone());
+  if(ref.fHcutCorrelation) fHcutCorrelation = dynamic_cast<TH2I *>(ref.fHcutCorrelation->Clone());
+  for(Int_t imode = 0; imode < 2; imode++){
+    if(ref.fHclusterRatio[imode]) fHclusterRatio[imode] = dynamic_cast<TH1F *>(ref.fHclusterRatio[imode]->Clone());
+    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+      if(fHnSigmaTPC[ispec][imode]) fHnSigmaTPC[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTPC[ispec][imode]->Clone());
+      if(fHnSigmaTOF[ispec][imode]) fHnSigmaTOF[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTPC[ispec][imode]->Clone());
+    }
+  }
+}
+
+//_____________________________________________________________________
+AliESDpidCuts &AliESDpidCuts::operator=(const AliESDpidCuts &ref){
+  //
+  // Assignment operator
+  //
+  if(this != &ref)
+    ref.Copy(*this);
+  return *this;
+}
+
+//_____________________________________________________________________
+AliESDpidCuts::~AliESDpidCuts(){
+  //
+  // Destructor
+  //
+
+  delete fHcutCorrelation;
+  for(Int_t imode = 0; imode < 2; imode++){
+    delete fHclusterRatio[imode];
+    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+      delete fHnSigmaTPC[ispec][imode];
+      delete fHnSigmaTOF[ispec][imode];
+    }
+  }
+}
+
+//_____________________________________________________________________
+void AliESDpidCuts::Init(){
+  //
+  // Init function, get PID response from the Analysis Manager
+  //
+  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
+  if(mgr){
+    AliInputEventHandler *handler = dynamic_cast<AliInputEventHandler*>(mgr->GetInputEventHandler());
+    if(handler){
+      fPIDresponse = handler->GetPIDResponse();
+    }
+  }
+}
+
+//_____________________________________________________________________
+Bool_t AliESDpidCuts::IsSelected(TObject *obj){
+  //
+  // Select Track
+  // 
+  AliESDtrack * trk = dynamic_cast<AliESDtrack*>(obj);
+  if(!trk){
+    AliError("Provided object is not AliESDtrack!");
+    return kFALSE;
+  }
+  const AliESDEvent* evt = trk->GetESDEvent();
+  if(!evt){
+    AliError("No AliESDEvent!");
+    return kFALSE;
+  }
+  return AcceptTrack(trk, evt);
+}
+
+//_____________________________________________________________________
+void AliESDpidCuts::Copy(TObject &c) const {
+  //
+  // Copy function
+  //
+  AliESDpidCuts &target = dynamic_cast<AliESDpidCuts &>(c);
+
+  target.fPIDresponse = fPIDresponse;
+
+  target.fCutTPCclusterRatio = fCutTPCclusterRatio;
+  target.fMinMomentumTOF = fMinMomentumTOF;
+
+  target.fTPCsigmaCutRequired = fTPCsigmaCutRequired;
+  target.fTOFsigmaCutRequired = fTOFsigmaCutRequired;
+  
+  if(fHcutStatistics) target.fHcutStatistics = dynamic_cast<TH1I *>(fHcutStatistics->Clone());
+  if(fHcutCorrelation) target.fHcutCorrelation = dynamic_cast<TH2I *>(fHcutCorrelation->Clone());
+  for(Int_t imode = 0; imode < 2; imode++){
+    if(fHclusterRatio[imode]) target.fHclusterRatio[imode] = dynamic_cast<TH1F *>(fHclusterRatio[imode]->Clone());
+    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+      if(fHnSigmaTPC[ispec][imode]) target.fHnSigmaTPC[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTPC[ispec][imode]->Clone());
+      if(fHnSigmaTOF[ispec][imode]) target.fHnSigmaTOF[ispec][imode] = dynamic_cast<TH1F *>(fHnSigmaTOF[ispec][imode]->Clone());
+    }
+  }
+  memcpy(target.fCutTPCnSigma, fCutTPCnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);
+  memcpy(target.fCutTOFnSigma, fCutTOFnSigma, sizeof(Float_t) * AliPID::kSPECIES * 2);
+  AliESDpidCuts::Copy(c);
+}
+
+//_____________________________________________________________________
+Long64_t AliESDpidCuts::Merge(TCollection *coll){
+  //
+  // Merge Cut objects
+  //
+  if(!coll) return 0;
+  if(coll->IsEmpty())   return 1;
+  if(!HasHistograms())  return 0;
+  
+  TIterator *iter = coll->MakeIterator();
+  TObject *o = NULL; 
+  AliESDpidCuts *ref = NULL;
+  Int_t counter = 0;
+  while((o = iter->Next())){
+    ref = dynamic_cast<AliESDpidCuts *>(o);
+    if(!ref) continue;
+    if(!ref->HasHistograms()) continue;
+
+    fHcutStatistics->Add(ref->fHcutStatistics);
+    fHcutCorrelation->Add(ref->fHcutCorrelation);
+    for(Int_t imode = 0; imode < 2; imode++){
+      fHclusterRatio[imode]->Add(ref->fHclusterRatio[imode]);
+      for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+        fHnSigmaTPC[ispec][imode]->Add(ref->fHnSigmaTPC[ispec][imode]);
+        fHnSigmaTOF[ispec][imode]->Add(ref->fHnSigmaTOF[ispec][imode]);
+      }
+    }
+    ++counter;
+  }
+  return ++counter;
+}
+
+//_____________________________________________________________________
+void AliESDpidCuts::DefineHistograms(Color_t color){
+  //
+  // Swich on QA and create the histograms
+  //
+  SetBit(kHasHistograms, kTRUE);
+  fHcutStatistics = new TH1I("fHcutStatistics", "Cut Statistics", kNcuts, 0, kNcuts);
+  fHcutStatistics->SetLineColor(color);
+  fHcutCorrelation = new TH2I("fHcutCorrelation", "Cut Correlation", kNcuts, 0, kNcuts, kNcuts, 0, kNcuts);
+  TString cutname[kNcuts] = {"TPCclusterRatio", "TPC sigma", "TOF sigma"};
+  for(Int_t icut = 0; icut < kNcuts; icut++){
+    fHcutStatistics->GetXaxis()->SetBinLabel(fHcutStatistics->GetXaxis()->GetFirst() + icut, cutname[icut].Data());
+    fHcutCorrelation->GetXaxis()->SetBinLabel(fHcutCorrelation->GetXaxis()->GetFirst() + icut, cutname[icut].Data());
+    fHcutCorrelation->GetYaxis()->SetBinLabel(fHcutCorrelation->GetYaxis()->GetFirst() + icut, cutname[icut].Data());
+  }
+  Char_t hname[256], htitle[256];
+  for(Int_t imode = 0; imode < 2; imode++){
+    snprintf(hname, 256, "fHclusterRatio%s", imode ? "After" : "Before");
+    snprintf(htitle, 256, "TPC cluster Ratio %s cuts;Ratio;Entries", imode ? "after" : "before");
+    fHclusterRatio[imode] = new TH1F(hname, htitle, 20, 0., 1.);
+    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+      snprintf(hname, 256, "fHnSigma%sTPC%s", AliPID::ParticleName(ispec), imode ? "after" : "before");
+      snprintf(htitle, 256, "TPC sigma for %s %s cuts;sigma;Entries", AliPID::ParticleName(ispec), imode ? "after" : "before");
+      fHnSigmaTPC[ispec][imode] = new TH1F(hname, htitle, 200, -10., 10.);
+      snprintf(hname, 256, "fHnSigma%sTOF%s", AliPID::ParticleName(ispec), imode ? "after" : "before");
+      snprintf(htitle, 256, "TOF sigma for %s %s cuts;sigma;Entries", AliPID::ParticleName(ispec), imode ? "after" : "before");
+      fHnSigmaTOF[ispec][imode] = new TH1F(hname, htitle, 200, -10., 10.);
+    }
+  }
+}
+
+//_____________________________________________________________________
+Bool_t AliESDpidCuts::AcceptTrack(const AliESDtrack *track, const AliESDEvent *event){
+  //
+  // Check whether the tracks survived the cuts
+  //
+  if(!fPIDresponse){
+    Init();
+    if (!fPIDresponse)
+      AliError("PID Response not available");
+    return 0;
+  }
+  enum{
+    kCutClusterRatioTPC,
+    kCutNsigmaTPC,
+    kCutNsigmaTOF
+  };
+  Long64_t cutRequired=0, cutFullfiled = 0;
+  if(fTOFsigmaCutRequired && event == 0)  {
+    AliError("No event pointer. Need event pointer for T0 for TOF cut");
+    return (0);
+  }
+  Double_t clusterRatio = track->GetTPCNclsF() ? static_cast<Float_t>(track->GetTPCNcls())/static_cast<Float_t>(track->GetTPCNclsF()) : 1.;
+  if(fCutTPCclusterRatio > 0.){
+    SETBIT(cutRequired, kCutClusterRatioTPC);
+    if(clusterRatio >= fCutTPCclusterRatio) 
+      SETBIT(cutFullfiled, kCutClusterRatioTPC);
+  }
+  // check TPC nSigma cut
+  Float_t nsigmaTPC[AliPID::kSPECIES], nsigma;   // need all sigmas for QA plotting
+  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+    nsigmaTPC[ispec] = nsigma = fPIDresponse->NumberOfSigmasTPC(track,(AliPID::EParticleType)ispec);
+    if(!(fTPCsigmaCutRequired & 1 << ispec)) continue;
+    SETBIT(cutRequired, kCutNsigmaTPC); // We found at least one species where the n-Sigma Cut is required
+    if(nsigma >= fCutTPCnSigma[2*ispec] && nsigma <= fCutTPCnSigma[2*ispec+1]) SETBIT(cutFullfiled, kCutNsigmaTPC);    // Fullfiled for at least one species
+  }
+  // check TOF nSigma cut
+  Float_t nsigmaTOF[AliPID::kSPECIES];    // see above
+  Bool_t hasTOFpid = track->GetStatus() & AliESDtrack::kTOFpid; // only apply TOF n-sigma cut when PID Status Bit is set
+  Double_t times[AliPID::kSPECIES];
+  track->GetIntegratedTimes(times);
+  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+    
+    if(hasTOFpid && event) nsigmaTOF[ispec] = nsigma = fPIDresponse->NumberOfSigmasTOF(track,(AliPID::EParticleType)ispec);
+    if(!(fTOFsigmaCutRequired && 1 << ispec)) continue;
+    SETBIT(cutRequired, kCutNsigmaTOF);
+    if(track->GetOuterParam()->P() >= fMinMomentumTOF){
+      if(hasTOFpid && nsigma <= fCutTOFnSigma[2*ispec] && nsigma >= fCutTOFnSigma[2*ispec+1]) SETBIT(cutFullfiled, kCutNsigmaTOF);
+    }
+  }
+
+  // Fill Histograms before cuts
+  if(HasHistograms()){
+    fHclusterRatio[0]->Fill(clusterRatio);
+    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+      fHnSigmaTPC[ispec][0]->Fill(nsigmaTPC[ispec]);
+      if(hasTOFpid) fHnSigmaTOF[ispec][0]->Fill(nsigmaTOF[ispec]);
+    }
+  }
+  if(cutRequired != cutFullfiled){
+    // Fill cut statistics
+    if(HasHistograms()){
+      for(Int_t icut = 0; icut < kNcuts; icut++){
+       if(TESTBIT(cutRequired, icut) && !TESTBIT(cutFullfiled, icut)){
+         // cut not fullfiled
+         fHcutStatistics->Fill(icut);
+         for(Int_t jcut = 0; jcut <= icut; jcut++)
+           if(TESTBIT(cutRequired, jcut) && !TESTBIT(cutFullfiled, jcut)) fHcutCorrelation->Fill(jcut, icut);
+       }
+      }
+    }
+    return kFALSE;    // At least one cut is not fullfiled
+  }
+
+  // Fill Histograms after cuts
+  if(HasHistograms()){
+    fHclusterRatio[1]->Fill(clusterRatio);
+    for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+      fHnSigmaTPC[ispec][1]->Fill(nsigmaTPC[ispec]);
+      if(hasTOFpid) fHnSigmaTOF[ispec][1]->Fill(nsigmaTOF[ispec]);
+    }
+  }
+
+  return kTRUE;
+}
+
+//_____________________________________________________________________
+void AliESDpidCuts::SaveHistograms(const Char_t * location){
+  //
+  // Save the histograms to a file
+  //
+  if(!HasHistograms()){
+    AliError("Histograms not on - Exiting");
+    return;
+  }
+  if(!location) location = GetName();
+  gDirectory->mkdir(location);
+  gDirectory->cd(location);
+  fHcutStatistics->Write();
+  fHcutCorrelation->Write();
+
+  gDirectory->mkdir("before_cuts");
+  gDirectory->mkdir("after_cuts");
+
+  gDirectory->cd("before_cuts");
+  fHclusterRatio[0]->Write();
+  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+    fHnSigmaTPC[ispec][0]->Write();
+    fHnSigmaTOF[ispec][0]->Write();
+  }
+
+  gDirectory->cd("../after_cuts");
+  fHclusterRatio[1]->Write();
+  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+    fHnSigmaTPC[ispec][1]->Write();
+    fHnSigmaTOF[ispec][1]->Write();
+  }
+
+  gDirectory->cd("..");
+}
+
+//_____________________________________________________________________
+void AliESDpidCuts::DrawHistograms(){
+  //
+  // Draw the Histograms
+  //
+  TCanvas *stat = new TCanvas("cutStat", "Cut Statistics", 640, 480);
+  stat->cd();
+  fHcutStatistics->SetStats(kFALSE);
+  fHcutStatistics->Draw();
+  stat->SaveAs(Form("%s_%s.gif", GetName(), stat->GetName()));
+
+  TCanvas *correl = new TCanvas("cutCorrelation", "Cut Correlation", 640, 480);
+  correl->cd();
+  fHcutCorrelation->SetStats(kFALSE);
+  fHcutCorrelation->Draw("colz");
+  correl->SaveAs(Form("%s_%s.gif", GetName(), correl->GetName()));
+
+  TCanvas *cRatio = new TCanvas("ClusterRatioTPC", "TPC cluster Ratio", 640, 480);
+  cRatio->cd();
+  fHclusterRatio[0]->SetLineColor(kRed);
+  fHclusterRatio[0]->SetStats(kFALSE);
+  fHclusterRatio[0]->Draw();
+  fHclusterRatio[1]->SetLineColor(kBlue);
+  fHclusterRatio[1]->SetStats(kFALSE);
+  fHclusterRatio[1]->Draw("same");
+  cRatio->SaveAs(Form("%s_%s.gif",  GetName(), cRatio->GetName()));
+
+  TCanvas *cNsigTPC = new TCanvas("NsigmaTPC", "TPC n-sigma", 640, 480);
+  cNsigTPC->Divide(3,2);
+  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+    cNsigTPC->cd(ispec + 1);
+    fHnSigmaTPC[ispec][0]->SetLineColor(kRed);
+    fHnSigmaTPC[ispec][0]->SetStats(kFALSE);
+    fHnSigmaTPC[ispec][0]->Draw();
+    fHnSigmaTPC[ispec][1]->SetLineColor(kBlue);
+    fHnSigmaTPC[ispec][1]->SetStats(kFALSE);
+    fHnSigmaTPC[ispec][1]->Draw("same");
+  }
+  cNsigTPC->SaveAs(Form("%s_%s.gif", GetName(), cNsigTPC->GetName()));
+
+  TCanvas *cNsigTOF = new TCanvas("NsigmaTOF", "TOF n-sigma", 640, 480);
+  cNsigTOF->Divide(3,2);
+  for(Int_t ispec = 0; ispec < AliPID::kSPECIES; ispec++){
+    cNsigTOF->cd(ispec + 1);
+    fHnSigmaTOF[ispec][0]->SetLineColor(kRed);
+    fHnSigmaTOF[ispec][0]->SetStats(kFALSE);
+    fHnSigmaTOF[ispec][0]->Draw();
+    fHnSigmaTOF[ispec][1]->SetLineColor(kBlue);
+    fHnSigmaTOF[ispec][1]->SetStats(kFALSE);
+    fHnSigmaTOF[ispec][1]->Draw("same");
+  }
+  cNsigTOF->SaveAs(Form("%s_%s.gif", GetName(), cNsigTOF->GetName()));
+}
+