- Update 11a10* (MC_PbPb) (also update for splines)
authormorsch <morsch@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 5 Jul 2013 14:29:16 +0000 (14:29 +0000)
committermorsch <morsch@f7af4fe6-9843-0410-8265-dc069ae4e863>
Fri, 5 Jul 2013 14:29:16 +0000 (14:29 +0000)
- update splines for 13b2_efix_p1
- Added maps for 13b2_efix_p1
- Added more verbose printout during pid initialisation
- catch some unnecessary warnings
- add nSigma histos for HMPID in PIDqa

Jens Wiechula

ANALYSIS/AliAnalysisTaskPIDqa.cxx
OADB/COMMON/PID/data/TPCPIDResponse.root
OADB/COMMON/PID/data/TPCetaMaps.root
STEER/STEERBase/AliPIDResponse.cxx
STEER/STEERBase/AliPIDResponse.h
STEER/STEERBase/AliTPCPIDResponse.cxx

index 33d60ca..2587c15 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
-\r
-/* $Id: AliAnalysisTaskPIDqa.cxx 43811 2010-09-23 14:13:31Z wiechula $ */\r
-#include <TList.h>\r
-#include <TVectorD.h>\r
-#include <TObjArray.h>\r
-#include <TH2.h>\r
-#include <TFile.h>\r
-#include <TPRegexp.h>\r
-#include <TChain.h>\r
-#include <TF1.h>\r
-#include <TSpline.h>\r
-\r
-#include <AliAnalysisManager.h>\r
-#include <AliInputEventHandler.h>\r
-#include <AliVEventHandler.h>\r
-#include <AliVEvent.h>\r
-#include <AliVParticle.h>\r
-#include <AliVTrack.h>\r
-#include <AliLog.h>\r
-#include <AliPID.h>\r
-#include <AliPIDResponse.h>\r
-#include <AliITSPIDResponse.h>\r
-#include <AliTPCPIDResponse.h>\r
-#include <AliTRDPIDResponse.h>\r
-#include <AliTOFPIDResponse.h>\r
-\r
-#include <AliESDEvent.h>\r
-#include <AliAODEvent.h>\r
-#include <AliESDv0.h>\r
-#include <AliAODv0.h>\r
-#include <AliESDv0KineCuts.h>\r
-\r
-#include "AliAnalysisTaskPIDqa.h"\r
-\r
-\r
-ClassImp(AliAnalysisTaskPIDqa)\r
-\r
-//______________________________________________________________________________\r
-AliAnalysisTaskPIDqa::AliAnalysisTaskPIDqa():\r
-AliAnalysisTaskSE(),\r
-fPIDResponse(0x0),\r
-fV0cuts(0x0),\r
-fV0electrons(0x0),\r
-fV0pions(0x0),\r
-fV0kaons(0x0),\r
-fV0protons(0x0),\r
-fListQA(0x0),\r
-fListQAits(0x0),\r
-fListQAitsSA(0x0),\r
-fListQAitsPureSA(0x0),\r
-fListQAtpc(0x0),\r
-fListQAtrd(0x0),\r
-fListQAtof(0x0),\r
-fListQAt0(0x0),\r
-fListQAemcal(0x0),\r
-fListQAhmpid(0x0),\r
-fListQAtofhmpid(0x0),\r
-fListQAtpctof(0x0),\r
-fListQAV0(0x0),\r
-fListQAinfo(0x0)\r
-{\r
-  //\r
-  // Dummy constructor\r
-  //\r
-}\r
-\r
-//______________________________________________________________________________\r
-AliAnalysisTaskPIDqa::AliAnalysisTaskPIDqa(const char* name):\r
-AliAnalysisTaskSE(name),\r
-fPIDResponse(0x0),\r
-fV0cuts(0x0),\r
-fV0electrons(0x0),\r
-fV0pions(0x0),\r
-fV0kaons(0x0),\r
-fV0protons(0x0),\r
-fListQA(0x0),\r
-fListQAits(0x0),\r
-fListQAitsSA(0x0),\r
-fListQAitsPureSA(0x0),\r
-fListQAtpc(0x0),\r
-fListQAtrd(0x0),\r
-fListQAtof(0x0),\r
-fListQAt0(0x0),\r
-fListQAemcal(0x0),\r
-fListQAhmpid(0x0),\r
-fListQAtofhmpid(0x0),\r
-fListQAtpctof(0x0),\r
-fListQAV0(0x0),\r
-fListQAinfo(0x0)\r
-{\r
-  //\r
-  // Default constructor\r
-  //\r
-  DefineInput(0,TChain::Class());\r
-  DefineOutput(1,TList::Class());\r
-}\r
-\r
-//______________________________________________________________________________\r
-AliAnalysisTaskPIDqa::~AliAnalysisTaskPIDqa()\r
-{\r
-  //\r
-  // Destructor\r
-  //\r
-\r
-  delete fV0cuts;\r
-  delete fV0electrons;\r
-  delete fV0pions;\r
-  delete fV0kaons;\r
-  delete fV0protons;\r
-\r
-  if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) delete fListQA;\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::UserCreateOutputObjects()\r
-{\r
-  //\r
-  // Create the output QA objects\r
-  //\r
-\r
-  AliLog::SetClassDebugLevel("AliAnalysisTaskPIDqa",10);\r
-\r
-  //input hander\r
-  AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();\r
-  AliInputEventHandler *inputHandler=dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());\r
-  if (!inputHandler) AliFatal("Input handler needed");\r
-\r
-  //pid response object\r
-  fPIDResponse=inputHandler->GetPIDResponse();\r
-  if (!fPIDResponse) AliError("PIDResponse object was not created");\r
-  \r
-  // V0 Kine cuts \r
-  fV0cuts = new AliESDv0KineCuts;\r
\r
-  // V0 PID Obj arrays\r
-  fV0electrons = new TObjArray;\r
-  fV0pions     = new TObjArray;\r
-  fV0kaons     = new TObjArray;\r
-  fV0protons   = new TObjArray;\r
-\r
-  //\r
-  fListQA=new TList;\r
-  fListQA->SetOwner();\r
-  \r
-  fListQAits=new TList;\r
-  fListQAits->SetOwner();\r
-  fListQAits->SetName("ITS");\r
-\r
-  fListQAitsSA=new TList;\r
-  fListQAitsSA->SetOwner();\r
-  fListQAitsSA->SetName("ITS_SA");\r
-\r
-  fListQAitsPureSA=new TList;\r
-  fListQAitsPureSA->SetOwner();\r
-  fListQAitsPureSA->SetName("ITS_PureSA");\r
-\r
-  fListQAtpc=new TList;\r
-  fListQAtpc->SetOwner();\r
-  fListQAtpc->SetName("TPC");\r
-  \r
-  fListQAtrd=new TList;\r
-  fListQAtrd->SetOwner();\r
-  fListQAtrd->SetName("TRD");\r
-  \r
-  fListQAtof=new TList;\r
-  fListQAtof->SetOwner();\r
-  fListQAtof->SetName("TOF");\r
-\r
-  fListQAt0=new TList;\r
-  fListQAt0->SetOwner();\r
-  fListQAt0->SetName("T0");\r
-  \r
-  fListQAemcal=new TList;\r
-  fListQAemcal->SetOwner();\r
-  fListQAemcal->SetName("EMCAL");\r
-  \r
-  fListQAhmpid=new TList;\r
-  fListQAhmpid->SetOwner();\r
-  fListQAhmpid->SetName("HMPID");\r
-  \r
-  fListQAtpctof=new TList;\r
-  fListQAtpctof->SetOwner();\r
-  fListQAtpctof->SetName("TPC_TOF");\r
-\r
-  fListQAtofhmpid=new TList;\r
-  fListQAtofhmpid->SetOwner();\r
-  fListQAtofhmpid->SetName("TOF_HMPID");\r
-  \r
-  fListQAV0=new TList;\r
-  fListQAV0->SetOwner();\r
-  fListQAV0->SetName("V0decay");\r
-\r
-  fListQAinfo=new TList;\r
-  fListQAinfo->SetOwner();\r
-  fListQAinfo->SetName("QAinfo");\r
-  \r
-  fListQA->Add(fListQAits);\r
-  fListQA->Add(fListQAitsSA);\r
-  fListQA->Add(fListQAitsPureSA);\r
-  fListQA->Add(fListQAtpc);\r
-  fListQA->Add(fListQAtrd);\r
-  fListQA->Add(fListQAtof);\r
-  fListQA->Add(fListQAt0);\r
-  fListQA->Add(fListQAemcal);\r
-  fListQA->Add(fListQAhmpid);\r
-  fListQA->Add(fListQAtpctof);\r
-  fListQA->Add(fListQAtofhmpid);\r
-  fListQA->Add(fListQAV0);\r
-  fListQA->Add(fListQAinfo);\r
-\r
-  SetupITSqa();\r
-  SetupTPCqa();\r
-  SetupTRDqa();\r
-  SetupTOFqa();\r
-  SetupT0qa();\r
-  SetupEMCALqa();\r
-  SetupHMPIDqa();\r
-  SetupTPCTOFqa();\r
-  SetupTOFHMPIDqa();\r
-  SetupV0qa();\r
-  SetupQAinfo();\r
-  \r
-  PostData(1,fListQA);\r
-}\r
-\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::UserExec(Option_t */*option*/)\r
-{\r
-  //\r
-  // Setup the PID response functions and fill the QA histograms\r
-  //\r
-\r
-  AliVEvent *event=InputEvent();\r
-  if (!event||!fPIDResponse) return;\r
-\r
-  // Start with the V0 task (only possible for ESDs?)\r
-  FillV0PIDlist();\r
-  \r
-  FillITSqa();\r
-  FillTPCqa();\r
-  FillTRDqa();\r
-  FillTOFqa();\r
-  FillEMCALqa();\r
-  FillHMPIDqa();\r
-  FillT0qa();\r
-  \r
-  //combined detector QA\r
-  FillTPCTOFqa();\r
-  FillTOFHMPIDqa();\r
-  \r
-  // Clear the V0 PID arrays\r
-  ClearV0PIDlist();\r
-\r
-  //QA info\r
-  FillQAinfo();\r
-  \r
-  PostData(1,fListQA);\r
-}\r
-\r
-//______________________________________________________________________________\r
-void  AliAnalysisTaskPIDqa::FillV0PIDlist(){\r
-\r
-  //\r
-  // Fill the PID object arrays holding the pointers to identified particle tracks\r
-  //\r
-\r
-  // Dynamic cast to ESD events (DO NOTHING for AOD events)\r
-  AliESDEvent *event = dynamic_cast<AliESDEvent *>(InputEvent());\r
-  if ( !event )  return;\r
-  \r
-  if(TString(event->GetBeamType())=="Pb-Pb" || TString(event->GetBeamType())=="A-A"){\r
-    fV0cuts->SetMode(AliESDv0KineCuts::kPurity,AliESDv0KineCuts::kPbPb); \r
-  }\r
-  else{\r
-    fV0cuts->SetMode(AliESDv0KineCuts::kPurity,AliESDv0KineCuts::kPP); \r
-  }\r
-\r
-  // V0 selection\r
-  // set event\r
-  fV0cuts->SetEvent(event);\r
-\r
-  // loop over V0 particles\r
-  for(Int_t iv0=0; iv0<event->GetNumberOfV0s();iv0++){\r
-\r
-    AliESDv0 *v0 = (AliESDv0 *) event->GetV0(iv0);\r
\r
-    if(!v0) continue;\r
-    if(v0->GetOnFlyStatus()) continue; \r
-  \r
-    // Get the particle selection \r
-    Bool_t foundV0 = kFALSE;\r
-    Int_t pdgV0, pdgP, pdgN;\r
-\r
-    foundV0 = fV0cuts->ProcessV0(v0, pdgV0, pdgP, pdgN);\r
-    if(!foundV0) continue;\r
-    \r
-    Int_t iTrackP = v0->GetPindex();  // positive track\r
-    Int_t iTrackN = v0->GetNindex();  // negative track\r
-\r
-    // v0 Armenteros plot (QA)\r
-    Float_t armVar[2] = {0.0,0.0};\r
-    fV0cuts->Armenteros(v0, armVar);\r
-\r
-    TH2 *h=(TH2*)fListQAV0->At(0);\r
-    if (!h) continue;\r
-    h->Fill(armVar[0],armVar[1]);\r
-\r
-    // fill the Object arrays\r
-    // positive particles\r
-    if( pdgP == -11){\r
-      fV0electrons->Add((AliVTrack*)event->GetTrack(iTrackP));\r
-    }\r
-    else if( pdgP == 211){\r
-      fV0pions->Add((AliVTrack*)event->GetTrack(iTrackP));\r
-    }\r
-    else if( pdgP == 321){\r
-      fV0kaons->Add((AliVTrack*)event->GetTrack(iTrackP));\r
-    }\r
-    else if( pdgP == 2212){\r
-      fV0protons->Add((AliVTrack*)event->GetTrack(iTrackP));\r
-    }\r
-\r
-    // negative particles\r
-    if( pdgN == 11){\r
-      fV0electrons->Add((AliVTrack*)event->GetTrack(iTrackN));\r
-    }\r
-    else if( pdgN == -211){\r
-      fV0pions->Add((AliVTrack*)event->GetTrack(iTrackN));\r
-    }\r
-    else if( pdgN == -321){\r
-      fV0kaons->Add((AliVTrack*)event->GetTrack(iTrackN));\r
-    }\r
-    else if( pdgN == -2212){\r
-      fV0protons->Add((AliVTrack*)event->GetTrack(iTrackN));\r
-    }\r
-  \r
-\r
-  }\r
-}\r
-//______________________________________________________________________________\r
-void  AliAnalysisTaskPIDqa::ClearV0PIDlist(){\r
-\r
-  //\r
-  // Clear the PID object arrays\r
-  //\r
-\r
-  fV0electrons->Clear();\r
-  fV0pions->Clear();\r
-  fV0kaons->Clear();\r
-  fV0protons->Clear();\r
-\r
-}\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillITSqa()\r
-{\r
-  //\r
-  // Fill PID qa histograms for the ITS\r
-  //\r
-\r
-  AliVEvent *event=InputEvent();\r
-  \r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    // ITS refit + ITS pid selection\r
-    if (!( ( (status & AliVTrack::kITSrefit)==AliVTrack::kITSrefit ) ||\r
-          ! ( (status & AliVTrack::kITSpid  )==AliVTrack::kITSpid   ) )) continue;\r
-    Double_t mom=track->P();\r
-    \r
-    TList *theList = 0x0;\r
-    if(( (status & AliVTrack::kTPCin)==AliVTrack::kTPCin )){\r
-      //ITS+TPC tracks\r
-      theList=fListQAits;\r
-    }else{\r
-      if(!( (status & AliVTrack::kITSpureSA)==AliVTrack::kITSpureSA )){ \r
-       //ITS Standalone tracks\r
-       theList=fListQAitsSA;\r
-      }else{\r
-       //ITS Pure Standalone tracks\r
-       theList=fListQAitsPureSA;\r
-      }\r
-    }\r
-    \r
-    \r
-    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-      TH2 *h=(TH2*)theList->At(ispecie);\r
-      if (!h) continue;\r
-      Double_t nSigma=fPIDResponse->NumberOfSigmasITS(track, (AliPID::EParticleType)ispecie);\r
-      h->Fill(mom,nSigma);\r
-    }\r
-    TH2 *h=(TH2*)theList->At(AliPID::kSPECIESC);\r
-    if (h) {\r
-      Double_t sig=track->GetITSsignal();\r
-      h->Fill(mom,sig);\r
-    }\r
-  }\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillTPCqa()\r
-{\r
-  //\r
-  // Fill PID qa histograms for the TPC\r
-  //\r
-  \r
-  AliVEvent *event=InputEvent();\r
-  \r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-    \r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    // TPC refit + ITS refit + TPC pid\r
-    if (!( (status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
-        !( (status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;\r
-\r
-    // The TPC pid cut removes the light nuclei (>5 sigma from proton line)\r
-    //||        !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid  )\r
-    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
-    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
-    if (track->GetTPCNclsF()>0) {\r
-      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
-    }\r
-    \r
-    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
-    \r
-    Double_t mom=track->GetTPCmomentum();\r
-    // the default scenario\r
-    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-      TH2 *h=(TH2*)fListQAtpc->At(ispecie);\r
-      if (!h) continue;\r
-      Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie);\r
-      h->Fill(mom,nSigma);\r
-    }\r
-    // the "hybrid" scenario\r
-    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-      TH2 *h=(TH2*)fListQAtpc->At(ispecie+AliPID::kSPECIESC);\r
-      if (!h) continue;\r
-      Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie, AliTPCPIDResponse::kdEdxHybrid);\r
-      h->Fill(mom,nSigma);\r
-    }\r
-    \r
-    // the "OROC" scenario\r
-    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-      TH2 *h=(TH2*)fListQAtpc->At(ispecie+2*AliPID::kSPECIESC);\r
-      if (!h) continue;\r
-      Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie, AliTPCPIDResponse::kdEdxOROC);\r
-      //TSpline3* spline = fPIDResponse->GetTPCResponse().GetCurrentResponseFunction();\r
-      //std::cout<<ispecie<<" "<<nSigma<<" phi:"<<track->Phi()<<". "<<std::endl;\r
-      //if (spline) {cout<<spline->GetName()<<endl;}\r
-      //else {cout<<"NULL spline"<<endl;}\r
-      h->Fill(mom,nSigma);\r
-    }\r
-    \r
-    TH2 *h=(TH2*)fListQAtpc->At(3*AliPID::kSPECIESC);\r
-\r
-    if (h) {\r
-      Double_t sig=track->GetTPCsignal();\r
-      h->Fill(mom,sig);\r
-    }\r
-  }\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillTRDqa()\r
-{\r
-  //\r
-  // Fill PID qa histograms for the TRD\r
-  //\r
-  AliVEvent *event=InputEvent();\r
-  Int_t ntracks = event->GetNumberOfTracks();\r
-  for(Int_t itrack = 0; itrack <  ntracks; itrack++){\r
-    AliVTrack *track = (AliVTrack *)event->GetTrack(itrack);\r
-\r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    // TPC refit + ITS refit + TPC pid + TRD out\r
-    if (!( (status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
-        !( (status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
-//         !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid  ) || //removes light nuclei. So it is out for the moment\r
-        !( (status & AliVTrack::kTRDout  ) == AliVTrack::kTRDout  )) continue;\r
-    \r
-    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
-    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
-    if (track->GetTPCNclsF()>0) {\r
-      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
-    }\r
-    \r
-    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
-\r
-    Double_t likelihoods[AliPID::kSPECIES];\r
-    if(fPIDResponse->ComputeTRDProbability(track, AliPID::kSPECIES, likelihoods) != AliPIDResponse::kDetPidOk) continue;\r
-    Int_t ntracklets = 0;\r
-    Double_t momentum = -1.;\r
-    for(Int_t itl = 0; itl < 6; itl++)\r
-      if(track->GetTRDmomentum(itl) > 0.){\r
-        ntracklets++;\r
-        if(momentum < 0) momentum = track->GetTRDmomentum(itl);\r
-    } \r
-    for(Int_t ispecie = 0; ispecie < AliPID::kSPECIES; ispecie++){\r
-      TH2F *hLike = (TH2F *)fListQAtrd->At(ntracklets*AliPID::kSPECIES+ispecie);\r
-      if (hLike) hLike->Fill(momentum,likelihoods[ispecie]);\r
-    }\r
-  }\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillTOFqa()\r
-{\r
-  //\r
-  // Fill TOF information\r
-  //\r
-  AliVEvent *event=InputEvent();\r
-\r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-  Int_t tracksAtTof = 0;\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-\r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // TPC refit + ITS refit +\r
-    // TOF out + kTIME\r
-    // kTIME\r
-    // (we don't use kTOFmismatch because it depends on TPC and kTOFpid because it prevents light nuclei\r
-    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
-        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
-        !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||\r
-       //        !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||\r
-        !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;\r
-\r
-    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
-    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
-    if (track->GetTPCNclsF()>0) {\r
-      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
-    }\r
-\r
-    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
-\r
-    tracksAtTof++;\r
-\r
-    Double_t mom=track->P();\r
-\r
-    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-      TH2 *h=(TH2*)fListQAtof->At(ispecie);\r
-      if (!h) continue;\r
-      Double_t nSigma=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);\r
-      h->Fill(mom,nSigma);\r
-    }\r
-\r
-    TH2 *h=(TH2*)fListQAtof->FindObject("hSigP_TOF");\r
-    if (h) {\r
-      Double_t sig=track->GetTOFsignal()/1000.;\r
-      h->Fill(mom,sig);\r
-    }\r
-\r
-    Int_t mask = fPIDResponse->GetTOFResponse().GetStartTimeMask(mom);\r
-    ((TH1F*)fListQAtof->FindObject("hStartTimeMask_TOF"))->Fill((Double_t)(mask+0.5));\r
-\r
-    if (mom >= 0.75 && mom <= 1.25 ) {\r
-      Double_t nsigma= fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)AliPID::kPion);\r
-      if (mask == 0) {\r
-       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-Fill"))->Fill(nsigma);\r
-      } else if (mask == 1) {\r
-       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-TOF"))->Fill(nsigma);\r
-      } else if ( (mask == 2) || (mask == 4) || (mask == 6) ) {\r
-       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-T0"))->Fill(nsigma);\r
-      } else {\r
-       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-Best"))->Fill(nsigma);\r
-      }\r
-      if (mask & 0x1) { //at least TOF-T0 present\r
-       Double_t delta=0;\r
-       (void)fPIDResponse->GetSignalDelta((AliPIDResponse::EDetector)AliPIDResponse::kTOF,track,(AliPID::EParticleType)AliPID::kPion,delta);\r
-       ((TH1F*)fListQAtof->FindObject("hDelta_TOF_Pion"))->Fill(delta);\r
-      }\r
-    }\r
-\r
-    Double_t res = (Double_t)fPIDResponse->GetTOFResponse().GetStartTimeRes(mom);\r
-    ((TH1F*)fListQAtof->FindObject("hStartTimeRes_TOF"))->Fill(res);\r
-\r
-    Double_t startTimeT0 = event->GetT0TOF(0);\r
-    if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeAC_T0"))->Fill(startTimeT0);\r
-    else {\r
-      startTimeT0 = event->GetT0TOF(1);\r
-      if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeA_T0"))->Fill(startTimeT0);\r
-      startTimeT0 = event->GetT0TOF(2);\r
-      if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeC_T0"))->Fill(startTimeT0);\r
-    }\r
-  }\r
-  if (tracksAtTof > 0) {\r
-    ((TH1F* )fListQAtof->FindObject("hnTracksAt_TOF"))->Fill(tracksAtTof);\r
-    Int_t mask = fPIDResponse->GetTOFResponse().GetStartTimeMask(5.);\r
-    if (mask & 0x1) ((TH1F*)fListQAtof->FindObject("hT0MakerEff"))->Fill(tracksAtTof);\r
-  }\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillT0qa()\r
-{\r
-  //\r
-  // Fill TOF information\r
-  //\r
-  AliVEvent *event=InputEvent();\r
-\r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-\r
-  Int_t tracksAtT0 = 0;\r
-\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-\r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // TPC refit + ITS refit +\r
-    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
-        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;\r
-    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
-    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
-    if (track->GetTPCNclsF()>0) {\r
-      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
-    }\r
-    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
-\r
-    tracksAtT0++;\r
-  }\r
-\r
-  Bool_t t0A = kFALSE;\r
-  Bool_t t0C = kFALSE;\r
-  Bool_t t0And = kFALSE;\r
-  Double_t startTimeT0 = event->GetT0TOF(0);     // AND\r
-  if (startTimeT0 < 90000) {\r
-    t0And = kTRUE;\r
-    ((TH1F*)fListQAt0->FindObject("hStartTimeAC_T0"))->Fill(startTimeT0);\r
-    }\r
-  startTimeT0 = event->GetT0TOF(1);             // T0A \r
-  if (startTimeT0 < 90000) {\r
-    t0A = kTRUE;\r
-    ((TH1F*)fListQAt0->FindObject("hStartTimeA_T0"))->Fill(startTimeT0);\r
-    \r
-  }\r
-  startTimeT0 = event->GetT0TOF(2);             // T0C \r
-  if (startTimeT0 < 90000) {\r
-    t0C = kTRUE;\r
-    ((TH1F*)fListQAt0->FindObject("hStartTimeC_T0"))->Fill(startTimeT0);\r
-  }\r
-  \r
-  ((TH1F* )fListQAt0->FindObject("hnTracksAt_T0"))->Fill(tracksAtT0);\r
-  if (t0A) ((TH1F*)fListQAt0->FindObject("hT0AEff"))->Fill(tracksAtT0);\r
-  if (t0C) ((TH1F*)fListQAt0->FindObject("hT0CEff"))->Fill(tracksAtT0);\r
-  if (t0And) ((TH1F*)fListQAt0->FindObject("hT0AndEff"))->Fill(tracksAtT0);\r
-  if (t0A || t0C) ((TH1F*)fListQAt0->FindObject("hT0OrEff"))->Fill(tracksAtT0);\r
-}\r
-\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillEMCALqa()\r
-{\r
-  //\r
-  // Fill PID qa histograms for the EMCAL\r
-  //\r
-\r
-  AliVEvent *event=InputEvent();\r
-  \r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-    \r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
-\r
-    Double_t pt=track->Pt();\r
-   \r
-    //EMCAL nSigma (only for electrons at the moment)\r
-    TH2 *h=(TH2*)fListQAemcal->At(0);\r
-    if (!h) continue;\r
-    Double_t nSigma=fPIDResponse->NumberOfSigmasEMCAL(track, (AliPID::EParticleType)0);\r
-    h->Fill(pt,nSigma);\r
-    \r
-  }\r
-\r
-   //EMCAL signal (E/p vs. pT) for electrons from V0\r
-  for(Int_t itrack = 0; itrack < fV0electrons->GetEntries(); itrack++){\r
-    AliVTrack *track=(AliVTrack*)fV0electrons->At(itrack);\r
-\r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
-\r
-    Double_t pt=track->Pt();\r
-\r
-    TH2 *h=(TH2*)fListQAemcal->At(1);\r
-    if (h) {\r
-\r
-      Int_t nMatchClus = track->GetEMCALcluster();\r
-      Double_t mom     = track->P();\r
-      Double_t eop     = -1.;\r
-\r
-      if(nMatchClus > -1){\r
-    \r
-        AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
-\r
-        if(matchedClus){\r
-\r
-          // matched cluster is EMCAL\r
-          if(matchedClus->IsEMCAL()){\r
-\r
-            Double_t fClsE       = matchedClus->E();\r
-            eop                  = fClsE/mom;\r
-\r
-            h->Fill(pt,eop);\r
-\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-   //EMCAL signal (E/p vs. pT) for pions from V0\r
-  for(Int_t itrack = 0; itrack < fV0pions->GetEntries(); itrack++){\r
-    AliVTrack *track=(AliVTrack*)fV0pions->At(itrack);\r
-\r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
-\r
-    Double_t pt=track->Pt();\r
-\r
-    TH2 *h=(TH2*)fListQAemcal->At(2);\r
-    if (h) {\r
-\r
-      Int_t nMatchClus = track->GetEMCALcluster();\r
-      Double_t mom     = track->P();\r
-      Double_t eop     = -1.;\r
-\r
-      if(nMatchClus > -1){\r
-    \r
-        AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
-\r
-        if(matchedClus){\r
-\r
-          // matched cluster is EMCAL\r
-          if(matchedClus->IsEMCAL()){\r
-\r
-            Double_t fClsE       = matchedClus->E();\r
-            eop                  = fClsE/mom;\r
-\r
-            h->Fill(pt,eop);\r
-\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-   //EMCAL signal (E/p vs. pT) for protons from V0\r
-  for(Int_t itrack = 0; itrack < fV0protons->GetEntries(); itrack++){\r
-    AliVTrack *track=(AliVTrack*)fV0protons->At(itrack);\r
-\r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;\r
-\r
-    Double_t pt=track->Pt();\r
-\r
-    TH2 *hP=(TH2*)fListQAemcal->At(3);\r
-    TH2 *hAP=(TH2*)fListQAemcal->At(4);\r
-    if (hP && hAP) {\r
-\r
-      Int_t nMatchClus = track->GetEMCALcluster();\r
-      Double_t mom     = track->P();\r
-      Int_t charge     = track->Charge();            \r
-      Double_t eop     = -1.;\r
-\r
-      if(nMatchClus > -1){\r
-    \r
-        AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
-\r
-        if(matchedClus){\r
-\r
-          // matched cluster is EMCAL\r
-          if(matchedClus->IsEMCAL()){\r
-\r
-            Double_t fClsE       = matchedClus->E();\r
-            eop                  = fClsE/mom;\r
-\r
-            if(charge > 0)      hP->Fill(pt,eop);\r
-            else if(charge < 0) hAP->Fill(pt,eop);\r
-\r
-          }\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
-\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillHMPIDqa()\r
-{\r
-  //\r
-  // Fill PID qa histograms for the HMPID\r
-  //\r
-  \r
-  AliVEvent *event=InputEvent();\r
-  \r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-    \r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    // TPC refit + ITS refit +\r
-    // TOF out + TOFpid +\r
-    // kTIME\r
-    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
-        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;\r
-\r
-    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
-    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
-    if (track->GetTPCNclsF()>0) {\r
-      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
-    }\r
-\r
-    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
-    \r
-    Double_t mom = track->P();\r
-    Double_t ckovAngle = track->GetHMPIDsignal();\r
-    \r
-    TH1F *hThetavsMom = (TH1F*)fListQAhmpid->At(0);;\r
-    \r
-    hThetavsMom->Fill(mom,ckovAngle);    \r
-  \r
-  }\r
-}\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillTOFHMPIDqa()\r
-{\r
-  //\r
-  // Fill PID qa histograms for the HMPID\r
-  //\r
-  \r
-  AliVEvent *event=InputEvent();\r
-  \r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-    \r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    // TPC refit + ITS refit +\r
-    // TOF out + TOFpid +\r
-    // kTIME\r
-    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
-        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
-        !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||\r
-        !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||\r
-        !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;\r
-\r
-    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
-    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
-    if (track->GetTPCNclsF()>0) {\r
-      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
-    }\r
-\r
-    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
-    \r
-    Double_t mom = track->P();\r
-    Double_t ckovAngle = track->GetHMPIDsignal();\r
-    \r
-    Double_t nSigmaTOF[3]; \r
-    TH1F *h[3];\r
-    \r
-    for (Int_t ispecie=2; ispecie<5; ++ispecie){\r
-      //TOF nSigma\r
-      nSigmaTOF[ispecie-2]=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);\r
-      h[ispecie-2] = (TH1F*)fListQAtofhmpid->At(ispecie-2);}\r
-      \r
-    if(TMath::Abs(nSigmaTOF[0])<2)                                                              h[0]->Fill(mom,ckovAngle);\r
-    \r
-    if(TMath::Abs(nSigmaTOF[1])<2 && TMath::Abs(nSigmaTOF[0])>3)                                h[1]->Fill(mom,ckovAngle);\r
-\r
-    if(TMath::Abs(nSigmaTOF[2])<2 && TMath::Abs(nSigmaTOF[1])>3 && TMath::Abs(nSigmaTOF[0])>3)  h[2]->Fill(mom,ckovAngle);\r
-      \r
-  }\r
-  \r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillTPCTOFqa()\r
-{\r
-  //\r
-  // Fill PID qa histograms for the TOF\r
-  //   Here also the TPC histograms after TOF selection are filled\r
-  //\r
-\r
-  AliVEvent *event=InputEvent();\r
-\r
-  Int_t ntracks=event->GetNumberOfTracks();\r
-  for(Int_t itrack = 0; itrack < ntracks; itrack++){\r
-    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);\r
-\r
-    //\r
-    //basic track cuts\r
-    //\r
-    ULong_t status=track->GetStatus();\r
-    // not that nice. status bits not in virtual interface\r
-    // TPC refit + ITS refit +\r
-    // TOF out + TOFpid +\r
-    // kTIME\r
-    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||\r
-        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||\r
-//         !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid ) || //removes light nuclei, so it is out for the moment\r
-        !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||\r
-        !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||\r
-        !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;\r
-\r
-    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);\r
-    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;\r
-    if (track->GetTPCNclsF()>0) {\r
-      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();\r
-    }\r
-\r
-    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;\r
-\r
-\r
-    Double_t mom=track->P();\r
-    Double_t momTPC=track->GetTPCmomentum();\r
-\r
-    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-      //TOF nSigma\r
-      Double_t nSigmaTOF=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);\r
-      Double_t nSigmaTPC=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie);\r
-\r
-      //TPC after TOF cut\r
-      TH2 *h=(TH2*)fListQAtpctof->At(ispecie);\r
-      if (h && TMath::Abs(nSigmaTOF)<3.) h->Fill(momTPC,nSigmaTPC);\r
-\r
-      //TOF after TPC cut\r
-      h=(TH2*)fListQAtpctof->At(ispecie+AliPID::kSPECIESC);\r
-      if (h && TMath::Abs(nSigmaTPC)<3.) h->Fill(mom,nSigmaTOF);\r
-\r
-      //EMCAL after TOF and TPC cut\r
-      h=(TH2*)fListQAtpctof->At(ispecie+2*AliPID::kSPECIESC);\r
-      if (h && TMath::Abs(nSigmaTOF)<3. && TMath::Abs(nSigmaTPC)<3. ){\r
-\r
-       Int_t nMatchClus = track->GetEMCALcluster();\r
-       Double_t pt      = track->Pt();\r
-       Double_t eop     = -1.;\r
-       \r
-       if(nMatchClus > -1){\r
-         \r
-         AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);\r
-         \r
-         if(matchedClus){\r
-           \r
-           // matched cluster is EMCAL\r
-           if(matchedClus->IsEMCAL()){\r
-             \r
-             Double_t fClsE       = matchedClus->E();\r
-             eop                  = fClsE/mom;\r
-\r
-             h->Fill(pt,eop);\r
\r
-             \r
-           }\r
-         }\r
-       }\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-//_____________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::FillQAinfo()\r
-{\r
-  //\r
-  // Fill the QA information\r
-  //\r
-\r
-\r
-  //TPC QA info\r
-  TObjArray *arrTPC=static_cast<TObjArray*>(fListQAinfo->At(0));\r
-  if (fPIDResponse && arrTPC){\r
-    AliTPCPIDResponse &tpcResp=fPIDResponse->GetTPCResponse();\r
-    // fill spline names\r
-    if (!arrTPC->UncheckedAt(0)){\r
-      \r
-      TObjArray *arrTPCsplineNames=new TObjArray(AliPID::kSPECIESC);\r
-      arrTPCsplineNames->SetOwner();\r
-      arrTPCsplineNames->SetName("TPC_spline_names");\r
-      arrTPC->AddAt(arrTPCsplineNames,0);\r
-      \r
-      for (Int_t iresp=0; iresp<AliPID::kSPECIESC; ++iresp){\r
-        const TObject *o=tpcResp.GetResponseFunction((AliPID::EParticleType)iresp);\r
-        if (!o) continue;\r
-        arrTPCsplineNames->Add(new TObjString(Form("%02d: %s",iresp, o->GetName())));\r
-      }\r
-    }\r
-\r
-    // tpc response config\r
-    if (!arrTPC->UncheckedAt(1)){\r
-      \r
-      TObjArray *arrTPCconfigInfo=new TObjArray;\r
-      arrTPCconfigInfo->SetOwner();\r
-      arrTPCconfigInfo->SetName("TPC_config_info");\r
-      arrTPC->AddAt(arrTPCconfigInfo,1);\r
-\r
-      TObjString *ostr=0x0;\r
-      ostr=new TObjString;\r
-      ostr->String().Form("Eta Corr map: %s", tpcResp.GetEtaCorrMap()?tpcResp.GetEtaCorrMap()->GetName():"none");\r
-      arrTPCconfigInfo->Add(ostr);\r
-\r
-      ostr=new TObjString;\r
-      ostr->String().Form("Sigma Par map: %s", tpcResp.GetSigmaPar1Map()?tpcResp.GetSigmaPar1Map()->GetName():"none");\r
-      arrTPCconfigInfo->Add(ostr);\r
-\r
-      ostr=new TObjString;\r
-      ostr->String().Form("MIP: %.2f", tpcResp.GetMIP());\r
-      arrTPCconfigInfo->Add(ostr);\r
-      \r
-      ostr=new TObjString;\r
-      ostr->String().Form("Res: Def %.3g (%.3g) : AllHigh %.3g (%.3g) : OROC high %.3g (%.3g)",\r
-                          tpcResp.GetRes0(AliTPCPIDResponse::kDefault), tpcResp.GetResN2(AliTPCPIDResponse::kDefault),\r
-                          tpcResp.GetRes0(AliTPCPIDResponse::kALLhigh), tpcResp.GetResN2(AliTPCPIDResponse::kALLhigh),\r
-                          tpcResp.GetRes0(AliTPCPIDResponse::kOROChigh), tpcResp.GetResN2(AliTPCPIDResponse::kOROChigh)\r
-                         );\r
-      arrTPCconfigInfo->Add(ostr);\r
-    }\r
-  }\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupITSqa()\r
-{\r
-  //\r
-  // Create the ITS qa objects\r
-  //\r
-  \r
-  TVectorD *vX=MakeLogBinning(200,.1,30);\r
-  \r
-  //ITS+TPC tracks\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_ITS_%s",AliPID::ParticleName(ispecie)),\r
-                              Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                              200,-10,10);\r
-    fListQAits->Add(hNsigmaP);\r
-  }\r
-  TH2F *hSig = new TH2F("hSigP_ITS",\r
-                        "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",\r
-                        vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                        300,0,300);\r
-  fListQAits->Add(hSig);\r
-\r
-  //ITS Standalone tracks\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaPSA = new TH2F(Form("hNsigmaP_ITSSA_%s",AliPID::ParticleName(ispecie)),\r
-                               Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                               vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                               200,-10,10);\r
-    fListQAitsSA->Add(hNsigmaPSA);\r
-  }\r
-  TH2F *hSigSA = new TH2F("hSigP_ITSSA",\r
-                         "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",\r
-                         vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                         300,0,300);\r
-  fListQAitsSA->Add(hSigSA);\r
-  \r
-  //ITS Pure Standalone tracks\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaPPureSA = new TH2F(Form("hNsigmaP_ITSPureSA_%s",AliPID::ParticleName(ispecie)),\r
-                                   Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                                   vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                                   200,-10,10);\r
-    fListQAitsPureSA->Add(hNsigmaPPureSA);\r
-  }\r
-  TH2F *hSigPureSA = new TH2F("hSigP_ITSPureSA",\r
-                             "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",\r
-                             vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                             300,0,300);\r
-  fListQAitsPureSA->Add(hSigPureSA);\r
-  \r
-  delete vX;  \r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupTPCqa()\r
-{\r
-  //\r
-  // Create the TPC qa objects\r
-  //\r
-  \r
-  TVectorD *vX=MakeLogBinning(200,.1,30);\r
-  \r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s",AliPID::ParticleName(ispecie)),\r
-                              Form("TPC n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                              200,-10,10);\r
-    fListQAtpc->Add(hNsigmaP);\r
-  }\r
-\r
-  // the "hybrid" scenario\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s_Hybrid",AliPID::ParticleName(ispecie)),\r
-                              Form("TPC n#sigma %s vs. p (Hybrid gain scenario);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                              200,-10,10);\r
-    fListQAtpc->Add(hNsigmaP);\r
-  }\r
-   \r
-  // the "OROC high" scenario\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s_OROChigh",AliPID::ParticleName(ispecie)),\r
-                              Form("TPC n#sigma %s vs. p (OROChigh gain scenario);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                              200,-10,10);\r
-    fListQAtpc->Add(hNsigmaP);\r
-  }\r
-  \r
-  \r
-  \r
-  TH2F *hSig = new TH2F("hSigP_TPC",\r
-                        "TPC signal vs. p;p [GeV]; TPC signal [arb. units]",\r
-                        vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                        300,0,300);\r
-  fListQAtpc->Add(hSig); //3*AliPID::kSPECIESC\r
-\r
-  delete vX;  \r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupTRDqa()\r
-{\r
-  //\r
-  // Create the TRD qa objects\r
-  //\r
-  TVectorD *vX=MakeLogBinning(200,.1,30);\r
-  for(Int_t itl = 0; itl < 6; ++itl){\r
-    for(Int_t ispecie = 0; ispecie < AliPID::kSPECIES; ispecie++){\r
-      TH2F *hLikeP = new TH2F(Form("hLikeP_TRD_%dtls_%s", itl, AliPID::ParticleName(ispecie)),\r
-                              Form("TRD Likelihood to be %s %s for tracks having %d %s; p (GeV/c); TRD %s Likelihood", ispecie == 0 ? "an" : "a", AliPID::ParticleName(ispecie), itl+1, itl == 0 ? "tracklet" : "tracklets", AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1, vX->GetMatrixArray(),\r
-                              100, 0., 1.);\r
-      fListQAtrd->Add(hLikeP);\r
-    }\r
-  }\r
-  delete vX;\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupTOFqa()\r
-{\r
-  //\r
-  // Create the TOF qa objects\r
-  //\r
-  \r
-  TVectorD *vX=MakeLogBinning(200,.1,30);\r
-\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TOF_%s",AliPID::ParticleName(ispecie)),\r
-                              Form("TOF n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                              200,-10,10);\r
-    fListQAtof->Add(hNsigmaP);\r
-  }\r
-\r
-  TH1F *hnSigT0Fill = new TH1F("hNsigma_TOF_Pion_T0-Fill","TOF n#sigma (Pion) T0-FILL [0.75-1.25. GeV/c]",200,-10,10);\r
-  fListQAtof->Add(hnSigT0Fill);\r
-  TH1F *hnSigT0T0 = new TH1F("hNsigma_TOF_Pion_T0-T0","TOF n#sigma (Pion) T0-T0 [0.75-1.25 GeV/c]",200,-10,10);\r
-  fListQAtof->Add(hnSigT0T0);\r
-  TH1F *hnSigT0TOF = new TH1F("hNsigma_TOF_Pion_T0-TOF","TOF n#sigma (Pion) T0-TOF [0.75-1.25 GeV/c]",200,-10,10);\r
-  fListQAtof->Add(hnSigT0TOF);\r
-  TH1F *hnSigT0Best = new TH1F("hNsigma_TOF_Pion_T0-Best","TOF n#sigma (Pion) T0-Best [0.75-1.25 GeV/c]",200,-10,10);\r
-  fListQAtof->Add(hnSigT0Best);\r
-  TH1F *hnDeltaPi = new TH1F("hDelta_TOF_Pion","DeltaT (Pion) [0.75-1.25 GeV/c]",50,-500,500);\r
-  fListQAtof->Add(hnDeltaPi);\r
-  \r
-  TH2F *hSig = new TH2F("hSigP_TOF",\r
-                        "TOF signal vs. p;p [GeV]; TOF signal [ns]",\r
-                        vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                        300,0,30);\r
-\r
-  delete vX;\r
-  \r
-  fListQAtof->Add(hSig);\r
-\r
-  TH1F *hStartTimeMaskTOF = new TH1F("hStartTimeMask_TOF","StartTime mask",8,0,8);\r
-  fListQAtof->Add(hStartTimeMaskTOF);\r
-  TH1F *hStartTimeResTOF = new TH1F("hStartTimeRes_TOF","StartTime resolution [ps]",100,0,500);\r
-  fListQAtof->Add(hStartTimeResTOF);\r
-\r
-  TH1F *hnTracksAtTOF = new TH1F("hnTracksAt_TOF","Matched tracks at TOF",100,0,100);\r
-  fListQAtof->Add(hnTracksAtTOF);\r
-  TH1F *hT0MakerEff = new TH1F("hT0MakerEff","Events with T0-TOF vs nTracks",100,0,100);\r
-  fListQAtof->Add(hT0MakerEff);\r
-\r
-  // this in principle should stay on a T0 PID QA, but are just the data prepared for TOF use\r
-  TH1F *hStartTimeAT0 = new TH1F("hStartTimeA_T0","StartTime from T0A [ps]",1000,-1000,1000);\r
-  fListQAtof->Add(hStartTimeAT0);\r
-  TH1F *hStartTimeCT0 = new TH1F("hStartTimeC_T0","StartTime from T0C [ps]",1000,-1000,1000);\r
-  fListQAtof->Add(hStartTimeCT0);\r
-  TH1F *hStartTimeACT0 = new TH1F("hStartTimeAC_T0","StartTime from T0AC [ps]",1000,-1000,1000);;\r
-  fListQAtof->Add(hStartTimeACT0);\r
-}\r
-\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupT0qa()\r
-{\r
-  //\r
-  // Create the T0 qa objects\r
-  //\r
-  \r
-  // these are similar to plots inside TOFqa, but these are for all events\r
-  TH1F *hStartTimeAT0 = new TH1F("hStartTimeA_T0","StartTime from T0A [ps]",1000,-1000,1000);\r
-  fListQAt0->Add(hStartTimeAT0);\r
-  TH1F *hStartTimeCT0 = new TH1F("hStartTimeC_T0","StartTime from T0C [ps]",1000,-1000,1000);\r
-  fListQAt0->Add(hStartTimeCT0);\r
-  TH1F *hStartTimeACT0 = new TH1F("hStartTimeAC_T0","StartTime from T0AC [ps]",1000,-1000,1000);;\r
-  fListQAt0->Add(hStartTimeACT0);\r
-\r
-  TH1F *hnTracksAtT0 = new TH1F("hnTracksAt_T0","Tracks for events selected for T0",100,0,100);\r
-  fListQAt0->Add(hnTracksAtT0);\r
-  TH1F *hT0AEff = new TH1F("hT0AEff","Events with T0A vs nTracks",100,0,100);\r
-  fListQAt0->Add(hT0AEff);\r
-  TH1F *hT0CEff = new TH1F("hT0CEff","Events with T0C vs nTracks",100,0,100);\r
-  fListQAt0->Add(hT0CEff);\r
-  TH1F *hT0AndEff = new TH1F("hT0AndEff","Events with T0AC (AND) vs nTracks",100,0,100);\r
-  fListQAt0->Add(hT0AndEff);\r
-  TH1F *hT0OrEff = new TH1F("hT0OrEff","Events with T0AC (OR) vs nTracks",100,0,100);\r
-  fListQAt0->Add(hT0OrEff);\r
-\r
-\r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupEMCALqa()\r
-{\r
-  //\r
-  // Create the EMCAL qa objects\r
-  //\r
-\r
-  TVectorD *vX=MakeLogBinning(200,.1,30);\r
-  \r
-  TH2F *hNsigmaPt = new TH2F(Form("hNsigmaPt_EMCAL_%s",AliPID::ParticleName(0)),\r
-                            Form("EMCAL n#sigma %s vs. p_{T};p_{T} [GeV]; n#sigma",AliPID::ParticleName(0)),\r
-                            vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                            200,-10,10);\r
-  fListQAemcal->Add(hNsigmaPt);  \r
-  \r
-\r
-  TH2F *hSigPtEle = new TH2F("hSigPt_EMCAL_Ele",\r
-                        "EMCAL signal (E/p) vs. p_{T} for electrons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
-                        vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                        200,0,2);\r
-  fListQAemcal->Add(hSigPtEle);\r
-\r
-  TH2F *hSigPtPions = new TH2F("hSigPt_EMCAL_Pions",\r
-                        "EMCAL signal (E/p) vs. p_{T} for pions;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
-                        vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                        200,0,2);\r
-  fListQAemcal->Add(hSigPtPions);\r
-\r
-  TH2F *hSigPtProtons = new TH2F("hSigPt_EMCAL_Protons",\r
-                        "EMCAL signal (E/p) vs. p_{T} for protons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
-                        vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                        200,0,2);\r
-  fListQAemcal->Add(hSigPtProtons);\r
-\r
-  TH2F *hSigPtAntiProtons = new TH2F("hSigPt_EMCAL_Antiprotons",\r
-                        "EMCAL signal (E/p) vs. p_{T} for antiprotons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",\r
-                        vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                        200,0,2);\r
-  fListQAemcal->Add(hSigPtAntiProtons);\r
-\r
-  delete vX;  \r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupHMPIDqa()\r
-{\r
-  //\r
-  // Create the HMPID qa objects\r
-  //\r
-  \r
-  TH2F *hCkovAnglevsMom   = new TH2F("hCkovAnglevsMom",  "Cherenkov angle vs momnetum",500,0,5.,500,0,1);\r
-  fListQAhmpid->Add(hCkovAnglevsMom);\r
-  \r
-}\r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupTOFHMPIDqa()\r
-{\r
-  //\r
-  // Create the HMPID qa objects\r
-  //\r
-  \r
-  TH2F *hCkovAnglevsMomPion   = new TH2F("hCkovAnglevsMom_pion",  "Cherenkov angle vs momnetum for pions",500,0,5.,500,0,1);\r
-  fListQAtofhmpid->Add(hCkovAnglevsMomPion);\r
-  \r
-  TH2F *hCkovAnglevsMomKaon   = new TH2F("hCkovAnglevsMom_kaon",  "Cherenkov angle vs momnetum for kaons",500,0,5.,500,0,1);\r
-  fListQAtofhmpid->Add(hCkovAnglevsMomKaon);\r
-  \r
-  TH2F *hCkovAnglevsMomProton = new TH2F("hCkovAnglevsMom_proton","Cherenkov angle vs momnetum for protons",500,0,5.,500,0,1);\r
-  fListQAtofhmpid->Add(hCkovAnglevsMomProton);\r
-  \r
-  \r
-}  \r
-\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupTPCTOFqa()\r
-{\r
-  //\r
-  // Create the qa objects for TPC + TOF combination\r
-  //\r
-  \r
-  TVectorD *vX=MakeLogBinning(200,.1,30);\r
-\r
-  //TPC signals after TOF cut\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_TOF_%s",AliPID::ParticleName(ispecie)),\r
-                              Form("TPC n#sigma %s vs. p (after TOF 3#sigma cut);p_{TPC} [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                              200,-10,10);\r
-    fListQAtpctof->Add(hNsigmaP);\r
-  }\r
-\r
-  //TOF signals after TPC cut\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){\r
-    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TOF_TPC_%s",AliPID::ParticleName(ispecie)),\r
-                              Form("TOF n#sigma %s vs. p (after TPC n#sigma cut);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),\r
-                              vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                              200,-10,10);\r
-    fListQAtpctof->Add(hNsigmaP);\r
-  }\r
-\r
-  //EMCAL signal after TOF and TPC cut\r
-  for (Int_t ispecie=0; ispecie<AliPID::kSPECIES; ++ispecie){\r
-    TH2F *heopPt = new TH2F(Form("heopPt_TOF_TPC_%s",AliPID::ParticleName(ispecie)),\r
-                           Form("EMCAL signal (E/p) %s vs. p_{T};p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",AliPID::ParticleName(ispecie)),\r
-                           vX->GetNrows()-1,vX->GetMatrixArray(),\r
-                           200,0,2);\r
-    fListQAtpctof->Add(heopPt);\r
-  }\r
-\r
-  delete vX;\r
-}\r
-//______________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupV0qa()\r
-{\r
-  //\r
-  // Create the qa objects for V0 Kine cuts\r
-  //\r
-  \r
-  TH2F *hArmenteros  = new TH2F("hArmenteros",  "Armenteros plot",200,-1.,1.,200,0.,0.4);\r
-  fListQAV0->Add(hArmenteros);\r
\r
-}\r
-\r
-//_____________________________________________________________________________\r
-void AliAnalysisTaskPIDqa::SetupQAinfo(){\r
-  //\r
-  // Setup the info of QA objects\r
-  //\r
-\r
-  TObjArray *arr=new TObjArray;\r
-  arr->SetName("TPC_info");\r
-  fListQAinfo->Add(arr);\r
-}\r
-\r
-//______________________________________________________________________________\r
-TVectorD* AliAnalysisTaskPIDqa::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)\r
-{\r
-  //\r
-  // Make logarithmic binning\r
-  // the user has to delete the array afterwards!!!\r
-  //\r
-  \r
-  //check limits\r
-  if (xmin<1e-20 || xmax<1e-20){\r
-    AliError("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");\r
-    return MakeLinBinning(nbinsX, xmin, xmax);\r
-  }\r
-  if (xmax<xmin){\r
-    Double_t tmp=xmin;\r
-    xmin=xmax;\r
-    xmax=tmp;\r
-  }\r
-  TVectorD *binLim=new TVectorD(nbinsX+1);\r
-  Double_t first=xmin;\r
-  Double_t last=xmax;\r
-  Double_t expMax=TMath::Log(last/first);\r
-  for (Int_t i=0; i<nbinsX+1; ++i){\r
-    (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);\r
-  }\r
-  return binLim;\r
-}\r
-\r
-//______________________________________________________________________________\r
-TVectorD* AliAnalysisTaskPIDqa::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)\r
-{\r
-  //\r
-  // Make linear binning\r
-  // the user has to delete the array afterwards!!!\r
-  //\r
-  if (xmax<xmin){\r
-    Double_t tmp=xmin;\r
-    xmin=xmax;\r
-    xmax=tmp;\r
-  }\r
-  TVectorD *binLim=new TVectorD(nbinsX+1);\r
-  Double_t first=xmin;\r
-  Double_t last=xmax;\r
-  Double_t binWidth=(last-first)/nbinsX;\r
-  for (Int_t i=0; i<nbinsX+1; ++i){\r
-    (*binLim)[i]=first+binWidth*(Double_t)i;\r
-  }\r
-  return binLim;\r
-}\r
-\r
-//_____________________________________________________________________________\r
-TVectorD* AliAnalysisTaskPIDqa::MakeArbitraryBinning(const char* bins)\r
-{\r
-  //\r
-  // Make arbitrary binning, bins separated by a ','\r
-  //\r
-  TString limits(bins);\r
-  if (limits.IsNull()){\r
-    AliError("Bin Limit string is empty, cannot add the variable");\r
-    return 0x0;\r
-  }\r
-  \r
-  TObjArray *arr=limits.Tokenize(",");\r
-  Int_t nLimits=arr->GetEntries();\r
-  if (nLimits<2){\r
-    AliError("Need at leas 2 bin limits, cannot add the variable");\r
-    delete arr;\r
-    return 0x0;\r
-  }\r
-  \r
-  TVectorD *binLimits=new TVectorD(nLimits);\r
-  for (Int_t iLim=0; iLim<nLimits; ++iLim){\r
-    (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();\r
-  }\r
-  \r
-  delete arr;\r
-  return binLimits;\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.                  *
+ **************************************************************************/
+
+/* $Id: AliAnalysisTaskPIDqa.cxx 43811 2010-09-23 14:13:31Z wiechula $ */
+#include <TList.h>
+#include <TVectorD.h>
+#include <TObjArray.h>
+#include <TH2.h>
+#include <TFile.h>
+#include <TPRegexp.h>
+#include <TChain.h>
+#include <TF1.h>
+#include <TSpline.h>
+
+#include <AliAnalysisManager.h>
+#include <AliInputEventHandler.h>
+#include <AliVEventHandler.h>
+#include <AliVEvent.h>
+#include <AliVParticle.h>
+#include <AliVTrack.h>
+#include <AliLog.h>
+#include <AliPID.h>
+#include <AliPIDResponse.h>
+#include <AliITSPIDResponse.h>
+#include <AliTPCPIDResponse.h>
+#include <AliTRDPIDResponse.h>
+#include <AliTOFPIDResponse.h>
+
+#include <AliESDEvent.h>
+#include <AliAODEvent.h>
+#include <AliESDv0.h>
+#include <AliAODv0.h>
+#include <AliESDv0KineCuts.h>
+
+#include "AliAnalysisTaskPIDqa.h"
+
+
+ClassImp(AliAnalysisTaskPIDqa)
+
+//______________________________________________________________________________
+AliAnalysisTaskPIDqa::AliAnalysisTaskPIDqa():
+AliAnalysisTaskSE(),
+fPIDResponse(0x0),
+fV0cuts(0x0),
+fV0electrons(0x0),
+fV0pions(0x0),
+fV0kaons(0x0),
+fV0protons(0x0),
+fListQA(0x0),
+fListQAits(0x0),
+fListQAitsSA(0x0),
+fListQAitsPureSA(0x0),
+fListQAtpc(0x0),
+fListQAtrd(0x0),
+fListQAtof(0x0),
+fListQAt0(0x0),
+fListQAemcal(0x0),
+fListQAhmpid(0x0),
+fListQAtofhmpid(0x0),
+fListQAtpctof(0x0),
+fListQAV0(0x0),
+fListQAinfo(0x0)
+{
+  //
+  // Dummy constructor
+  //
+}
+
+//______________________________________________________________________________
+AliAnalysisTaskPIDqa::AliAnalysisTaskPIDqa(const char* name):
+AliAnalysisTaskSE(name),
+fPIDResponse(0x0),
+fV0cuts(0x0),
+fV0electrons(0x0),
+fV0pions(0x0),
+fV0kaons(0x0),
+fV0protons(0x0),
+fListQA(0x0),
+fListQAits(0x0),
+fListQAitsSA(0x0),
+fListQAitsPureSA(0x0),
+fListQAtpc(0x0),
+fListQAtrd(0x0),
+fListQAtof(0x0),
+fListQAt0(0x0),
+fListQAemcal(0x0),
+fListQAhmpid(0x0),
+fListQAtofhmpid(0x0),
+fListQAtpctof(0x0),
+fListQAV0(0x0),
+fListQAinfo(0x0)
+{
+  //
+  // Default constructor
+  //
+  DefineInput(0,TChain::Class());
+  DefineOutput(1,TList::Class());
+}
+
+//______________________________________________________________________________
+AliAnalysisTaskPIDqa::~AliAnalysisTaskPIDqa()
+{
+  //
+  // Destructor
+  //
+
+  delete fV0cuts;
+  delete fV0electrons;
+  delete fV0pions;
+  delete fV0kaons;
+  delete fV0protons;
+
+  if (!AliAnalysisManager::GetAnalysisManager()->IsProofMode()) delete fListQA;
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::UserCreateOutputObjects()
+{
+  //
+  // Create the output QA objects
+  //
+
+  AliLog::SetClassDebugLevel("AliAnalysisTaskPIDqa",10);
+
+  //input hander
+  AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
+  AliInputEventHandler *inputHandler=dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());
+  if (!inputHandler) AliFatal("Input handler needed");
+
+  //pid response object
+  fPIDResponse=inputHandler->GetPIDResponse();
+  if (!fPIDResponse) AliError("PIDResponse object was not created");
+  
+  // V0 Kine cuts 
+  fV0cuts = new AliESDv0KineCuts;
+  // V0 PID Obj arrays
+  fV0electrons = new TObjArray;
+  fV0pions     = new TObjArray;
+  fV0kaons     = new TObjArray;
+  fV0protons   = new TObjArray;
+
+  //
+  fListQA=new TList;
+  fListQA->SetOwner();
+  
+  fListQAits=new TList;
+  fListQAits->SetOwner();
+  fListQAits->SetName("ITS");
+
+  fListQAitsSA=new TList;
+  fListQAitsSA->SetOwner();
+  fListQAitsSA->SetName("ITS_SA");
+
+  fListQAitsPureSA=new TList;
+  fListQAitsPureSA->SetOwner();
+  fListQAitsPureSA->SetName("ITS_PureSA");
+
+  fListQAtpc=new TList;
+  fListQAtpc->SetOwner();
+  fListQAtpc->SetName("TPC");
+  
+  fListQAtrd=new TList;
+  fListQAtrd->SetOwner();
+  fListQAtrd->SetName("TRD");
+  
+  fListQAtof=new TList;
+  fListQAtof->SetOwner();
+  fListQAtof->SetName("TOF");
+
+  fListQAt0=new TList;
+  fListQAt0->SetOwner();
+  fListQAt0->SetName("T0");
+  
+  fListQAemcal=new TList;
+  fListQAemcal->SetOwner();
+  fListQAemcal->SetName("EMCAL");
+  
+  fListQAhmpid=new TList;
+  fListQAhmpid->SetOwner();
+  fListQAhmpid->SetName("HMPID");
+  
+  fListQAtpctof=new TList;
+  fListQAtpctof->SetOwner();
+  fListQAtpctof->SetName("TPC_TOF");
+
+  fListQAtofhmpid=new TList;
+  fListQAtofhmpid->SetOwner();
+  fListQAtofhmpid->SetName("TOF_HMPID");
+  
+  fListQAV0=new TList;
+  fListQAV0->SetOwner();
+  fListQAV0->SetName("V0decay");
+
+  fListQAinfo=new TList;
+  fListQAinfo->SetOwner();
+  fListQAinfo->SetName("QAinfo");
+  
+  fListQA->Add(fListQAits);
+  fListQA->Add(fListQAitsSA);
+  fListQA->Add(fListQAitsPureSA);
+  fListQA->Add(fListQAtpc);
+  fListQA->Add(fListQAtrd);
+  fListQA->Add(fListQAtof);
+  fListQA->Add(fListQAt0);
+  fListQA->Add(fListQAemcal);
+  fListQA->Add(fListQAhmpid);
+  fListQA->Add(fListQAtpctof);
+  fListQA->Add(fListQAtofhmpid);
+  fListQA->Add(fListQAV0);
+  fListQA->Add(fListQAinfo);
+
+  SetupITSqa();
+  SetupTPCqa();
+  SetupTRDqa();
+  SetupTOFqa();
+  SetupT0qa();
+  SetupEMCALqa();
+  SetupHMPIDqa();
+  SetupTPCTOFqa();
+  SetupTOFHMPIDqa();
+  SetupV0qa();
+  SetupQAinfo();
+  
+  PostData(1,fListQA);
+}
+
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::UserExec(Option_t */*option*/)
+{
+  //
+  // Setup the PID response functions and fill the QA histograms
+  //
+
+  AliVEvent *event=InputEvent();
+  if (!event||!fPIDResponse) return;
+
+  // Start with the V0 task (only possible for ESDs?)
+  FillV0PIDlist();
+  
+  FillITSqa();
+  FillTPCqa();
+  FillTRDqa();
+  FillTOFqa();
+  FillEMCALqa();
+  FillHMPIDqa();
+  FillT0qa();
+  
+  //combined detector QA
+  FillTPCTOFqa();
+  FillTOFHMPIDqa();
+  
+  // Clear the V0 PID arrays
+  ClearV0PIDlist();
+
+  //QA info
+  FillQAinfo();
+  
+  PostData(1,fListQA);
+}
+
+//______________________________________________________________________________
+void  AliAnalysisTaskPIDqa::FillV0PIDlist(){
+
+  //
+  // Fill the PID object arrays holding the pointers to identified particle tracks
+  //
+
+  // Dynamic cast to ESD events (DO NOTHING for AOD events)
+  AliESDEvent *event = dynamic_cast<AliESDEvent *>(InputEvent());
+  if ( !event )  return;
+  
+  if(TString(event->GetBeamType())=="Pb-Pb" || TString(event->GetBeamType())=="A-A"){
+    fV0cuts->SetMode(AliESDv0KineCuts::kPurity,AliESDv0KineCuts::kPbPb); 
+  }
+  else{
+    fV0cuts->SetMode(AliESDv0KineCuts::kPurity,AliESDv0KineCuts::kPP); 
+  }
+
+  // V0 selection
+  // set event
+  fV0cuts->SetEvent(event);
+
+  // loop over V0 particles
+  for(Int_t iv0=0; iv0<event->GetNumberOfV0s();iv0++){
+
+    AliESDv0 *v0 = (AliESDv0 *) event->GetV0(iv0);
+    if(!v0) continue;
+    if(v0->GetOnFlyStatus()) continue; 
+  
+    // Get the particle selection 
+    Bool_t foundV0 = kFALSE;
+    Int_t pdgV0, pdgP, pdgN;
+
+    foundV0 = fV0cuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
+    if(!foundV0) continue;
+    
+    Int_t iTrackP = v0->GetPindex();  // positive track
+    Int_t iTrackN = v0->GetNindex();  // negative track
+
+    // v0 Armenteros plot (QA)
+    Float_t armVar[2] = {0.0,0.0};
+    fV0cuts->Armenteros(v0, armVar);
+
+    TH2 *h=(TH2*)fListQAV0->At(0);
+    if (!h) continue;
+    h->Fill(armVar[0],armVar[1]);
+
+    // fill the Object arrays
+    // positive particles
+    if( pdgP == -11){
+      fV0electrons->Add((AliVTrack*)event->GetTrack(iTrackP));
+    }
+    else if( pdgP == 211){
+      fV0pions->Add((AliVTrack*)event->GetTrack(iTrackP));
+    }
+    else if( pdgP == 321){
+      fV0kaons->Add((AliVTrack*)event->GetTrack(iTrackP));
+    }
+    else if( pdgP == 2212){
+      fV0protons->Add((AliVTrack*)event->GetTrack(iTrackP));
+    }
+
+    // negative particles
+    if( pdgN == 11){
+      fV0electrons->Add((AliVTrack*)event->GetTrack(iTrackN));
+    }
+    else if( pdgN == -211){
+      fV0pions->Add((AliVTrack*)event->GetTrack(iTrackN));
+    }
+    else if( pdgN == -321){
+      fV0kaons->Add((AliVTrack*)event->GetTrack(iTrackN));
+    }
+    else if( pdgN == -2212){
+      fV0protons->Add((AliVTrack*)event->GetTrack(iTrackN));
+    }
+  
+
+  }
+}
+//______________________________________________________________________________
+void  AliAnalysisTaskPIDqa::ClearV0PIDlist(){
+
+  //
+  // Clear the PID object arrays
+  //
+
+  fV0electrons->Clear();
+  fV0pions->Clear();
+  fV0kaons->Clear();
+  fV0protons->Clear();
+
+}
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillITSqa()
+{
+  //
+  // Fill PID qa histograms for the ITS
+  //
+
+  AliVEvent *event=InputEvent();
+  
+  Int_t ntracks=event->GetNumberOfTracks();
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    // ITS refit + ITS pid selection
+    if (!( ( (status & AliVTrack::kITSrefit)==AliVTrack::kITSrefit ) ||
+          ! ( (status & AliVTrack::kITSpid  )==AliVTrack::kITSpid   ) )) continue;
+    Double_t mom=track->P();
+    
+    TList *theList = 0x0;
+    if(( (status & AliVTrack::kTPCin)==AliVTrack::kTPCin )){
+      //ITS+TPC tracks
+      theList=fListQAits;
+    }else{
+      if(!( (status & AliVTrack::kITSpureSA)==AliVTrack::kITSpureSA )){ 
+       //ITS Standalone tracks
+       theList=fListQAitsSA;
+      }else{
+       //ITS Pure Standalone tracks
+       theList=fListQAitsPureSA;
+      }
+    }
+    
+    
+    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+      TH2 *h=(TH2*)theList->At(ispecie);
+      if (!h) continue;
+      Double_t nSigma=fPIDResponse->NumberOfSigmasITS(track, (AliPID::EParticleType)ispecie);
+      h->Fill(mom,nSigma);
+    }
+    TH2 *h=(TH2*)theList->At(AliPID::kSPECIESC);
+    if (h) {
+      Double_t sig=track->GetITSsignal();
+      h->Fill(mom,sig);
+    }
+  }
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillTPCqa()
+{
+  //
+  // Fill PID qa histograms for the TPC
+  //
+  
+  AliVEvent *event=InputEvent();
+  
+  Int_t ntracks=event->GetNumberOfTracks();
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+    
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    // TPC refit + ITS refit + TPC pid
+    if (!( (status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||
+        !( (status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;
+
+    // The TPC pid cut removes the light nuclei (>5 sigma from proton line)
+    //||        !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid  )
+    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
+    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;
+    if (track->GetTPCNclsF()>0) {
+      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
+    }
+    
+    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;
+    
+    Double_t mom=track->GetTPCmomentum();
+    // the default scenario
+    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+      TH2 *h=(TH2*)fListQAtpc->At(ispecie);
+      if (!h) continue;
+      Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie);
+      h->Fill(mom,nSigma);
+    }
+    // the "hybrid" scenario
+    if (track->GetTPCdEdxInfo()){
+      for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+        TH2 *h=(TH2*)fListQAtpc->At(ispecie+AliPID::kSPECIESC);
+        if (!h) continue;
+        Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie, AliTPCPIDResponse::kdEdxHybrid);
+        h->Fill(mom,nSigma);
+      }
+
+      // the "OROC" scenario
+      for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+        TH2 *h=(TH2*)fListQAtpc->At(ispecie+2*AliPID::kSPECIESC);
+        if (!h) continue;
+        Double_t nSigma=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie, AliTPCPIDResponse::kdEdxOROC);
+        //TSpline3* spline = fPIDResponse->GetTPCResponse().GetCurrentResponseFunction();
+        //std::cout<<ispecie<<" "<<nSigma<<" phi:"<<track->Phi()<<". "<<std::endl;
+        //if (spline) {cout<<spline->GetName()<<endl;}
+        //else {cout<<"NULL spline"<<endl;}
+        h->Fill(mom,nSigma);
+        }
+    }
+    
+    TH2 *h=(TH2*)fListQAtpc->At(3*AliPID::kSPECIESC);
+
+    if (h) {
+      Double_t sig=track->GetTPCsignal();
+      h->Fill(mom,sig);
+    }
+  }
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillTRDqa()
+{
+  //
+  // Fill PID qa histograms for the TRD
+  //
+  AliVEvent *event=InputEvent();
+  Int_t ntracks = event->GetNumberOfTracks();
+  for(Int_t itrack = 0; itrack <  ntracks; itrack++){
+    AliVTrack *track = (AliVTrack *)event->GetTrack(itrack);
+
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    // TPC refit + ITS refit + TPC pid + TRD out
+    if (!( (status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||
+        !( (status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||
+//         !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid  ) || //removes light nuclei. So it is out for the moment
+        !( (status & AliVTrack::kTRDout  ) == AliVTrack::kTRDout  )) continue;
+    
+    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
+    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;
+    if (track->GetTPCNclsF()>0) {
+      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
+    }
+    
+    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;
+
+    Double_t likelihoods[AliPID::kSPECIES];
+    if(fPIDResponse->ComputeTRDProbability(track, AliPID::kSPECIES, likelihoods) != AliPIDResponse::kDetPidOk) continue;
+    Int_t ntracklets = 0;
+    Double_t momentum = -1.;
+    for(Int_t itl = 0; itl < 6; itl++)
+      if(track->GetTRDmomentum(itl) > 0.){
+        ntracklets++;
+        if(momentum < 0) momentum = track->GetTRDmomentum(itl);
+    } 
+    for(Int_t ispecie = 0; ispecie < AliPID::kSPECIES; ispecie++){
+      TH2F *hLike = (TH2F *)fListQAtrd->At(ntracklets*AliPID::kSPECIES+ispecie);
+      if (hLike) hLike->Fill(momentum,likelihoods[ispecie]);
+    }
+  }
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillTOFqa()
+{
+  //
+  // Fill TOF information
+  //
+  AliVEvent *event=InputEvent();
+
+  Int_t ntracks=event->GetNumberOfTracks();
+  Int_t tracksAtTof = 0;
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // TPC refit + ITS refit +
+    // TOF out + kTIME
+    // kTIME
+    // (we don't use kTOFmismatch because it depends on TPC and kTOFpid because it prevents light nuclei
+    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||
+        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||
+        !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||
+       //        !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||
+        !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;
+
+    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
+    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;
+    if (track->GetTPCNclsF()>0) {
+      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
+    }
+
+    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;
+
+    tracksAtTof++;
+
+    Double_t mom=track->P();
+
+    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+      TH2 *h=(TH2*)fListQAtof->At(ispecie);
+      if (!h) continue;
+      Double_t nSigma=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);
+      h->Fill(mom,nSigma);
+    }
+
+    TH2 *h=(TH2*)fListQAtof->FindObject("hSigP_TOF");
+    if (h) {
+      Double_t sig=track->GetTOFsignal()/1000.;
+      h->Fill(mom,sig);
+    }
+
+    Int_t mask = fPIDResponse->GetTOFResponse().GetStartTimeMask(mom);
+    ((TH1F*)fListQAtof->FindObject("hStartTimeMask_TOF"))->Fill((Double_t)(mask+0.5));
+
+    if (mom >= 0.75 && mom <= 1.25 ) {
+      Double_t nsigma= fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)AliPID::kPion);
+      if (mask == 0) {
+       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-Fill"))->Fill(nsigma);
+      } else if (mask == 1) {
+       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-TOF"))->Fill(nsigma);
+      } else if ( (mask == 2) || (mask == 4) || (mask == 6) ) {
+       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-T0"))->Fill(nsigma);
+      } else {
+       ((TH1F*)fListQAtof->FindObject("hNsigma_TOF_Pion_T0-Best"))->Fill(nsigma);
+      }
+      if (mask & 0x1) { //at least TOF-T0 present
+       Double_t delta=0;
+       (void)fPIDResponse->GetSignalDelta((AliPIDResponse::EDetector)AliPIDResponse::kTOF,track,(AliPID::EParticleType)AliPID::kPion,delta);
+       ((TH1F*)fListQAtof->FindObject("hDelta_TOF_Pion"))->Fill(delta);
+      }
+    }
+
+    Double_t res = (Double_t)fPIDResponse->GetTOFResponse().GetStartTimeRes(mom);
+    ((TH1F*)fListQAtof->FindObject("hStartTimeRes_TOF"))->Fill(res);
+
+    Double_t startTimeT0 = event->GetT0TOF(0);
+    if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeAC_T0"))->Fill(startTimeT0);
+    else {
+      startTimeT0 = event->GetT0TOF(1);
+      if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeA_T0"))->Fill(startTimeT0);
+      startTimeT0 = event->GetT0TOF(2);
+      if (startTimeT0 < 90000) ((TH1F*)fListQAtof->FindObject("hStartTimeC_T0"))->Fill(startTimeT0);
+    }
+  }
+  if (tracksAtTof > 0) {
+    ((TH1F* )fListQAtof->FindObject("hnTracksAt_TOF"))->Fill(tracksAtTof);
+    Int_t mask = fPIDResponse->GetTOFResponse().GetStartTimeMask(5.);
+    if (mask & 0x1) ((TH1F*)fListQAtof->FindObject("hT0MakerEff"))->Fill(tracksAtTof);
+  }
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillT0qa()
+{
+  //
+  // Fill TOF information
+  //
+  AliVEvent *event=InputEvent();
+
+  Int_t ntracks=event->GetNumberOfTracks();
+
+  Int_t tracksAtT0 = 0;
+
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // TPC refit + ITS refit +
+    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||
+        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;
+    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
+    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;
+    if (track->GetTPCNclsF()>0) {
+      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
+    }
+    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;
+
+    tracksAtT0++;
+  }
+
+  Bool_t t0A = kFALSE;
+  Bool_t t0C = kFALSE;
+  Bool_t t0And = kFALSE;
+  Double_t startTimeT0 = event->GetT0TOF(0);     // AND
+  if (startTimeT0 < 90000) {
+    t0And = kTRUE;
+    ((TH1F*)fListQAt0->FindObject("hStartTimeAC_T0"))->Fill(startTimeT0);
+    }
+  startTimeT0 = event->GetT0TOF(1);             // T0A 
+  if (startTimeT0 < 90000) {
+    t0A = kTRUE;
+    ((TH1F*)fListQAt0->FindObject("hStartTimeA_T0"))->Fill(startTimeT0);
+    
+  }
+  startTimeT0 = event->GetT0TOF(2);             // T0C 
+  if (startTimeT0 < 90000) {
+    t0C = kTRUE;
+    ((TH1F*)fListQAt0->FindObject("hStartTimeC_T0"))->Fill(startTimeT0);
+  }
+  
+  ((TH1F* )fListQAt0->FindObject("hnTracksAt_T0"))->Fill(tracksAtT0);
+  if (t0A) ((TH1F*)fListQAt0->FindObject("hT0AEff"))->Fill(tracksAtT0);
+  if (t0C) ((TH1F*)fListQAt0->FindObject("hT0CEff"))->Fill(tracksAtT0);
+  if (t0And) ((TH1F*)fListQAt0->FindObject("hT0AndEff"))->Fill(tracksAtT0);
+  if (t0A || t0C) ((TH1F*)fListQAt0->FindObject("hT0OrEff"))->Fill(tracksAtT0);
+}
+
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillEMCALqa()
+{
+  //
+  // Fill PID qa histograms for the EMCAL
+  //
+
+  AliVEvent *event=InputEvent();
+  
+  Int_t ntracks=event->GetNumberOfTracks();
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+    
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;
+
+    Double_t pt=track->Pt();
+   
+    //EMCAL nSigma (only for electrons at the moment)
+    TH2 *h=(TH2*)fListQAemcal->At(0);
+    if (!h) continue;
+    Double_t nSigma=fPIDResponse->NumberOfSigmasEMCAL(track, (AliPID::EParticleType)0);
+    h->Fill(pt,nSigma);
+    
+  }
+
+   //EMCAL signal (E/p vs. pT) for electrons from V0
+  for(Int_t itrack = 0; itrack < fV0electrons->GetEntries(); itrack++){
+    AliVTrack *track=(AliVTrack*)fV0electrons->At(itrack);
+
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;
+
+    Double_t pt=track->Pt();
+
+    TH2 *h=(TH2*)fListQAemcal->At(1);
+    if (h) {
+
+      Int_t nMatchClus = track->GetEMCALcluster();
+      Double_t mom     = track->P();
+      Double_t eop     = -1.;
+
+      if(nMatchClus > -1){
+    
+        AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);
+
+        if(matchedClus){
+
+          // matched cluster is EMCAL
+          if(matchedClus->IsEMCAL()){
+
+            Double_t fClsE       = matchedClus->E();
+            eop                  = fClsE/mom;
+
+            h->Fill(pt,eop);
+
+          }
+        }
+      }
+    }
+  }
+
+   //EMCAL signal (E/p vs. pT) for pions from V0
+  for(Int_t itrack = 0; itrack < fV0pions->GetEntries(); itrack++){
+    AliVTrack *track=(AliVTrack*)fV0pions->At(itrack);
+
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;
+
+    Double_t pt=track->Pt();
+
+    TH2 *h=(TH2*)fListQAemcal->At(2);
+    if (h) {
+
+      Int_t nMatchClus = track->GetEMCALcluster();
+      Double_t mom     = track->P();
+      Double_t eop     = -1.;
+
+      if(nMatchClus > -1){
+    
+        AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);
+
+        if(matchedClus){
+
+          // matched cluster is EMCAL
+          if(matchedClus->IsEMCAL()){
+
+            Double_t fClsE       = matchedClus->E();
+            eop                  = fClsE/mom;
+
+            h->Fill(pt,eop);
+
+          }
+        }
+      }
+    }
+  }
+
+   //EMCAL signal (E/p vs. pT) for protons from V0
+  for(Int_t itrack = 0; itrack < fV0protons->GetEntries(); itrack++){
+    AliVTrack *track=(AliVTrack*)fV0protons->At(itrack);
+
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    if (!( (status & AliVTrack::kEMCALmatch) == AliVTrack::kEMCALmatch) ) continue;
+
+    Double_t pt=track->Pt();
+
+    TH2 *hP=(TH2*)fListQAemcal->At(3);
+    TH2 *hAP=(TH2*)fListQAemcal->At(4);
+    if (hP && hAP) {
+
+      Int_t nMatchClus = track->GetEMCALcluster();
+      Double_t mom     = track->P();
+      Int_t charge     = track->Charge();            
+      Double_t eop     = -1.;
+
+      if(nMatchClus > -1){
+    
+        AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);
+
+        if(matchedClus){
+
+          // matched cluster is EMCAL
+          if(matchedClus->IsEMCAL()){
+
+            Double_t fClsE       = matchedClus->E();
+            eop                  = fClsE/mom;
+
+            if(charge > 0)      hP->Fill(pt,eop);
+            else if(charge < 0) hAP->Fill(pt,eop);
+
+          }
+        }
+      }
+    }
+  }
+
+}
+
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillHMPIDqa()
+{
+  //
+  // Fill PID qa histograms for the HMPID
+  //
+  
+  AliVEvent *event=InputEvent();
+  
+  Int_t ntracks=event->GetNumberOfTracks();
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+    
+    //
+    //basic track cuts
+    //
+    const ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    // TPC refit + ITS refit +
+    // TOF out + TOFpid +
+    // kTIME
+    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||
+        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ) continue;
+
+    const Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
+    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;
+    if (track->GetTPCNclsF()>0) {
+      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
+    }
+
+    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;
+    
+    const Double_t mom = track->P();
+    const Double_t ckovAngle = track->GetHMPIDsignal();
+
+    Int_t nhists=0;
+    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+      if (ispecie==AliPID::kElectron || ispecie==AliPID::kMuon) continue;
+      TH2 *h=(TH2*)fListQAhmpid->At(nhists);
+      if (!h) {++nhists; continue;}
+      const Double_t nSigma=fPIDResponse->NumberOfSigmasHMPID(track, (AliPID::EParticleType)ispecie);
+      h->Fill(mom,nSigma);
+      ++nhists;
+    }
+    
+    TH1F *hThetavsMom = (TH1F*)fListQAhmpid->At(AliPID::kSPECIESC);
+    
+    if (hThetavsMom) hThetavsMom->Fill(mom,ckovAngle);
+  
+  }
+}
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillTOFHMPIDqa()
+{
+  //
+  // Fill PID qa histograms for the HMPID
+  //
+  
+  AliVEvent *event=InputEvent();
+  
+  Int_t ntracks=event->GetNumberOfTracks();
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+    
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    // TPC refit + ITS refit +
+    // TOF out + TOFpid +
+    // kTIME
+    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||
+        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||
+        !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||
+        !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||
+        !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;
+
+    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
+    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;
+    if (track->GetTPCNclsF()>0) {
+      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
+    }
+
+    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;
+    
+    Double_t mom = track->P();
+    Double_t ckovAngle = track->GetHMPIDsignal();
+    
+    Double_t nSigmaTOF[3]; 
+    TH1F *h[3];
+    
+    for (Int_t ispecie=2; ispecie<5; ++ispecie){
+      //TOF nSigma
+      nSigmaTOF[ispecie-2]=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);
+      h[ispecie-2] = (TH1F*)fListQAtofhmpid->At(ispecie-2);}
+      
+    if(TMath::Abs(nSigmaTOF[0])<2)                                                              h[0]->Fill(mom,ckovAngle);
+    
+    if(TMath::Abs(nSigmaTOF[1])<2 && TMath::Abs(nSigmaTOF[0])>3)                                h[1]->Fill(mom,ckovAngle);
+
+    if(TMath::Abs(nSigmaTOF[2])<2 && TMath::Abs(nSigmaTOF[1])>3 && TMath::Abs(nSigmaTOF[0])>3)  h[2]->Fill(mom,ckovAngle);
+      
+  }
+  
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillTPCTOFqa()
+{
+  //
+  // Fill PID qa histograms for the TOF
+  //   Here also the TPC histograms after TOF selection are filled
+  //
+
+  AliVEvent *event=InputEvent();
+
+  Int_t ntracks=event->GetNumberOfTracks();
+  for(Int_t itrack = 0; itrack < ntracks; itrack++){
+    AliVTrack *track=(AliVTrack*)event->GetTrack(itrack);
+
+    //
+    //basic track cuts
+    //
+    ULong_t status=track->GetStatus();
+    // not that nice. status bits not in virtual interface
+    // TPC refit + ITS refit +
+    // TOF out + TOFpid +
+    // kTIME
+    if (!((status & AliVTrack::kTPCrefit) == AliVTrack::kTPCrefit) ||
+        !((status & AliVTrack::kITSrefit) == AliVTrack::kITSrefit) ||
+//         !( (status & AliVTrack::kTPCpid  ) == AliVTrack::kTPCpid ) || //removes light nuclei, so it is out for the moment
+        !((status & AliVTrack::kTOFout  ) == AliVTrack::kTOFout  ) ||
+        !((status & AliVTrack::kTOFpid  ) == AliVTrack::kTOFpid  ) ||
+        !((status & AliVTrack::kTIME    ) == AliVTrack::kTIME    ) ) continue;
+
+    Float_t nCrossedRowsTPC = track->GetTPCClusterInfo(2,1);
+    Float_t  ratioCrossedRowsOverFindableClustersTPC = 1.0;
+    if (track->GetTPCNclsF()>0) {
+      ratioCrossedRowsOverFindableClustersTPC = nCrossedRowsTPC/track->GetTPCNclsF();
+    }
+
+    if ( nCrossedRowsTPC<70 || ratioCrossedRowsOverFindableClustersTPC<.8 ) continue;
+
+
+    Double_t mom=track->P();
+    Double_t momTPC=track->GetTPCmomentum();
+
+    for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+      //TOF nSigma
+      Double_t nSigmaTOF=fPIDResponse->NumberOfSigmasTOF(track, (AliPID::EParticleType)ispecie);
+      Double_t nSigmaTPC=fPIDResponse->NumberOfSigmasTPC(track, (AliPID::EParticleType)ispecie);
+
+      //TPC after TOF cut
+      TH2 *h=(TH2*)fListQAtpctof->At(ispecie);
+      if (h && TMath::Abs(nSigmaTOF)<3.) h->Fill(momTPC,nSigmaTPC);
+
+      //TOF after TPC cut
+      h=(TH2*)fListQAtpctof->At(ispecie+AliPID::kSPECIESC);
+      if (h && TMath::Abs(nSigmaTPC)<3.) h->Fill(mom,nSigmaTOF);
+
+      //EMCAL after TOF and TPC cut
+      h=(TH2*)fListQAtpctof->At(ispecie+2*AliPID::kSPECIESC);
+      if (h && TMath::Abs(nSigmaTOF)<3. && TMath::Abs(nSigmaTPC)<3. ){
+
+       Int_t nMatchClus = track->GetEMCALcluster();
+       Double_t pt      = track->Pt();
+       Double_t eop     = -1.;
+       
+       if(nMatchClus > -1){
+         
+         AliVCluster *matchedClus = (AliVCluster*)event->GetCaloCluster(nMatchClus);
+         
+         if(matchedClus){
+           
+           // matched cluster is EMCAL
+           if(matchedClus->IsEMCAL()){
+             
+             Double_t fClsE       = matchedClus->E();
+             eop                  = fClsE/mom;
+
+             h->Fill(pt,eop);
+             
+           }
+         }
+       }
+      }
+    }
+  }
+}
+
+//_____________________________________________________________________________
+void AliAnalysisTaskPIDqa::FillQAinfo()
+{
+  //
+  // Fill the QA information
+  //
+
+
+  //TPC QA info
+  TObjArray *arrTPC=static_cast<TObjArray*>(fListQAinfo->At(0));
+  if (fPIDResponse && arrTPC){
+    AliTPCPIDResponse &tpcResp=fPIDResponse->GetTPCResponse();
+    // fill spline names
+    if (!arrTPC->UncheckedAt(0)){
+      
+      TObjArray *arrTPCsplineNames=new TObjArray(AliPID::kSPECIESC);
+      arrTPCsplineNames->SetOwner();
+      arrTPCsplineNames->SetName("TPC_spline_names");
+      arrTPC->AddAt(arrTPCsplineNames,0);
+      
+      for (Int_t iresp=0; iresp<AliPID::kSPECIESC; ++iresp){
+        const TObject *o=tpcResp.GetResponseFunction((AliPID::EParticleType)iresp);
+        if (!o) continue;
+        arrTPCsplineNames->Add(new TObjString(Form("%02d: %s",iresp, o->GetName())));
+      }
+    }
+
+    // tpc response config
+    if (!arrTPC->UncheckedAt(1)){
+      
+      TObjArray *arrTPCconfigInfo=new TObjArray;
+      arrTPCconfigInfo->SetOwner();
+      arrTPCconfigInfo->SetName("TPC_config_info");
+      arrTPC->AddAt(arrTPCconfigInfo,1);
+
+      TObjString *ostr=0x0;
+      ostr=new TObjString;
+      ostr->String().Form("Eta Corr map: %s", tpcResp.GetEtaCorrMap()?tpcResp.GetEtaCorrMap()->GetName():"none");
+      arrTPCconfigInfo->Add(ostr);
+
+      ostr=new TObjString;
+      ostr->String().Form("Sigma Par map: %s", tpcResp.GetSigmaPar1Map()?tpcResp.GetSigmaPar1Map()->GetName():"none");
+      arrTPCconfigInfo->Add(ostr);
+
+      ostr=new TObjString;
+      ostr->String().Form("MIP: %.2f", tpcResp.GetMIP());
+      arrTPCconfigInfo->Add(ostr);
+      
+      ostr=new TObjString;
+      ostr->String().Form("Res: Def %.3g (%.3g) : AllHigh %.3g (%.3g) : OROC high %.3g (%.3g)",
+                          tpcResp.GetRes0(AliTPCPIDResponse::kDefault), tpcResp.GetResN2(AliTPCPIDResponse::kDefault),
+                          tpcResp.GetRes0(AliTPCPIDResponse::kALLhigh), tpcResp.GetResN2(AliTPCPIDResponse::kALLhigh),
+                          tpcResp.GetRes0(AliTPCPIDResponse::kOROChigh), tpcResp.GetResN2(AliTPCPIDResponse::kOROChigh)
+                         );
+      arrTPCconfigInfo->Add(ostr);
+    }
+  }
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupITSqa()
+{
+  //
+  // Create the ITS qa objects
+  //
+  
+  TVectorD *vX=MakeLogBinning(200,.1,30);
+  
+  //ITS+TPC tracks
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_ITS_%s",AliPID::ParticleName(ispecie)),
+                              Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAits->Add(hNsigmaP);
+  }
+  TH2F *hSig = new TH2F("hSigP_ITS",
+                        "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",
+                        vX->GetNrows()-1,vX->GetMatrixArray(),
+                        300,0,300);
+  fListQAits->Add(hSig);
+
+  //ITS Standalone tracks
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaPSA = new TH2F(Form("hNsigmaP_ITSSA_%s",AliPID::ParticleName(ispecie)),
+                               Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                               vX->GetNrows()-1,vX->GetMatrixArray(),
+                               200,-10,10);
+    fListQAitsSA->Add(hNsigmaPSA);
+  }
+  TH2F *hSigSA = new TH2F("hSigP_ITSSA",
+                         "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",
+                         vX->GetNrows()-1,vX->GetMatrixArray(),
+                         300,0,300);
+  fListQAitsSA->Add(hSigSA);
+  
+  //ITS Pure Standalone tracks
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaPPureSA = new TH2F(Form("hNsigmaP_ITSPureSA_%s",AliPID::ParticleName(ispecie)),
+                                   Form("ITS n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                                   vX->GetNrows()-1,vX->GetMatrixArray(),
+                                   200,-10,10);
+    fListQAitsPureSA->Add(hNsigmaPPureSA);
+  }
+  TH2F *hSigPureSA = new TH2F("hSigP_ITSPureSA",
+                             "ITS signal vs. p;p [GeV]; ITS signal [arb. units]",
+                             vX->GetNrows()-1,vX->GetMatrixArray(),
+                             300,0,300);
+  fListQAitsPureSA->Add(hSigPureSA);
+  
+  delete vX;  
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupTPCqa()
+{
+  //
+  // Create the TPC qa objects
+  //
+  
+  TVectorD *vX=MakeLogBinning(200,.1,30);
+  
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s",AliPID::ParticleName(ispecie)),
+                              Form("TPC n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAtpc->Add(hNsigmaP);
+  }
+
+  // the "hybrid" scenario
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s_Hybrid",AliPID::ParticleName(ispecie)),
+                              Form("TPC n#sigma %s vs. p (Hybrid gain scenario);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAtpc->Add(hNsigmaP);
+  }
+   
+  // the "OROC high" scenario
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_%s_OROChigh",AliPID::ParticleName(ispecie)),
+                              Form("TPC n#sigma %s vs. p (OROChigh gain scenario);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAtpc->Add(hNsigmaP);
+  }
+  
+  
+  
+  TH2F *hSig = new TH2F("hSigP_TPC",
+                        "TPC signal vs. p;p [GeV]; TPC signal [arb. units]",
+                        vX->GetNrows()-1,vX->GetMatrixArray(),
+                        500,0,1000);
+  fListQAtpc->Add(hSig); //3*AliPID::kSPECIESC
+
+  delete vX;  
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupTRDqa()
+{
+  //
+  // Create the TRD qa objects
+  //
+  TVectorD *vX=MakeLogBinning(200,.1,30);
+  for(Int_t itl = 0; itl < 6; ++itl){
+    for(Int_t ispecie = 0; ispecie < AliPID::kSPECIES; ispecie++){
+      TH2F *hLikeP = new TH2F(Form("hLikeP_TRD_%dtls_%s", itl, AliPID::ParticleName(ispecie)),
+                              Form("TRD Likelihood to be %s %s for tracks having %d %s; p (GeV/c); TRD %s Likelihood", ispecie == 0 ? "an" : "a", AliPID::ParticleName(ispecie), itl+1, itl == 0 ? "tracklet" : "tracklets", AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1, vX->GetMatrixArray(),
+                              100, 0., 1.);
+      fListQAtrd->Add(hLikeP);
+    }
+  }
+  delete vX;
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupTOFqa()
+{
+  //
+  // Create the TOF qa objects
+  //
+  
+  TVectorD *vX=MakeLogBinning(200,.1,30);
+
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TOF_%s",AliPID::ParticleName(ispecie)),
+                              Form("TOF n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAtof->Add(hNsigmaP);
+  }
+
+  TH1F *hnSigT0Fill = new TH1F("hNsigma_TOF_Pion_T0-Fill","TOF n#sigma (Pion) T0-FILL [0.75-1.25. GeV/c]",200,-10,10);
+  fListQAtof->Add(hnSigT0Fill);
+  TH1F *hnSigT0T0 = new TH1F("hNsigma_TOF_Pion_T0-T0","TOF n#sigma (Pion) T0-T0 [0.75-1.25 GeV/c]",200,-10,10);
+  fListQAtof->Add(hnSigT0T0);
+  TH1F *hnSigT0TOF = new TH1F("hNsigma_TOF_Pion_T0-TOF","TOF n#sigma (Pion) T0-TOF [0.75-1.25 GeV/c]",200,-10,10);
+  fListQAtof->Add(hnSigT0TOF);
+  TH1F *hnSigT0Best = new TH1F("hNsigma_TOF_Pion_T0-Best","TOF n#sigma (Pion) T0-Best [0.75-1.25 GeV/c]",200,-10,10);
+  fListQAtof->Add(hnSigT0Best);
+  TH1F *hnDeltaPi = new TH1F("hDelta_TOF_Pion","DeltaT (Pion) [0.75-1.25 GeV/c]",50,-500,500);
+  fListQAtof->Add(hnDeltaPi);
+  
+  TH2F *hSig = new TH2F("hSigP_TOF",
+                        "TOF signal vs. p;p [GeV]; TOF signal [ns]",
+                        vX->GetNrows()-1,vX->GetMatrixArray(),
+                        300,0,30);
+
+  delete vX;
+  
+  fListQAtof->Add(hSig);
+
+  TH1F *hStartTimeMaskTOF = new TH1F("hStartTimeMask_TOF","StartTime mask",8,0,8);
+  fListQAtof->Add(hStartTimeMaskTOF);
+  TH1F *hStartTimeResTOF = new TH1F("hStartTimeRes_TOF","StartTime resolution [ps]",100,0,500);
+  fListQAtof->Add(hStartTimeResTOF);
+
+  TH1F *hnTracksAtTOF = new TH1F("hnTracksAt_TOF","Matched tracks at TOF",100,0,100);
+  fListQAtof->Add(hnTracksAtTOF);
+  TH1F *hT0MakerEff = new TH1F("hT0MakerEff","Events with T0-TOF vs nTracks",100,0,100);
+  fListQAtof->Add(hT0MakerEff);
+
+  // this in principle should stay on a T0 PID QA, but are just the data prepared for TOF use
+  TH1F *hStartTimeAT0 = new TH1F("hStartTimeA_T0","StartTime from T0A [ps]",1000,-1000,1000);
+  fListQAtof->Add(hStartTimeAT0);
+  TH1F *hStartTimeCT0 = new TH1F("hStartTimeC_T0","StartTime from T0C [ps]",1000,-1000,1000);
+  fListQAtof->Add(hStartTimeCT0);
+  TH1F *hStartTimeACT0 = new TH1F("hStartTimeAC_T0","StartTime from T0AC [ps]",1000,-1000,1000);;
+  fListQAtof->Add(hStartTimeACT0);
+}
+
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupT0qa()
+{
+  //
+  // Create the T0 qa objects
+  //
+  
+  // these are similar to plots inside TOFqa, but these are for all events
+  TH1F *hStartTimeAT0 = new TH1F("hStartTimeA_T0","StartTime from T0A [ps]",1000,-1000,1000);
+  fListQAt0->Add(hStartTimeAT0);
+  TH1F *hStartTimeCT0 = new TH1F("hStartTimeC_T0","StartTime from T0C [ps]",1000,-1000,1000);
+  fListQAt0->Add(hStartTimeCT0);
+  TH1F *hStartTimeACT0 = new TH1F("hStartTimeAC_T0","StartTime from T0AC [ps]",1000,-1000,1000);;
+  fListQAt0->Add(hStartTimeACT0);
+
+  TH1F *hnTracksAtT0 = new TH1F("hnTracksAt_T0","Tracks for events selected for T0",100,0,100);
+  fListQAt0->Add(hnTracksAtT0);
+  TH1F *hT0AEff = new TH1F("hT0AEff","Events with T0A vs nTracks",100,0,100);
+  fListQAt0->Add(hT0AEff);
+  TH1F *hT0CEff = new TH1F("hT0CEff","Events with T0C vs nTracks",100,0,100);
+  fListQAt0->Add(hT0CEff);
+  TH1F *hT0AndEff = new TH1F("hT0AndEff","Events with T0AC (AND) vs nTracks",100,0,100);
+  fListQAt0->Add(hT0AndEff);
+  TH1F *hT0OrEff = new TH1F("hT0OrEff","Events with T0AC (OR) vs nTracks",100,0,100);
+  fListQAt0->Add(hT0OrEff);
+
+
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupEMCALqa()
+{
+  //
+  // Create the EMCAL qa objects
+  //
+
+  TVectorD *vX=MakeLogBinning(200,.1,30);
+  
+  TH2F *hNsigmaPt = new TH2F(Form("hNsigmaPt_EMCAL_%s",AliPID::ParticleName(0)),
+                            Form("EMCAL n#sigma %s vs. p_{T};p_{T} [GeV]; n#sigma",AliPID::ParticleName(0)),
+                            vX->GetNrows()-1,vX->GetMatrixArray(),
+                            200,-10,10);
+  fListQAemcal->Add(hNsigmaPt);  
+  
+
+  TH2F *hSigPtEle = new TH2F("hSigPt_EMCAL_Ele",
+                        "EMCAL signal (E/p) vs. p_{T} for electrons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",
+                        vX->GetNrows()-1,vX->GetMatrixArray(),
+                        200,0,2);
+  fListQAemcal->Add(hSigPtEle);
+
+  TH2F *hSigPtPions = new TH2F("hSigPt_EMCAL_Pions",
+                        "EMCAL signal (E/p) vs. p_{T} for pions;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",
+                        vX->GetNrows()-1,vX->GetMatrixArray(),
+                        200,0,2);
+  fListQAemcal->Add(hSigPtPions);
+
+  TH2F *hSigPtProtons = new TH2F("hSigPt_EMCAL_Protons",
+                        "EMCAL signal (E/p) vs. p_{T} for protons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",
+                        vX->GetNrows()-1,vX->GetMatrixArray(),
+                        200,0,2);
+  fListQAemcal->Add(hSigPtProtons);
+
+  TH2F *hSigPtAntiProtons = new TH2F("hSigPt_EMCAL_Antiprotons",
+                        "EMCAL signal (E/p) vs. p_{T} for antiprotons;p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",
+                        vX->GetNrows()-1,vX->GetMatrixArray(),
+                        200,0,2);
+  fListQAemcal->Add(hSigPtAntiProtons);
+
+  delete vX;  
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupHMPIDqa()
+{
+  //
+  // Create the HMPID qa objects
+  //
+
+  TVectorD *vX=MakeLogBinning(200,.1,30);
+
+  // nSigmas
+  Int_t nhists=0;
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIES; ++ispecie){
+    if (ispecie==AliPID::kElectron || ispecie==AliPID::kMuon) continue;
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_HMPID_%s",AliPID::ParticleName(ispecie)),
+                              Form("HMPID n#sigma %s vs. p;p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAhmpid->AddAt(hNsigmaP, nhists);
+    ++nhists;
+  }
+  
+  // cherenkov angle
+  TH2F *hCkovAnglevsMom   = new TH2F("hCkovAnglevsMom",  "Cherenkov angle vs momentum",
+                                     vX->GetNrows()-1,vX->GetMatrixArray(),
+                                     500,0,1);
+  fListQAhmpid->AddAt(hCkovAnglevsMom,nhists);
+  
+  delete vX;
+}
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupTOFHMPIDqa()
+{
+  //
+  // Create the HMPID qa objects
+  //
+  
+  TH2F *hCkovAnglevsMomPion   = new TH2F("hCkovAnglevsMom_pion",  "Cherenkov angle vs momentum for pions",500,0,5.,500,0,1);
+  fListQAtofhmpid->Add(hCkovAnglevsMomPion);
+  
+  TH2F *hCkovAnglevsMomKaon   = new TH2F("hCkovAnglevsMom_kaon",  "Cherenkov angle vs momentum for kaons",500,0,5.,500,0,1);
+  fListQAtofhmpid->Add(hCkovAnglevsMomKaon);
+  
+  TH2F *hCkovAnglevsMomProton = new TH2F("hCkovAnglevsMom_proton","Cherenkov angle vs momentum for protons",500,0,5.,500,0,1);
+  fListQAtofhmpid->Add(hCkovAnglevsMomProton);
+  
+  
+}  
+
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupTPCTOFqa()
+{
+  //
+  // Create the qa objects for TPC + TOF combination
+  //
+  
+  TVectorD *vX=MakeLogBinning(200,.1,30);
+
+  //TPC signals after TOF cut
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TPC_TOF_%s",AliPID::ParticleName(ispecie)),
+                              Form("TPC n#sigma %s vs. p (after TOF 3#sigma cut);p_{TPC} [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAtpctof->Add(hNsigmaP);
+  }
+
+  //TOF signals after TPC cut
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIESC; ++ispecie){
+    TH2F *hNsigmaP = new TH2F(Form("hNsigmaP_TOF_TPC_%s",AliPID::ParticleName(ispecie)),
+                              Form("TOF n#sigma %s vs. p (after TPC n#sigma cut);p [GeV]; n#sigma",AliPID::ParticleName(ispecie)),
+                              vX->GetNrows()-1,vX->GetMatrixArray(),
+                              200,-10,10);
+    fListQAtpctof->Add(hNsigmaP);
+  }
+
+  //EMCAL signal after TOF and TPC cut
+  for (Int_t ispecie=0; ispecie<AliPID::kSPECIES; ++ispecie){
+    TH2F *heopPt = new TH2F(Form("heopPt_TOF_TPC_%s",AliPID::ParticleName(ispecie)),
+                           Form("EMCAL signal (E/p) %s vs. p_{T};p_{T} [GeV]; EMCAL signal (E/p) [arb. units]",AliPID::ParticleName(ispecie)),
+                           vX->GetNrows()-1,vX->GetMatrixArray(),
+                           200,0,2);
+    fListQAtpctof->Add(heopPt);
+  }
+
+  delete vX;
+}
+//______________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupV0qa()
+{
+  //
+  // Create the qa objects for V0 Kine cuts
+  //
+  
+  TH2F *hArmenteros  = new TH2F("hArmenteros",  "Armenteros plot",200,-1.,1.,200,0.,0.4);
+  fListQAV0->Add(hArmenteros);
+}
+
+//_____________________________________________________________________________
+void AliAnalysisTaskPIDqa::SetupQAinfo(){
+  //
+  // Setup the info of QA objects
+  //
+
+  TObjArray *arr=new TObjArray;
+  arr->SetName("TPC_info");
+  fListQAinfo->Add(arr);
+}
+
+//______________________________________________________________________________
+TVectorD* AliAnalysisTaskPIDqa::MakeLogBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)
+{
+  //
+  // Make logarithmic binning
+  // the user has to delete the array afterwards!!!
+  //
+  
+  //check limits
+  if (xmin<1e-20 || xmax<1e-20){
+    AliError("For Log binning xmin and xmax must be > 1e-20. Using linear binning instead!");
+    return MakeLinBinning(nbinsX, xmin, xmax);
+  }
+  if (xmax<xmin){
+    Double_t tmp=xmin;
+    xmin=xmax;
+    xmax=tmp;
+  }
+  TVectorD *binLim=new TVectorD(nbinsX+1);
+  Double_t first=xmin;
+  Double_t last=xmax;
+  Double_t expMax=TMath::Log(last/first);
+  for (Int_t i=0; i<nbinsX+1; ++i){
+    (*binLim)[i]=first*TMath::Exp(expMax/nbinsX*(Double_t)i);
+  }
+  return binLim;
+}
+
+//______________________________________________________________________________
+TVectorD* AliAnalysisTaskPIDqa::MakeLinBinning(Int_t nbinsX, Double_t xmin, Double_t xmax)
+{
+  //
+  // Make linear binning
+  // the user has to delete the array afterwards!!!
+  //
+  if (xmax<xmin){
+    Double_t tmp=xmin;
+    xmin=xmax;
+    xmax=tmp;
+  }
+  TVectorD *binLim=new TVectorD(nbinsX+1);
+  Double_t first=xmin;
+  Double_t last=xmax;
+  Double_t binWidth=(last-first)/nbinsX;
+  for (Int_t i=0; i<nbinsX+1; ++i){
+    (*binLim)[i]=first+binWidth*(Double_t)i;
+  }
+  return binLim;
+}
+
+//_____________________________________________________________________________
+TVectorD* AliAnalysisTaskPIDqa::MakeArbitraryBinning(const char* bins)
+{
+  //
+  // Make arbitrary binning, bins separated by a ','
+  //
+  TString limits(bins);
+  if (limits.IsNull()){
+    AliError("Bin Limit string is empty, cannot add the variable");
+    return 0x0;
+  }
+  
+  TObjArray *arr=limits.Tokenize(",");
+  Int_t nLimits=arr->GetEntries();
+  if (nLimits<2){
+    AliError("Need at leas 2 bin limits, cannot add the variable");
+    delete arr;
+    return 0x0;
+  }
+  
+  TVectorD *binLimits=new TVectorD(nLimits);
+  for (Int_t iLim=0; iLim<nLimits; ++iLim){
+    (*binLimits)[iLim]=(static_cast<TObjString*>(arr->At(iLim)))->GetString().Atof();
+  }
+  
+  delete arr;
+  return binLimits;
+}
+
index 2887788..795bb3e 100644 (file)
Binary files a/OADB/COMMON/PID/data/TPCPIDResponse.root and b/OADB/COMMON/PID/data/TPCPIDResponse.root differ
index 6f67937..12926e0 100644 (file)
Binary files a/OADB/COMMON/PID/data/TPCetaMaps.root and b/OADB/COMMON/PID/data/TPCetaMaps.root differ
index 15892ae..2b6177b 100644 (file)
@@ -33,6 +33,8 @@
 #include <TArrayI.h>
 #include <TArrayF.h>
 #include <TLinearFitter.h>
+#include <TSystem.h>
+#include <TMD5.h>
 
 #include <AliVEvent.h>
 #include <AliVTrack.h>
@@ -985,8 +987,9 @@ void AliPIDResponse::SetTPCEtaMaps(Double_t refineFactorMapX, Double_t refineFac
           fUseTPCEtaCorrection = kFALSE;
         }
         else {
-          AliInfo(Form("Loaded TPC eta correction map (refine factors %.2f/%.2f) from %s/COMMON/PID/data/TPCetaMaps.root: %s", 
-                       refineFactorMapX, refineFactorMapY, fOADBPath.Data(), fTPCResponse.GetEtaCorrMap()->GetTitle()));
+          AliInfo(Form("Loaded TPC eta correction map (refine factors %.2f/%.2f) from %s/COMMON/PID/data/TPCetaMaps.root: %s (MD5(map) = %s)", 
+                       refineFactorMapX, refineFactorMapY, fOADBPath.Data(), fTPCResponse.GetEtaCorrMap()->GetTitle(),
+                       GetChecksum(fTPCResponse.GetEtaCorrMap()).Data()));
         }
         
         delete etaMapRefined;
@@ -1055,8 +1058,9 @@ void AliPIDResponse::SetTPCEtaMaps(Double_t refineFactorMapX, Double_t refineFac
           fTPCResponse.SetSigmaParams(0x0, 0);
         }
         else {
-          AliInfo(Form("Loaded TPC sigma correction map (refine factors %.2f/%.2f) from %s/COMMON/PID/data/TPCetaMaps.root: %s", 
-                       refineFactorSigmaMapX, refineFactorSigmaMapY, fOADBPath.Data(), fTPCResponse.GetSigmaPar1Map()->GetTitle()));
+          AliInfo(Form("Loaded TPC sigma correction map (refine factors %.2f/%.2f) from %s/COMMON/PID/data/TPCetaMaps.root: %s (MD5(map) = %s, sigmaPar0 = %f)", 
+                       refineFactorSigmaMapX, refineFactorSigmaMapY, fOADBPath.Data(), fTPCResponse.GetSigmaPar1Map()->GetTitle(),
+                       GetChecksum(fTPCResponse.GetSigmaPar1Map()).Data(), sigmaPar0));
         }
         
         delete etaSigmaPar1MapRefined;
@@ -1200,7 +1204,8 @@ void AliPIDResponse::SetTPCParametrisation()
                                                 (AliPID::EParticleType)ispec,
                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
               fTPCResponse.SetUseDatabase(kTRUE);
-              AliInfo(Form("Adding graph: %d %d - %s",ispec,igainScenario,responseFunction->GetName()));
+              AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,responseFunction->GetName(),
+                           GetChecksum((TSpline3*)responseFunction).Data()));
               found=kTRUE;
               break;
             }
