#include <TH1F.h>
#include <TH2F.h>
#include <THnSparse.h>
#include <TList.h>
#include <TString.h>
#include "AliAODPid.h"
#include "AliAODTrack.h"
#include "AliAODMCParticle.h"
#include "AliESDtrack.h"
#include "AliLog.h"
#include "AliMCParticle.h"
#include "AliOADBContainer.h"
#include "AliPID.h"
#include "AliPIDResponse.h"
#include "AliHFEOADBThresholdsTRD.h"
#include "AliHFEpidQAmanager.h"
#include "AliHFEpidTRD.h"
ClassImp(AliHFEpidTRD)
AliHFEpidTRD::AliHFEpidTRD() :
AliHFEpidBase()
, fOADBThresholds(NULL)
, fMinP(0.5)
, fNTracklets(6)
, fCutNTracklets(0)
, fRunNumber(0)
, fElectronEfficiency(0.90)
, fTotalChargeInSlice0(kFALSE)
, fTRDOldPIDMethod(kFALSE)
, fTRD2DPID(kFALSE)
{
memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
}
AliHFEpidTRD::AliHFEpidTRD(const char* name) :
AliHFEpidBase(name)
, fOADBThresholds(NULL)
, fMinP(0.5)
, fNTracklets(6)
, fCutNTracklets(0)
, fRunNumber(0)
, fElectronEfficiency(0.91)
, fTotalChargeInSlice0(kFALSE)
, fTRDOldPIDMethod(kFALSE)
, fTRD2DPID(kFALSE)
{
memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
}
AliHFEpidTRD::AliHFEpidTRD(const AliHFEpidTRD &ref):
AliHFEpidBase("")
, fOADBThresholds(NULL)
, fMinP(ref.fMinP)
, fNTracklets(ref.fNTracklets)
, fCutNTracklets(ref.fCutNTracklets)
, fRunNumber(ref.fRunNumber)
, fElectronEfficiency(ref.fElectronEfficiency)
, fTotalChargeInSlice0(ref.fTotalChargeInSlice0)
, fTRDOldPIDMethod(ref.fTRDOldPIDMethod)
, fTRD2DPID(ref.fTRD2DPID)
{
memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
ref.Copy(*this);
}
AliHFEpidTRD &AliHFEpidTRD::operator=(const AliHFEpidTRD &ref){
if(this != &ref){
ref.Copy(*this);
}
return *this;
}
void AliHFEpidTRD::Copy(TObject &ref) const {
AliHFEpidTRD &target = dynamic_cast<AliHFEpidTRD &>(ref);
target.fMinP = fMinP;
target.fNTracklets = fNTracklets;
target.fCutNTracklets = fCutNTracklets;
target.fRunNumber = fRunNumber;
target.fTotalChargeInSlice0 = fTotalChargeInSlice0;
target.fTRDOldPIDMethod = fTRDOldPIDMethod;
target.fTRD2DPID = fTRD2DPID;
target.fElectronEfficiency = fElectronEfficiency;
memcpy(target.fThreshParams, fThreshParams, sizeof(Double_t) * kThreshParams);
AliHFEpidBase::Copy(ref);
}
AliHFEpidTRD::~AliHFEpidTRD(){
}
Bool_t AliHFEpidTRD::InitializePID(Int_t run){
if(fTRDOldPIDMethod) return Initialize1D(run);
else return kTRUE;
}
Bool_t AliHFEpidTRD::Initialize1D(Int_t run){
AliDebug(1, Form("Initializing TRD PID for run %d", run));
if(InitParamsFromOADB(run)){
SetBit(kThresholdsInitialized);
return kTRUE;
}
AliDebug(1, Form("Threshold Parameters for %d tracklets and an electron efficiency %f loaded:", fNTracklets, fElectronEfficiency));
AliDebug(1, Form("Params: [%f|%f|%f|%f]", fThreshParams[0], fThreshParams[1], fThreshParams[2], fThreshParams[3]));
fRunNumber = run;
return kFALSE;
}
Int_t AliHFEpidTRD::IsSelected(const AliHFEpidObject *track, AliHFEpidQAmanager *pidqa) const {
if(fTRDOldPIDMethod) return IsSelected1D(track, pidqa);
else return IsSelectedTRDPID(track, pidqa);
}
Int_t AliHFEpidTRD::IsSelected1D(const AliHFEpidObject *track, AliHFEpidQAmanager *pidqa) const {
if(!TestBit(kThresholdsInitialized)) {
AliDebug(1,"Threshold Parameters not available");
return 0;
}
AliDebug(2, "Applying TRD PID");
if(!fkPIDResponse){
AliDebug(2, "Cannot process track");
return 0;
}
AliHFEpidObject::AnalysisType_t anatype = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis: AliHFEpidObject::kAODanalysis;
Double_t p = GetP(track->GetRecTrack(), anatype);
if(p < fMinP){
AliDebug(2, Form("Track momentum below %f", fMinP));
return 0;
}
if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kBeforePID);
if(fCutNTracklets > 0){
AliDebug(1, Form("Number of tracklets cut applied: %d\n", fCutNTracklets));
Int_t ntracklets = track->GetRecTrack() ? track->GetRecTrack()->GetTRDntrackletsPID() : 0;
if(TestBit(kExactTrackletCut)){
AliDebug(1, Form("Exact cut applied: %d tracklets found\n", ntracklets));
if(ntracklets != fCutNTracklets) return 0;
} else {
AliDebug(1, Form("Greater Equal cut applied: %d tracklets found\n", ntracklets));
if(ntracklets < fCutNTracklets) return 0;
}
}
AliDebug(1,"Track selected\n");
Double_t electronLike = GetElectronLikelihood(track->GetRecTrack(), anatype);
Double_t threshold;
if(TestBit(kSelectCutOnTheFly)){
threshold = GetTRDthresholds(p, track->GetRecTrack()->GetTRDntrackletsPID());
} else {
threshold = GetTRDthresholds(p);
}
AliDebug(2, Form("Threshold: %f\n", threshold));
if(electronLike > threshold){
if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kAfterPID);
return 11;
}
return 211;
}
Int_t AliHFEpidTRD::IsSelectedTRDPID(const AliHFEpidObject *track, AliHFEpidQAmanager *pidqa) const {
AliDebug(2, "Applying TRD PID");
if(!fkPIDResponse){
AliDebug(2, "Cannot process track");
return 0;
}
AliHFEpidObject::AnalysisType_t anatype = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis: AliHFEpidObject::kAODanalysis;
Double_t p = GetP(track->GetRecTrack(), anatype);
if(p < fMinP){
AliDebug(2, Form("Track momentum below %f", fMinP));
return 0;
}
if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kBeforePID);
if(fCutNTracklets > 0){
AliDebug(1, Form("Number of tracklets cut applied: %d\n", fCutNTracklets));
Int_t ntracklets = track->GetRecTrack() ? track->GetRecTrack()->GetTRDntrackletsPID() : 0;
if(TestBit(kExactTrackletCut)){
AliDebug(1, Form("Exact cut applied: %d tracklets found\n", ntracklets));
if(ntracklets != fCutNTracklets) return 0;
} else {
AliDebug(1, Form("Greater Equal cut applied: %d tracklets found\n", ntracklets));
if(ntracklets < fCutNTracklets) return 0;
}
}
AliDebug(1,"Track selected\n");
Int_t centralitybin = track->IsPbPb() ? track->GetCentrality() : -2;
Float_t fCentralityLimitsdefault[12]= {0.,5.,10., 20., 30., 40., 50., 60.,70.,80., 90., 100.};
Float_t centrality=-1;
if(centralitybin>=0) centrality=fCentralityLimitsdefault[centralitybin]+1;
AliTRDPIDResponse::ETRDPIDMethod fTRDPIDMethod = AliTRDPIDResponse::kLQ1D;
if(fTRD2DPID) fTRDPIDMethod = AliTRDPIDResponse::kLQ2D;
Int_t ntrackletsPID=0;
Bool_t iselectron=kFALSE;
iselectron=fkPIDResponse->IdentifiedAsElectronTRD(track->GetRecTrack(),ntrackletsPID,fElectronEfficiency,centrality,fTRDPIDMethod);
if((ntrackletsPID==fCutNTracklets) && iselectron){
AliDebug(2, Form("Electron effi: %f %i %i %f %i\n", fElectronEfficiency,track->GetCentrality(),centralitybin,centrality,fTRDPIDMethod));
if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kAfterPID);
return 11;
} else return 211;
}
Double_t AliHFEpidTRD::GetTRDthresholds(Double_t p, UInt_t nTracklets) const {
Double_t threshParams[4];
AliDebug(1, Form("Select cut for %d tracklets\n", nTracklets));
AliHFEOADBThresholdsTRD *thresholds = dynamic_cast<AliHFEOADBThresholdsTRD *>(fOADBThresholds->GetObject(fRunNumber));
if(!thresholds){
AliDebug(1, Form("Thresholds for run %d not in the OADB", fRunNumber));
return 0.;
}
if(!thresholds->GetThresholdParameters(nTracklets, fElectronEfficiency, threshParams)){
AliDebug(1, "loading thresholds failed\n");
return 0.;
}
Double_t threshold = 1. - threshParams[0] - threshParams[1] * p - threshParams[2] * TMath::Exp(-threshParams[3] * p);
return TMath::Max(TMath::Min(threshold, 0.99), 0.2);
}
Double_t AliHFEpidTRD::GetTRDthresholds(Double_t p) const {
Double_t threshold = 1. - fThreshParams[0] - fThreshParams[1] * p - fThreshParams[2] * TMath::Exp(-fThreshParams[3] * p);
return TMath::Max(TMath::Min(threshold, 0.99), 0.2);
}
Bool_t AliHFEpidTRD::InitParamsFromOADB(Int_t run){
AliHFEOADBThresholdsTRD *thresholds = dynamic_cast<AliHFEOADBThresholdsTRD *>(fOADBThresholds->GetObject(run));
if(!thresholds){
AliDebug(1, Form("Thresholds for run %d not in the OADB", run));
return kFALSE;
}
return thresholds->GetThresholdParameters(fNTracklets, fElectronEfficiency, fThreshParams);
}
void AliHFEpidTRD::RenormalizeElPi(const Double_t * const likein, Double_t * const likeout) const {
memset(likeout, 0, sizeof(Double_t) * AliPID::kSPECIES);
Double_t norm = likein[AliPID::kElectron] + likein[AliPID::kPion];
if(norm == 0.) norm = 1.;
likeout[AliPID::kElectron] = likein[AliPID::kElectron] / norm;
likeout[AliPID::kPion] = likein[AliPID::kPion] / norm;
}
Double_t AliHFEpidTRD::GetElectronLikelihood(const AliVTrack *track, AliHFEpidObject::AnalysisType_t anaType) const {
Double_t pidProbs[AliPID::kSPECIES]; memset(pidProbs, 0, sizeof(Double_t) * AliPID::kSPECIES);
if(anaType == AliHFEpidObject::kESDanalysis){
const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
if(esdtrack) esdtrack->GetTRDpid(pidProbs);
} else {
if(fTRD2DPID) fkPIDResponse->ComputeTRDProbability(track, AliPID::kSPECIES, pidProbs,AliTRDPIDResponse::kLQ2D);
else fkPIDResponse->ComputeTRDProbability(track, AliPID::kSPECIES, pidProbs,AliTRDPIDResponse::kLQ1D);
}
if(!IsRenormalizeElPi()) return pidProbs[AliPID::kElectron];
Double_t probsNew[AliPID::kSPECIES];
RenormalizeElPi(pidProbs, probsNew);
return probsNew[AliPID::kElectron];
}
Double_t AliHFEpidTRD::GetP(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType) const {
Double_t p = 0.;
if(anaType == AliHFEpidObject::kESDanalysis){
const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
if(esdtrack) p = esdtrack->GetOuterParam() ? esdtrack->GetOuterParam()->P() : esdtrack->P();
} else {
const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
if(aodtrack) p = aodtrack->P();
}
return p;
}
Double_t AliHFEpidTRD::GetChargeLayer(const AliVParticle *track, UInt_t layer, AliHFEpidObject::AnalysisType_t anaType) const {
if(layer >= 6) return 0.;
Double_t charge = 0.;
if(anaType == AliHFEpidObject::kESDanalysis){
const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
if(esdtrack){
if(fTotalChargeInSlice0)
charge = esdtrack->GetTRDslice(static_cast<UInt_t>(layer), 0);
else
for(Int_t islice = 0; islice < esdtrack->GetNumberOfTRDslices(); islice++) charge += esdtrack->GetTRDslice(static_cast<UInt_t>(layer), islice);
}
} else {
const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
AliAODPid *aoddetpid = aodtrack ? aodtrack->GetDetPid() : NULL;
if(aoddetpid){
if(fTotalChargeInSlice0)
charge = aoddetpid->GetTRDslices()[layer * aoddetpid->GetTRDnSlices()];
else
for(Int_t islice = 0; islice < aoddetpid->GetTRDnSlices(); islice++) charge += aoddetpid->GetTRDslices()[layer * aoddetpid->GetTRDnSlices() + islice];
}
}
return charge;
}
void AliHFEpidTRD::GetTRDmomenta(const AliVTrack *track, Double_t *mom) const {
for(Int_t itl = 0; itl < 6; itl++)
mom[itl] = track->GetTRDmomentum(itl);
}
Double_t AliHFEpidTRD::GetTRDSignalV1(const AliESDtrack *track, Float_t truncation) const {
const Int_t kNSlices = 48;
const Int_t kLastSlice = 6;
const Double_t kVerySmall = 1e-12;
const Double_t kWeightSlice[8] = {1., 2.122, 1.8, 1.635, 1.595, 1.614, 1.16, 7.0};
const Double_t kWeightSliceNo0[8] = {1., 1., 1.271, 1.451, 1.531, 1.543, 1.553, 2.163};
const Double_t *kWeightFactor = fTotalChargeInSlice0 ? kWeightSliceNo0 : kWeightSlice;
AliDebug(3, Form("Number of Tracklets: %d\n", track->GetTRDntrackletsPID()));
Double_t trdSlices[kNSlices], tmp[kNSlices];
Int_t indices[48];
Int_t icnt = 0;
for(Int_t idet = 0; idet < 6; idet++)
for(Int_t islice = fTotalChargeInSlice0 ? 1 : 0 ; islice <= kLastSlice; islice++){
AliDebug(2, Form("Chamber[%d], Slice[%d]: TRDSlice = %f", idet, islice, track->GetTRDslice(idet, islice)));
if(TMath::Abs(track->GetTRDslice(idet, islice)) < kVerySmall) continue;;
trdSlices[icnt++] = track->GetTRDslice(idet, islice) * kWeightFactor[islice];
}
AliDebug(1, Form("Number of Slices: %d\n", icnt));
if(icnt < 6) return 0.;
TMath::Sort(icnt, trdSlices, indices, kFALSE);
memcpy(tmp, trdSlices, sizeof(Double_t) * icnt);
for(Int_t ien = 0; ien < icnt; ien++)
trdSlices[ien] = tmp[indices[ien]];
Double_t trdSignal = TMath::Mean(static_cast<Int_t>(static_cast<Float_t>(icnt) * truncation), trdSlices);
Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
AliDebug(3, Form("PID Meth. 1: p[%f], TRDSignal[%f]", mom, trdSignal));
return trdSignal;
}
Double_t AliHFEpidTRD::GetTRDSignalV2(const AliESDtrack *track, Float_t truncation) const {
const Double_t kWeightSlice[8] = {1., 2.122, 1.8, 1.635, 1.595, 1.614, 1.16, 7.0};
const Int_t kLayers = 6;
const Int_t kSlicesLow = 6;
const Int_t kSlicesHigh = 1;
const Double_t kVerySmall = 1e-12;
Double_t trdSlicesLowTime[kLayers*kSlicesLow], trdSlicesRemaining[kLayers*(kSlicesHigh + kSlicesLow)];
Int_t indices[kLayers*kSlicesLow];
Int_t cntLowTime=0, cntRemaining = 0;
for(Int_t idet = 0; idet < 6; idet++)
for(Int_t islice = fTotalChargeInSlice0 ? 1 : 0; islice < kSlicesLow+kSlicesHigh; islice++){
if(TMath::Abs(track->GetTRDslice(idet, islice)) < kVerySmall) continue;;
if(islice < kSlicesLow){
AliDebug(3, Form("Part 1, Det[%d], Slice[%d], TRDSlice: %f", idet, islice, track->GetTRDslice(idet, islice)));
trdSlicesLowTime[cntLowTime++] = track->GetTRDslice(idet, islice) * kWeightSlice[islice];
} else{
AliDebug(3, Form("Part 1, Det[%d], Slice[%d], TRDSlice: %f", idet, islice, track->GetTRDslice(idet, islice)));
trdSlicesRemaining[cntRemaining++] = track->GetTRDslice(idet, islice) * kWeightSlice[islice];
}
}
if(cntLowTime < 4 || cntRemaining < 2) return 0.;
TMath::Sort(cntLowTime, trdSlicesLowTime, indices, kFALSE);
for(Int_t ien = 0; ien < static_cast<Int_t>(static_cast<Float_t>(cntLowTime) * truncation); ien++)
trdSlicesRemaining[cntRemaining++] = trdSlicesLowTime[indices[ien]];
Double_t trdSignal = TMath::Mean(cntRemaining, trdSlicesRemaining);
Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
AliDebug(3, Form("PID Meth. 2: p[%f], TRDSignal[%f]", mom, trdSignal));
return trdSignal;
}