#include "TChain.h"
#include "TTree.h"
#include "TF1.h"
#include "TAxis.h"
#include "TH2I.h"
#include "THnSparse.h"
#include "AliMCParticle.h"
#include "AliAnalysisTask.h"
#include "AliAnalysisManager.h"
#include "AliESDEvent.h"
#include "AliMCEvent.h"
#include "AliESDInputHandler.h"
#include "AliInputEventHandler.h"
#include "AliVVertex.h"
#include "AliAnalysisFilter.h"
#include "AliPID.h"
#include "AliPIDResponse.h"
#include "AliTPCPIDResponse.h"
#include "AliTPCPIDEtaTree.h"
ClassImp(AliTPCPIDEtaTree)
AliTPCPIDEtaTree::AliTPCPIDEtaTree()
: AliTPCPIDBase()
, fNumEtaCorrReqErrorsIssued(0)
, fNumMultCorrReqErrorsIssued(0)
, fStoreMultiplicity(kFALSE)
, fStoreNumOfSubthresholdclusters(kFALSE)
, fStoreNumClustersInActiveVolume(kFALSE)
, fDoAdditionalQA(kFALSE)
, fPtpcPionCut(1.0)
, fPtpc(0)
, fPt(0)
, fDeDx(0)
, fDeDxExpected(0)
, fTanTheta(0)
, fPhiPrime(0)
, fTPCsignalN(0)
, fTPCsignalNsubthreshold(0)
, fNumTPCClustersInActiveVolume(0)
, fPIDtype(0)
, fMultiplicity(0)
, fCorrectdEdxEtaDependence(kFALSE)
, fCorrectdEdxMultiplicityDependence(kFALSE)
, fTree(0x0)
, fTreePions(0x0)
, fOutputContainer(0x0)
, fhTOFqa(0x0)
, fhMultiplicityQA(0x0)
{
}
AliTPCPIDEtaTree::AliTPCPIDEtaTree(const char *name)
: AliTPCPIDBase(name)
, fNumEtaCorrReqErrorsIssued(0)
, fNumMultCorrReqErrorsIssued(0)
, fStoreMultiplicity(kFALSE)
, fStoreNumOfSubthresholdclusters(kFALSE)
, fStoreNumClustersInActiveVolume(kFALSE)
, fDoAdditionalQA(kFALSE)
, fPtpcPionCut(1.0)
, fPtpc(0)
, fPt(0)
, fDeDx(0)
, fDeDxExpected(0)
, fTanTheta(0)
, fPhiPrime(0)
, fTPCsignalN(0)
, fTPCsignalNsubthreshold(0)
, fNumTPCClustersInActiveVolume(0)
, fPIDtype(0)
, fMultiplicity(0)
, fCorrectdEdxEtaDependence(kFALSE)
, fCorrectdEdxMultiplicityDependence(kFALSE)
, fTree(0x0)
, fTreePions(0x0)
, fOutputContainer(0x0)
, fhTOFqa(0x0)
, fhMultiplicityQA(0x0)
{
DefineInput(0, TChain::Class());
DefineOutput(1, TTree::Class());
DefineOutput(2, TTree::Class());
DefineOutput(3, TObjArray::Class());
}
AliTPCPIDEtaTree::~AliTPCPIDEtaTree()
{
delete fOutputContainer;
fOutputContainer = 0x0;
}
void AliTPCPIDEtaTree::UserCreateOutputObjects()
{
AliTPCPIDBase::UserCreateOutputObjects();
if (fDoAdditionalQA) {
OpenFile(3);
fOutputContainer = new TObjArray(2);
fOutputContainer->SetName(GetName());
fOutputContainer->SetOwner(kTRUE);
const Int_t nBins = 6;
Int_t bins[nBins] = { 48, 48, 9, 30, 110, 4 };
Double_t xmin[nBins] = { 0.3, 0.3, -0.9, -5.0, 0.0, 0. };
Double_t xmax[nBins] = { 2.7, 2.7, 0.9, 5.0, 1.1, 3200 };
fhTOFqa = new THnSparseI("hTOFqa","", nBins, bins, xmin, xmax);
fhTOFqa->GetAxis(0)->SetTitle("p_{Vertex} (GeV/c)");
fhTOFqa->GetAxis(1)->SetTitle("p_{TPC_inner} (GeV/c)");
fhTOFqa->GetAxis(2)->SetTitle("#eta");
fhTOFqa->GetAxis(3)->SetTitle("n #sigma_{p} TOF");
fhTOFqa->GetAxis(4)->SetTitle("#beta");
fhTOFqa->GetAxis(5)->SetTitle("Multiplicity");
fOutputContainer->Add(fhTOFqa);
fhMultiplicityQA = new TH2I("hMultiplicityQA", "Multiplicity check; Contributors to primary vertex per event; Total number of tracks per Event",
120, 0, 6000, 400, 0, 20000);
fOutputContainer->Add(fhMultiplicityQA);
}
else {
fOutputContainer = new TObjArray(1);
fOutputContainer->SetName(GetName());
fOutputContainer->SetOwner(kTRUE);
}
OpenFile(1);
fTree = new TTree("fTree", "Tree for analysis of #eta dependence of TPC signal");
fTree->Branch("pTPC", &fPtpc);
fTree->Branch("dEdx", &fDeDx);
fTree->Branch("dEdxExpected", &fDeDxExpected);
fTree->Branch("tanTheta", &fTanTheta);
fTree->Branch("tpcSignalN", &fTPCsignalN);
if (fStoreNumOfSubthresholdclusters)
fTree->Branch("tpcSignalNsubthreshold", &fTPCsignalNsubthreshold);
if (fStoreNumClustersInActiveVolume)
fTree->Branch("numTPCClustersInActiveVolume", &fNumTPCClustersInActiveVolume);
fTree->Branch("pidType", &fPIDtype);
if (fStoreMultiplicity) {
fTree->Branch("fMultiplicity", &fMultiplicity);
}
OpenFile(2);
fTreePions = new TTree("fTreePions", "Tree for analysis of #eta dependence of TPC signal - Pions");
fTreePions->Branch("pTPC", &fPtpc);
fTreePions->Branch("pT", &fPt);
fTreePions->Branch("dEdx", &fDeDx);
fTreePions->Branch("dEdxExpected", &fDeDxExpected);
fTreePions->Branch("tanTheta", &fTanTheta);
fTreePions->Branch("tpcSignalN", &fTPCsignalN);
if (fStoreNumOfSubthresholdclusters)
fTreePions->Branch("tpcSignalNsubthreshold", &fTPCsignalNsubthreshold);
if (fStoreMultiplicity) {
fTreePions->Branch("fMultiplicity", &fMultiplicity);
}
PostData(1, fTree);
PostData(2, fTreePions);
PostData(3, fOutputContainer);
}
void AliTPCPIDEtaTree::UserExec(Option_t *)
{
fESD = dynamic_cast<AliESDEvent*>(InputEvent());
if (!fESD) {
Printf("ERROR: fESD not available");
return;
}
fMC = dynamic_cast<AliMCEvent*>(MCEvent());
if (!fPIDResponse || !fV0KineCuts)
return;
if (!GetVertexIsOk(fESD))
return;
const AliVVertex* primaryVertex = fESD->GetPrimaryVertexTracks();
if (!primaryVertex)
return;
if(primaryVertex->GetNContributors() <= 0)
return;
fMultiplicity = fESD->GetNumberOfESDTracks();
if (fDoAdditionalQA) {
Int_t nTotTracks = fESD->GetNumberOfESDTracks();
fhMultiplicityQA->Fill(primaryVertex->GetNContributors(), nTotTracks);
}
Double_t magField = fESD->GetMagneticField();
FillV0PIDlist();
Bool_t etaCorrAvail = fPIDResponse->UseTPCEtaCorrection();
Bool_t multCorrAvail = fPIDResponse->UseTPCMultiplicityCorrection();
for (Int_t iTracks = 0; iTracks < fESD->GetNumberOfTracks(); iTracks++) {
Bool_t isPr = kFALSE;
Bool_t isPi = kFALSE;
AliESDtrack* track = fESD->GetTrack(iTracks);
if (!track) {
Printf("ERROR: Could not receive track %d", iTracks);
continue;
}
if (TMath::Abs(track->Eta()) > fEtaCut)
continue;
Char_t v0tagAllCharges = TMath::Abs(GetV0tag(iTracks));
if (v0tagAllCharges == -99) {
AliError(Form("Problem with V0 tag list (requested V0 track for track %d from %d (list status %d))!", iTracks, fESD->GetNumberOfTracks(),
fV0tags != 0x0));
continue;
}
Bool_t isV0prNotMC = (v0tagAllCharges == 16) && !fMC;
Bool_t isV0piNotMC = (v0tagAllCharges == 15) && !fMC;
Bool_t isV0NotMC = isV0prNotMC || isV0piNotMC;
if(!isV0NotMC && fTrackFilter && !fTrackFilter->IsSelected(track))
continue;
if (!isV0NotMC && GetUseTPCCutMIGeo()) {
if (!TPCCutMIGeo(track, InputEvent()))
continue;
}
fPtpc = track->GetTPCmomentum();
if (fPtpc > 5.)
continue;
fPt = track->Pt();
fPhiPrime = GetPhiPrime(track->Phi(), magField, track->Charge());
Int_t label = track->GetLabel();
AliMCParticle* mcTrack = 0x0;
if (fMC) {
if (label < 0)
continue;
mcTrack = dynamic_cast<AliMCParticle*>(fMC->GetTrack(TMath::Abs(label)));
if (!mcTrack) {
Printf("ERROR: Could not receive mcTrack with label %d for track %d", label, iTracks);
continue;
}
}
if (fMC) {
Int_t pdg = mcTrack->PdgCode();
if (TMath::Abs(pdg) == 2212)
isPr = kTRUE;
else if ((pdg == 111 || TMath::Abs(pdg) == 211) && fPtpc <= fPtpcPionCut)
isPi = kTRUE;
else
continue;
fPIDtype = kMCid;
}
fDeDx = track->GetTPCsignal();
UInt_t status = track->GetStatus();
Bool_t hasTOFout = status&AliESDtrack::kTOFout;
Bool_t hasTOFtime = status&AliESDtrack::kTIME;
Bool_t hasTOF = kFALSE;
if (hasTOFout && hasTOFtime)
hasTOF = kTRUE;
Float_t length = track->GetIntegratedLength();
if (length < 350 && !isV0NotMC)
hasTOF = kFALSE;
if (!fMC) {
if (isV0prNotMC) {
isPr = kTRUE;
if (!hasTOF) {
fPIDtype = kV0idNoTOF;
}
else {
if (TMath::Abs(fPIDResponse->NumberOfSigmasTOF(track, AliPID::kProton)) < 3.0)
fPIDtype = kV0idPlusTOFaccepted;
else
fPIDtype = kV0idPlusTOFrejected;
}
}
else if (isV0piNotMC) {
if (fPtpc > fPtpcPionCut || fDeDx > 140.)
continue;
isPi = kTRUE;
if (!hasTOF) {
fPIDtype = kV0idNoTOF;
}
else {
if (TMath::Abs(fPIDResponse->NumberOfSigmasTOF(track, AliPID::kPion)) < 3.0)
fPIDtype = kV0idPlusTOFaccepted;
else
fPIDtype = kV0idPlusTOFrejected;
}
}
else {
isPr = kTRUE;
if (fPtpc < 4.0 &&
(fDeDx >= 50. / TMath::Power(fPtpc, 1.3))) {
if (fPtpc < 0.6) {
fPIDtype = kTPCid;
}
else if (hasTOF && TMath::Abs(fPIDResponse->NumberOfSigmasTOF(track, AliPID::kProton)) < 3.0) {
fPIDtype = kTPCandTOFid;
}
else
continue;
}
else
continue;
}
}
if (fDoAdditionalQA) {
Double_t tofTime = track->GetTOFsignal();
Double_t tof = tofTime * 1E-3;
Double_t length2 = track->GetIntegratedLength();
Double_t c = TMath::C() * 1.E-9;
length2 = length2 * 0.01;
tof = tof * c;
Double_t beta = length2 / tof;
Double_t nSigmaTOF = hasTOF ? fPIDResponse->NumberOfSigmasTOF(track, AliPID::kProton) : 999;
Double_t entry[6] = { track->P(), fPtpc, track->Eta(), nSigmaTOF, beta, (Double_t)fMultiplicity };
fhTOFqa->Fill(entry);
}
if (fCorrectdEdxEtaDependence && fNumEtaCorrReqErrorsIssued < 23 && !etaCorrAvail) {
AliError("TPC eta correction requested, but was not activated in PID response (most likely not available)!");
fNumEtaCorrReqErrorsIssued++;
if (fNumEtaCorrReqErrorsIssued == 23)
AliError("Ignoring this error from now on!");
}
if (fCorrectdEdxMultiplicityDependence && fNumMultCorrReqErrorsIssued < 23 && !multCorrAvail) {
AliError("TPC multiplicity correction requested, but was not activated in PID response (most likely not available)!");
fNumMultCorrReqErrorsIssued++;
if (fNumMultCorrReqErrorsIssued == 23)
AliError("Ignoring this error from now on!");
}
if (isPr)
fDeDxExpected = fPIDResponse->GetTPCResponse().GetExpectedSignal(track, AliPID::kProton, AliTPCPIDResponse::kdEdxDefault,
fCorrectdEdxEtaDependence && etaCorrAvail,
fCorrectdEdxMultiplicityDependence && multCorrAvail);
else if (isPi)
fDeDxExpected = fPIDResponse->GetTPCResponse().GetExpectedSignal(track, AliPID::kPion, AliTPCPIDResponse::kdEdxDefault,
fCorrectdEdxEtaDependence && etaCorrAvail,
fCorrectdEdxMultiplicityDependence && multCorrAvail);
else
fDeDxExpected = -1.;
fTanTheta = track->GetInnerParam()->GetTgl();
fTPCsignalN = track->GetTPCsignalN();
if (fStoreNumOfSubthresholdclusters) {
const AliTPCdEdxInfo *clsInfo = track->GetTPCdEdxInfo();
if (clsInfo) {
Double32_t signal[4] = {0};
Char_t ncl[3] = {0};
Char_t nrows[3] = {0};
clsInfo->GetTPCSignalRegionInfo(signal, ncl, nrows);
fTPCsignalNsubthreshold = nrows[0] + nrows[1] + nrows[2] - ncl[0] - ncl[1] - ncl[2];
}
else
fTPCsignalNsubthreshold = 200;
}
if (fStoreNumClustersInActiveVolume)
fNumTPCClustersInActiveVolume = track->GetLengthInActiveZone(1, 1.8, 220, magField);
else
fNumTPCClustersInActiveVolume = 200.;
if (isPr)
fTree->Fill();
else if (isPi)
fTreePions->Fill();
}
PostData(1, fTree);
PostData(2, fTreePions);
if (fDoAdditionalQA)
PostData(3, fOutputContainer);
ClearV0PIDlist();
}
void AliTPCPIDEtaTree::Terminate(const Option_t *)
{
}