@@ -1227,7 +1232,8 @@ void AliPIDResponse::SetTPCParametrisation()
                                                 (AliPID::EParticleType)ispec,
                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
               fTPCResponse.SetUseDatabase(kTRUE);
-              AliInfo(Form("Adding graph: %d %d - %s",ispec,igainScenario,responseFunctionPion->GetName()));
+              AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,responseFunctionPion->GetName(),
+                           GetChecksum((TSpline3*)responseFunctionPion).Data()));
               found=kTRUE;  
             }
             else if (grAll) {
@@ -1235,7 +1241,8 @@ void AliPIDResponse::SetTPCParametrisation()
                                                 (AliPID::EParticleType)ispec,
                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
               fTPCResponse.SetUseDatabase(kTRUE);
-              AliInfo(Form("Adding graph: %d %d - %s",ispec,igainScenario,grAll->GetName()));
+              AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,grAll->GetName(),
+                           GetChecksum((TSpline3*)grAll).Data()));
               found=kTRUE;
             }
             //else
@@ -1247,7 +1254,8 @@ void AliPIDResponse::SetTPCParametrisation()
                                                 (AliPID::EParticleType)ispec,
                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
               fTPCResponse.SetUseDatabase(kTRUE);
-              AliInfo(Form("Adding graph: %d %d - %s",ispec,igainScenario,responseFunctionProton->GetName()));
+              AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,responseFunctionProton->GetName(),
+                           GetChecksum((TSpline3*)responseFunctionProton).Data()));
               found=kTRUE;  
             }
             else if (grAll) {
@@ -1255,7 +1263,8 @@ void AliPIDResponse::SetTPCParametrisation()
                                                 (AliPID::EParticleType)ispec,
                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
               fTPCResponse.SetUseDatabase(kTRUE);
-              AliInfo(Form("Adding graph: %d %d - %s",ispec,igainScenario,grAll->GetName()));
+              AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,grAll->GetName(),
+                           GetChecksum((TSpline3*)grAll).Data()));
               found=kTRUE;
             }
             //else
