#include "TChain.h"
#include "TF1.h"
#include "TRandom3.h"
#include "AliMCParticle.h"
#include "AliAnalysisTask.h"
#include "AliAnalysisManager.h"
#include "AliVEvent.h"
#include "AliESDEvent.h"
#include "AliAODEvent.h"
#include "AliMCEvent.h"
#include "AliESDInputHandler.h"
#include "AliInputEventHandler.h"
#include "AliVTrack.h"
#include "AliExternalTrackParam.h"
#include "AliVVertex.h"
#include "AliAnalysisFilter.h"
#include "AliPID.h"
#include "AliPIDResponse.h"
#include "AliESDv0KineCuts.h"
#include "AliESDv0.h"
#include "AliTPCPIDBase.h"
ClassImp(AliTPCPIDBase)
Double_t AliTPCPIDBase::fgCutGeo = 1.;
Double_t AliTPCPIDBase::fgCutNcr = 0.85;
Double_t AliTPCPIDBase::fgCutNcl = 0.7;
UShort_t AliTPCPIDBase::fgCutPureNcl = 60;
AliTPCPIDBase::AliTPCPIDBase()
: AliAnalysisTaskSE()
, fEvent(0x0)
, fESD(0x0)
, fMC(0x0)
, fPIDResponse(0x0)
, fV0KineCuts(0x0)
, fIsPbpOrpPb(kFALSE)
, fUsePhiCut(kFALSE)
, fTPCcutType(kNoCut)
, fZvtxCutEvent(10.0)
, fEtaCut(0.9)
, fPhiCutLow(0x0)
, fPhiCutHigh(0x0)
, fRandom(0x0)
, fTrackFilter(0x0)
, fNumTagsStored(0)
, fV0tags(0x0)
, fStoreMotherIndex(kFALSE)
, fV0motherIndex(0x0)
{
fRandom = new TRandom3(0);
fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
}
AliTPCPIDBase::AliTPCPIDBase(const char *name)
: AliAnalysisTaskSE(name)
, fEvent(0x0)
, fESD(0x0)
, fMC(0x0)
, fPIDResponse(0x0)
, fV0KineCuts(0x0)
, fIsPbpOrpPb(kFALSE)
, fUsePhiCut(kFALSE)
, fTPCcutType(kNoCut)
, fZvtxCutEvent(10.0)
, fEtaCut(0.9)
, fPhiCutLow(0x0)
, fPhiCutHigh(0x0)
, fRandom(0x0)
, fTrackFilter(0x0)
, fNumTagsStored(0)
, fV0tags(0x0)
, fStoreMotherIndex(kFALSE)
, fV0motherIndex(0x0)
{
fRandom = new TRandom3(0);
fPhiCutLow = new TF1("StdPhiCutLow", "0.1/x/x+pi/18.0-0.025", 0, 100);
fPhiCutHigh = new TF1("StandardPhiCutHigh", "0.12/x+pi/18.0+0.035", 0, 100);
DefineInput (0, TChain::Class());
DefineOutput(0, TTree::Class());
}
AliTPCPIDBase::~AliTPCPIDBase()
{
delete fPhiCutLow;
fPhiCutLow = 0;
delete fPhiCutHigh;
fPhiCutHigh = 0;
delete fTrackFilter;
fTrackFilter = 0;
delete fRandom;
fRandom = 0;
delete fV0KineCuts;
fV0KineCuts = 0;
delete fV0tags;
fV0tags = 0;
fNumTagsStored = 0;
delete fV0motherIndex;
fV0motherIndex = 0;
}
void AliTPCPIDBase::UserCreateOutputObjects()
{
AliAnalysisManager* man = AliAnalysisManager::GetAnalysisManager();
AliInputEventHandler* inputHandler = dynamic_cast<AliInputEventHandler*>(man->GetInputEventHandler());
if (!inputHandler) {
AliFatal("Input handler needed");
fPIDResponse = 0x0;
return;
}
fPIDResponse = inputHandler->GetPIDResponse();
if (!fPIDResponse)
AliError("PIDResponse object was not created");
fV0KineCuts = new AliESDv0KineCuts;
fV0KineCuts->SetGammaCutChi2NDF(5.);
Float_t gammaProdVertexRadiusCuts[2] = { 3.0, 45. };
fV0KineCuts->SetGammaCutVertexR(&gammaProdVertexRadiusCuts[0]);
}
void AliTPCPIDBase::UserExec(Option_t *)
{
}
void AliTPCPIDBase::Terminate(const Option_t *)
{
}
Double_t AliTPCPIDBase::GetPhiPrime(Double_t phi, Double_t magField, Int_t charge) const
{
if(magField < 0)
phi = TMath::TwoPi() - phi;
if(charge < 0)
phi = TMath::TwoPi() - phi;
phi += TMath::Pi() / 18.0;
phi = fmod(phi, TMath::Pi() / 9.0);
return phi;
}
Bool_t AliTPCPIDBase::PhiPrimeCut(Double_t trackPt, Double_t trackPhi, Short_t trackCharge, Double_t magField) const
{
if (trackPt < 2.0)
return kTRUE;
Double_t phiPrime = GetPhiPrime(trackPhi, magField, trackCharge);
if (phiPrime < fPhiCutHigh->Eval(trackPt) && phiPrime > fPhiCutLow->Eval(trackPt))
return kFALSE;
return kTRUE;
}
Bool_t AliTPCPIDBase::PhiPrimeCut(const AliVTrack* track, Double_t magField) const
{
return PhiPrimeCut(track->Pt(), track->Phi(), track->Charge(), magField);
}
Bool_t AliTPCPIDBase::GetVertexIsOk(AliVEvent* event, Bool_t doVtxZcut) const
{
AliAODEvent* aod = 0x0;
AliESDEvent* esd = 0x0;
aod = dynamic_cast<AliAODEvent*>(event);
if (!aod) {
esd = dynamic_cast<AliESDEvent*>(event);
if (!esd) {
AliError("Event seems to be neither AOD nor ESD!");
return kFALSE;
}
}
if (fIsPbpOrpPb) {
const AliVVertex* trkVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertex()));
if (!trkVtx || trkVtx->GetNContributors() <= 0)
return kFALSE;
TString vtxTtl = trkVtx->GetTitle();
if (!vtxTtl.Contains("VertexerTracks"))
return kFALSE;
Float_t zvtx = trkVtx->GetZ();
const AliVVertex* spdVtx = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertexSPD()) :
dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexSPD()));
if (spdVtx->GetNContributors() <= 0)
return kFALSE;
TString vtxTyp = spdVtx->GetTitle();
Double_t cov[6] = {0};
spdVtx->GetCovarianceMatrix(cov);
Double_t zRes = TMath::Sqrt(cov[5]);
if (vtxTyp.Contains("vertexer:Z") && (zRes > 0.25))
return kFALSE;
if (TMath::Abs(spdVtx->GetZ() - trkVtx->GetZ()) > 0.5)
return kFALSE;
if (doVtxZcut) {
if (TMath::Abs(zvtx) > fZvtxCutEvent)
return kFALSE;
}
return kTRUE;
}
const AliVVertex* primaryVertex = (aod ? dynamic_cast<const AliVVertex*>(aod->GetPrimaryVertex()) :
dynamic_cast<const AliVVertex*>(esd->GetPrimaryVertexTracks()));
if (!primaryVertex || primaryVertex->GetNContributors() <= 0)
return kFALSE;
if (doVtxZcut) {
if (TMath::Abs(primaryVertex->GetZ()) > fZvtxCutEvent)
return kFALSE;
}
return kTRUE;
}
void AliTPCPIDBase::FillV0PIDlist(AliESDEvent* event)
{
if (!event)
event = dynamic_cast<AliESDEvent *>(InputEvent());
if (!event) {
AliError("Failed to retrieve ESD event. No V0's processed (only works for ESDs by now).");
return;
}
if (!fV0KineCuts) {
AliError("V0KineCuts not available!");
return;
}
TString beamType(event->GetBeamType());
if (beamType.CompareTo("Pb-Pb") == 0 || beamType.CompareTo("A-A") == 0) {
fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPbPb);
}
else {
fV0KineCuts->SetMode(AliESDv0KineCuts::kPurity, AliESDv0KineCuts::kPP);
}
fV0KineCuts->SetEvent(event);
const Int_t numTracks = event->GetNumberOfTracks();
fV0tags = new Char_t[numTracks];
for (Int_t i = 0; i < numTracks; i++)
fV0tags[i] = 0;
if (fStoreMotherIndex) {
fV0motherIndex = new Int_t[numTracks];
for (Int_t i = 0; i < numTracks; i++)
fV0motherIndex[i] = -1;
}
fNumTagsStored = numTracks;
for (Int_t iv0 = 0; iv0 < event->GetNumberOfV0s(); iv0++) {
AliESDv0* v0 = (AliESDv0*)event->GetV0(iv0);
if (!v0)
continue;
if (v0->GetOnFlyStatus())
continue;
Bool_t foundV0 = kFALSE;
Int_t pdgV0 = 0, pdgP = 0, pdgN = 0;
foundV0 = fV0KineCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
if (!foundV0)
continue;
Int_t iTrackP = v0->GetPindex();
Int_t iTrackN = v0->GetNindex();
if (pdgP == -11) {
fV0tags[iTrackP] = 14;
}
else if (pdgP == 211) {
fV0tags[iTrackP] = 15;
}
else if(pdgP == 2212) {
fV0tags[iTrackP] = 16;
}
if (fStoreMotherIndex)
fV0motherIndex[iTrackP] = iv0;
if( pdgN == 11){
fV0tags[iTrackN] = -14;
}
else if( pdgN == -211){
fV0tags[iTrackN] = -15;
}
else if( pdgN == -2212){
fV0tags[iTrackN] = -16;
}
if (fStoreMotherIndex)
fV0motherIndex[iTrackN] = iv0;
}
}
void AliTPCPIDBase::ClearV0PIDlist()
{
delete fV0tags;
fV0tags = 0;
delete fV0motherIndex;
fV0motherIndex = 0;
fNumTagsStored = 0;
}
Char_t AliTPCPIDBase::GetV0tag(Int_t trackIndex) const
{
if (trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0tags)
return -99;
return fV0tags[trackIndex];
}
Int_t AliTPCPIDBase::GetV0motherIndex(Int_t trackIndex) const
{
if (!fStoreMotherIndex || trackIndex < 0 || trackIndex >= fNumTagsStored || !fV0motherIndex)
return -99;
return fV0motherIndex[trackIndex];
}
Bool_t AliTPCPIDBase::TPCCutMIGeo(const AliVTrack* track, const AliVEvent* evt, TTreeStream* streamer)
{
if (!track || !evt)
return kFALSE;
const Short_t sign = track->Charge();
Double_t xyz[50];
Double_t pxpypz[50];
Double_t cv[100];
track->GetXYZ(xyz);
track->GetPxPyPz(pxpypz);
AliExternalTrackParam* par = new AliExternalTrackParam(xyz, pxpypz, cv, sign);
const AliESDtrack dummy;
const Double_t magField = evt->GetMagneticField();
Double_t varGeom = dummy.GetLengthInActiveZone(par, 3, 236, magField, 0, 0);
Double_t varNcr = track->GetTPCClusterInfo(3, 1);
Double_t varNcls = track->GetTPCsignalN();
const Double_t varEval = 130. - 5. * TMath::Abs(1. / track->Pt());
Bool_t cutGeom = varGeom > fgCutGeo * varEval;
Bool_t cutNcr = varNcr > fgCutNcr * varEval;
Bool_t cutNcls = varNcls > fgCutNcl * varEval;
Bool_t kout = cutGeom && cutNcr && cutNcls;
if (streamer) {
Double_t dedx = track->GetTPCsignal();
(*streamer)<<"tree"<<
"param.="<< par<<
"varGeom="<<varGeom<<
"varNcr="<<varNcr<<
"varNcls="<<varNcls<<
"cutGeom="<<cutGeom<<
"cutNcr="<<cutNcr<<
"cutNcls="<<cutNcls<<
"kout="<<kout<<
"dedx="<<dedx<<
"\n";
}
delete par;
return kout;
}
Bool_t AliTPCPIDBase::TPCnclCut(const AliVTrack* track)
{
if (!track)
return kFALSE;
return (track->GetTPCsignalN() >= fgCutPureNcl);
}