@@ -1406,7 +1415,8 @@ void AliPIDResponse::SetTPCParametrisation()
   if (fArrPidResponseMaster)
   fResolutionCorrection=(TF1*)fArrPidResponseMaster->FindObject(Form("TF1_%s_ALL_%s_PASS%d_%s_SIGMA",datatype.Data(),period.Data(),recopass,fBeamType.Data()));
   
-  if (fResolutionCorrection) AliInfo(Form("Setting multiplicity correction function: %s",fResolutionCorrection->GetName()));
+  if (fResolutionCorrection) AliInfo(Form("Setting multiplicity correction function: %s  (MD5(corr function) = %s)",
+                                          fResolutionCorrection->GetName(), GetChecksum(fResolutionCorrection).Data()));
 
   //read in the voltage map
   TVectorF* gsm = 0x0;
@@ -2479,3 +2489,52 @@ AliPIDResponse::EDetPidStatus AliPIDResponse::GetPIDStatus(EDetector detector, c
   return kDetNoSignal;
   
 }
+
+//______________________________________________________________________________
+TString AliPIDResponse::GetChecksum(const TObject* obj) const
+{
+  // Return the checksum for an object obj (tested to work properly at least for histograms and TSplines).
+  
+  TString fileName = Form("tempChecksum.C"); // File name must be fixed for data type "TSpline3", since the file name will end up in the file content!
+  
+  // For parallel processing, a unique file pathname is required. Uniqueness can be guaranteed by using a unique directory name
+  UInt_t index = 0;
+  TString uniquePathName = Form("tempChecksum_%u", index);
+  
+  // To get a unique path name, increase the index until no directory
+  // of such a name exists.
+  // NOTE: gSystem->AccessPathName(...) returns kTRUE, if the access FAILED!
+  while (!gSystem->AccessPathName(uniquePathName.Data()))
+    uniquePathName = Form("tempChecksum_%u", ++index);
+  
+  if (gSystem->mkdir(uniquePathName.Data()) < 0) {
+    AliError("Could not create temporary directory to store temp file for checksum determination!");
+    return "ERROR";
+  }
+  
+  TString option = "";
+  
+  // Save object as a macro, which will be deleted immediately after the checksum has been computed
+  // (does not work for desired data types if saved as *.root for some reason) - one only wants to compare the content, not
+  // the modification time etc. ...
+  if (dynamic_cast<const TH1*>(obj))
+    option = "colz"; // Histos need this option, since w/o this option, a counter is added to the filename
+  
+  
+  // SaveAs must be called with the fixed fileName only, since the first argument goes into the file content
+  // for some object types. Thus, change the directory, save the file and then go back
+  TString oldDir = gSystem->pwd();
+  gSystem->cd(uniquePathName.Data());
+  obj->SaveAs(fileName.Data(), option.Data());
+  gSystem->cd(oldDir.Data());
+  
+  // Use the file to calculate the MD5 checksum
+  TMD5* md5 = TMD5::FileChecksum(Form("%s/%s", uniquePathName.Data(), fileName.Data()));
+  TString checksum = md5->AsString();
+  
+  // Clean up
+  delete md5;
+  gSystem->Exec(Form("rm -rf %s", uniquePathName.Data()));
+  
+  return checksum;
+}
index fd75708..9dffe8c 100644 (file)
@@ -167,6 +167,9 @@ public:
   Int_t GetTunedOnDataMask() const {return fTuneMConDataMask;};
   void SetTunedOnDataMask(Int_t detMask) {fTuneMConDataMask = detMask;}
 
+  // Utilities
+  TString GetChecksum(const TObject* obj) const;
+    
   AliPIDResponse(const AliPIDResponse &other);
   AliPIDResponse& operator=(const AliPIDResponse &other);
 
index 9491c1f..779be05 100644 (file)
@@ -80,6 +80,9 @@ AliTPCPIDResponse::AliTPCPIDResponse():
   //
   //  The default constructor
   //
+  
+  AliLog::SetClassDebugLevel("AliTPCPIDResponse", AliLog::kInfo); 
+  
   for (Int_t i=0; i<fgkNumberOfGainScenarios; i++) {fRes0[i]=0.07;fResN2[i]=0.0;}
   
   fCorrFuncMultiplicity = new TF1("fCorrFuncMultiplicity", 
@@ -536,6 +539,12 @@ Double_t AliTPCPIDResponse::GetExpectedSigma(const AliVTrack* track,
     return 999;
     
   //TODO Check whether it makes sense to set correctMultiplicity to kTRUE while correctEta might be kFALSE
+  
+  // If eta correction (=> new sigma parametrisation) is requested, but no sigma map is available, print error message
+  if (correctEta && !fhEtaSigmaPar1) {
+    AliError("New sigma parametrisation requested, but sigma map not initialised (usually via AliPIDResponse). Old sigma parametrisation will be used!");
+  }
+  
   // If no sigma map is available or if no eta correction is requested (sigma maps only for corrected eta!), use the old parametrisation
   if (!fhEtaSigmaPar1 || !correctEta) {  
     if (nPoints != 0) 
@@ -764,8 +773,11 @@ Double_t AliTPCPIDResponse::GetEtaCorrectionFast(const AliVTrack *track, Double_
   // Get eta correction for the given parameters.
   //
   
-  if (!fhEtaCorr)
+  if (!fhEtaCorr) {
+    // Calling this function means to request eta correction in some way. Print error message, if no map is available!
+    AliError("Eta correction requested, but map not initialised (usually via AliPIDResponse). Returning eta correction factor 1!");
     return 1.;
+  }
   
   Double_t tpcSignal = dEdxSplines;
   
@@ -871,8 +883,11 @@ Double_t AliTPCPIDResponse::GetSigmaPar1Fast(const AliVTrack *track, AliPID::EPa
   // Get parameter 1 of sigma parametrisation of TPC dEdx from the histogram for the given track.
   //
   
-  if (!fhEtaSigmaPar1)
+  if (!fhEtaSigmaPar1) {
+    // Calling this function means to request new sigma parametrisation in some way. Print error message, if no map is available!
+    AliError("New sigma parametrisation requested, but sigma map not initialised (usually via AliPIDResponse). Returning error value for sigma parameter1 = 999!");
     return 999;
+  }
   
   // The sigma maps are created with data sets that are already eta corrected and for which the 
   // splines have been re-created. Therefore, the value for the lookup needs to be the value of