]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGDQ/dielectron/AliDielectronPID.cxx
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronPID.cxx
index efa9dfdfa35e0ae144a4cdbf8af64e0badad0ab2..0253771885b0c88ee38f61c8d88193b364e1c5e9 100644 (file)
@@ -34,9 +34,13 @@ Detailed description
 #include <AliLog.h>
 #include <AliExternalTrackParam.h>
 #include <AliPIDResponse.h>
+#include <AliTRDPIDResponse.h>
 #include <AliESDtrack.h> //!!!!! Remove once Eta correction is treated in the tender
+#include <AliAODTrack.h>
+#include <AliAODPid.h>
 
 #include "AliDielectronVarManager.h"
+#include "AliDielectronVarCuts.h"
 
 #include "AliDielectronPID.h"
 
@@ -46,6 +50,8 @@ TGraph *AliDielectronPID::fgFitCorr=0x0;
 Double_t AliDielectronPID::fgCorr=0.0;
 Double_t AliDielectronPID::fgCorrdEdx=1.0;
 TF1 *AliDielectronPID::fgFunEtaCorr=0x0;
+TF1 *AliDielectronPID::fgFunCntrdCorr=0x0;
+TF1 *AliDielectronPID::fgFunWdthCorr=0x0;
 TGraph *AliDielectronPID::fgdEdxRunCorr=0x0;
 
 AliDielectronPID::AliDielectronPID() :
@@ -68,6 +74,10 @@ AliDielectronPID::AliDielectronPID() :
     fFunLowerCut[icut]=0x0;
     fRequirePIDbit[icut]=0;
     fActiveCuts[icut]=-1;
+    fSigmaFunLow[icut]=0;
+    fSigmaFunUp[icut]=0;
+    fFunSigma[icut]=0x0;
+    fVarCuts[icut]=0x0;
   }
 }
 
@@ -92,6 +102,10 @@ AliDielectronPID::AliDielectronPID(const char* name, const char* title) :
     fFunLowerCut[icut]=0x0;
     fRequirePIDbit[icut]=0;
     fActiveCuts[icut]=0;
+    fSigmaFunLow[icut]=0;
+    fSigmaFunUp[icut]=0;
+    fFunSigma[icut]=0x0;
+    fVarCuts[icut]=0x0;
   }
 }
 
@@ -134,8 +148,8 @@ void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t
   fRequirePIDbit[fNcuts]=pidBitType;
   fActiveCuts[fNcuts]=(var==-1 ? AliDielectronVarManager::kP : var);
 
-  //  AliInfo(Form("Add PID cut %d: sigma [% .1f,% .1f] \t cut [% .1f,% .f] \t var %d->%s \n",
-  //          fNcuts,nSigmaLow,nSigmaUp,min,max,fActiveCuts[fNcuts],AliDielectronVarManager::GetValueName(fActiveCuts[fNcuts])));  
+  AliDebug(1,Form("Add PID cut %d: sigma [% .1f,% .1f] \t cut [% .1f,% .f] \t var %d->%s \n",
+                 fNcuts,nSigmaLow,nSigmaUp,min,max,fActiveCuts[fNcuts],AliDielectronVarManager::GetValueName(fActiveCuts[fNcuts])));
   
   ++fNcuts;
 
@@ -190,6 +204,61 @@ void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * con
   AddCut(det,type,0.,0.,min,max,exclude,pidBitType,var);
 }
 
+//______________________________________________
+void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, Double_t nSigmaUp,
+                              Double_t min, Double_t max, Bool_t exclude,
+                              UInt_t pidBitType, TF1 * const funSigma)
+{
+  //
+  // cut using a TF1 as lower cut
+  //
+  if (funSigma==0x0){
+    AliError("A valid function is required for the sigma cut. Not adding the cut!");
+    return;
+  }
+  fFunSigma[fNcuts]=funSigma;
+  fSigmaFunLow[fNcuts]=min;
+  fSigmaFunUp[fNcuts]=max;
+
+  AddCut(det,type,nSigmaLow,nSigmaUp,0,0,exclude,pidBitType,-1);
+}
+
+//______________________________________________
+void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, Double_t nSigmaUp,
+                              AliDielectronVarCuts *var, Bool_t exclude/*=kFALSE*/,
+                              UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
+{
+  //
+  // Add a pid nsigma cut
+  // use response of detector 'det' in the ranges for variables defined in var
+  // use a sigma band between 'nSigmaLow' and 'nSigmaUp'
+  // if nSigmaUp==-99999. then nSigmaLow will be uesd as a symmetric band +- nSigmaLow
+  // specify whether to 'exclude' the given band
+  //
+  if(!var) return;
+  if (fNcuts>=kNmaxPID){
+    AliError(Form("only %d pid cut ranges allowed",kNmaxPID));
+    return;
+  }
+  if (TMath::Abs(nSigmaUp+99999.)<1e-20){
+    nSigmaUp=TMath::Abs(nSigmaLow);
+    nSigmaLow=-1.*nSigmaUp;
+  }
+  fDetType[fNcuts]=det;
+  fPartType[fNcuts]=type;
+  fNsigmaLow[fNcuts]=nSigmaLow;
+  fNsigmaUp[fNcuts]=nSigmaUp;
+  fExclude[fNcuts]=exclude;
+  fRequirePIDbit[fNcuts]=pidBitType;
+  fVarCuts[fNcuts]=var;
+
+  AliDebug(1,Form("Add PID cut %d: sigma [% .1f,% .1f] \n",
+                 fNcuts,nSigmaLow,nSigmaUp));
+  
+  ++fNcuts;
+
+}
+
 //______________________________________________
 Bool_t AliDielectronPID::IsSelected(TObject* track)
 {
@@ -200,15 +269,22 @@ Bool_t AliDielectronPID::IsSelected(TObject* track)
   //loop over all cuts
   AliVTrack *part=static_cast<AliVTrack*>(track);
   AliESDtrack *esdTrack=0x0;
+  AliAODTrack *aodTrack=0x0;
   Double_t origdEdx=-1;
   
   // apply ETa correction, remove once this is in the tender
-  if( (part->IsA() == AliESDtrack::Class()) && fgFunEtaCorr ){
+  if( (part->IsA() == AliESDtrack::Class()) ){
     esdTrack=static_cast<AliESDtrack*>(part);
     origdEdx=esdTrack->GetTPCsignal();
     esdTrack->SetTPCsignal(origdEdx/GetEtaCorr(esdTrack)/fgCorrdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
+  } else if ( (part->IsA() == AliAODTrack::Class()) ){
+    aodTrack=static_cast<AliAODTrack*>(track);
+    AliAODPid *pid=const_cast<AliAODPid*>(aodTrack->GetDetPid());
+    if (pid){
+      origdEdx=pid->GetTPCsignal();
+      pid->SetTPCsignal(origdEdx/GetEtaCorr(aodTrack)/fgCorrdEdx);
+    }
   }
-
   
   //Fill values
   Double_t values[AliDielectronVarManager::kNMaxValues];
@@ -220,10 +296,26 @@ Bool_t AliDielectronPID::IsSelected(TObject* track)
     Double_t min=fmin[icut];
     Double_t max=fmax[icut];
     Double_t val=values[fActiveCuts[icut]];
-    
+
     // test var range. In case min==max do not cut
-    if ( (TMath::Abs(min-max)>1e-20) && (val<min || val>=max) ) continue;
-    
+    if ( fVarCuts[icut] ) {
+      if ( !fVarCuts[icut]->IsSelected(part) ) continue;
+    }
+    else if ( ( (TMath::Abs(min-max)>1e-20) && (val<min || val>=max) ) ) {
+       continue;
+    }
+
+    // check if fFunSigma is set, then check if 'part' is in sigma range of the function
+    if(fFunSigma[icut]){
+        val= fPIDResponse->NumberOfSigmasTPC(part, fPartType[icut]);
+        if (fPartType[icut]==AliPID::kElectron){
+            val-=fgCorr;
+        }
+        min= fFunSigma[icut]->Eval(part->GetTPCmomentum())+fSigmaFunLow[icut];
+        max= fFunSigma[icut]->Eval(part->GetTPCmomentum())+fSigmaFunUp[icut];
+        if(val<min || val>=max) continue;
+    }
+
     switch (fDetType[icut]){
     case kITS:
       selected = IsSelectedITS(part,icut);
@@ -237,6 +329,9 @@ Bool_t AliDielectronPID::IsSelected(TObject* track)
     case kTRDeleEff:
       selected = IsSelectedTRDeleEff(part,icut);
       break;
+    case kTRDeleEff2D:
+      selected = IsSelectedTRDeleEff(part,icut,AliTRDPIDResponse::kLQ2D);
+      break;
     case kTOF:
       selected = IsSelectedTOF(part,icut);
       break;
@@ -246,12 +341,20 @@ Bool_t AliDielectronPID::IsSelected(TObject* track)
     }
     if (!selected) {
       if (esdTrack) esdTrack->SetTPCsignal(origdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
+      else if (aodTrack){
+        AliAODPid *pid=const_cast<AliAODPid*>(aodTrack->GetDetPid());
+        if (pid) pid->SetTPCsignal(origdEdx);
+      }
 
       return kFALSE;
     }
   }
 
   if (esdTrack) esdTrack->SetTPCsignal(origdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
+  else if (aodTrack){
+    AliAODPid *pid=const_cast<AliAODPid*>(aodTrack->GetDetPid());
+    if (pid) pid->SetTPCsignal(origdEdx);
+  }
   return selected;
 }
 
@@ -262,9 +365,9 @@ Bool_t AliDielectronPID::IsSelectedITS(AliVTrack * const part, Int_t icut)
   // ITS part of the PID check
   // Don't accept the track if there was no pid bit set
   //
-  
-  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kITSpid)) return kFALSE;
-  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kITSpid)) return kTRUE;
+  AliPIDResponse::EDetPidStatus pidStatus = fPIDResponse->CheckPIDStatus(AliPIDResponse::kITS,part);
+  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kFALSE;
+  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kTRUE;
 
   Double_t mom=part->P();
   
@@ -285,8 +388,9 @@ Bool_t AliDielectronPID::IsSelectedTPC(AliVTrack * const part, Int_t icut)
   // TPC part of the PID check
   // Don't accept the track if there was no pid bit set
   //
-  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTPCpid)) return kFALSE;
-  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTPCpid)) return kTRUE;
+  AliPIDResponse::EDetPidStatus pidStatus = fPIDResponse->CheckPIDStatus(AliPIDResponse::kTPC,part);
+  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kFALSE;
+  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kTRUE;
 
   Double_t mom=part->GetTPCmomentum();
   
@@ -294,6 +398,8 @@ Bool_t AliDielectronPID::IsSelectedTPC(AliVTrack * const part, Int_t icut)
 
   if (fPartType[icut]==AliPID::kElectron){
     numberOfSigmas-=fgCorr;
+    numberOfSigmas-=GetCntrdCorr(part);
+    numberOfSigmas/=GetWdthCorr(part);
   }
   
   // test if we are supposed to use a function for the cut
@@ -312,8 +418,10 @@ Bool_t AliDielectronPID::IsSelectedTRD(AliVTrack * const part, Int_t icut)
   // the TRD checks on the probabilities.
   //
 
-  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kFALSE;
-  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kTRUE;
+  AliPIDResponse::EDetPidStatus pidStatus = fPIDResponse->CheckPIDStatus(AliPIDResponse::kTRD,part);
+  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kFALSE;
+  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kTRUE;
+
   if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable && (part->GetTRDntrackletsPID()<4)) return kTRUE;
 
   Double_t p[AliPID::kSPECIES]={0.};
@@ -325,7 +433,7 @@ Bool_t AliDielectronPID::IsSelectedTRD(AliVTrack * const part, Int_t icut)
 }
 
 //______________________________________________
-Bool_t AliDielectronPID::IsSelectedTRDeleEff(AliVTrack * const part, Int_t icut)
+Bool_t AliDielectronPID::IsSelectedTRDeleEff(AliVTrack * const part, Int_t icut, AliTRDPIDResponse::ETRDPIDMethod PIDmethod)
 {
   //
   // TRD part of the pid check using electron efficiency requirement
@@ -333,10 +441,17 @@ Bool_t AliDielectronPID::IsSelectedTRDeleEff(AliVTrack * const part, Int_t icut)
   //   and the lower limit regarded as the requested electron efficiency
   //
 
-  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kFALSE;
-  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kTRUE;
+  AliPIDResponse::EDetPidStatus pidStatus = fPIDResponse->CheckPIDStatus(AliPIDResponse::kTRD,part);
+  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kFALSE;
+  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kTRUE;
+
+  Double_t centrality = -1.;
+  if(part->IsA() == AliESDtrack::Class())
+    centrality=(const_cast<AliESDEvent*>( (static_cast<const AliESDtrack*>(part))->GetESDEvent()) )->GetCentrality()->GetCentralityPercentile("V0M");
+  if(part->IsA() == AliAODTrack::Class())
+    centrality=(const_cast<AliAODEvent*>( (static_cast<const AliAODTrack*>(part))->GetAODEvent()) )->GetCentrality()->GetCentralityPercentile("V0M");
 
-  Bool_t selected=fPIDResponse->IdentifiedAsElectronTRD(part,fNsigmaLow[icut])^fExclude[icut];
+  Bool_t selected=fPIDResponse->IdentifiedAsElectronTRD(part,fNsigmaLow[icut], centrality, PIDmethod)^fExclude[icut];
   return selected;
 }
 
@@ -347,9 +462,9 @@ Bool_t AliDielectronPID::IsSelectedTOF(AliVTrack * const part, Int_t icut)
   // TOF part of the PID check
   // Don't accept the track if there was no pid bit set
   //
-  
-  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTOFpid)) return kFALSE;
-  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTOFpid)) return kTRUE;
+  AliPIDResponse::EDetPidStatus pidStatus = fPIDResponse->CheckPIDStatus(AliPIDResponse::kTOF,part);
+  if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kFALSE;
+  if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&(pidStatus!=AliPIDResponse::kDetPidOk)) return kTRUE;
 
   Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasTOF(part, fPartType[icut]);
   
@@ -477,6 +592,38 @@ void AliDielectronPID::SetDefaults(Int_t def){
     AddCut(kTPC,AliPID::kElectron,lowerCut,4.);
     AddCut(kTOF,AliPID::kElectron,-5,5,0,200,kFALSE,AliDielectronPID::kIfAvailable);
   }
+  else if (def==13) {
+    // TPC electron inclusion
+    // TOF electron inclusion if available
+    AddCut(kTOF,AliPID::kElectron,-3.,3.,0,200,kFALSE,AliDielectronPID::kIfAvailable);
+    AddCut(kTPC,AliPID::kElectron,10.);
+  }
+  else if (def==14) {
+    // TRD 1D 90% elec eff, 4-6 tracklets
+    // TPC electron inclusion
+    // TOF electron inclusion if available
+    AddCut(AliDielectronPID::kTRDeleEff,AliPID::kElectron,.9,1.,3.5,6.,kFALSE,
+          AliDielectronPID::kIfAvailable,AliDielectronVarManager::kTRDpidQuality);
+    AddCut(kTOF,AliPID::kElectron,-3.,3.,0,200,kFALSE,AliDielectronPID::kIfAvailable);
+    AddCut(kTPC,AliPID::kElectron,10.);
+  }
+  else if (def==15) {
+    // TRD 1D 90% elec eff, 4-6 tracklets, chi2 < 2
+    // TPC electron inclusion
+    // TOF electron inclusion if available
+    AddCut(AliDielectronPID::kTRDeleEff,AliPID::kElectron,.9,1.,3.5,6.,kFALSE,
+          AliDielectronPID::kIfAvailable,AliDielectronVarManager::kTRDpidQuality);
+    AddCut(AliDielectronPID::kTRDeleEff,AliPID::kElectron,.9,1.,0.,2.,kFALSE,
+          AliDielectronPID::kIfAvailable,AliDielectronVarManager::kTRDchi2);
+    AddCut(kTOF,AliPID::kElectron,-3.,3.,0,200,kFALSE,AliDielectronPID::kIfAvailable);
+    AddCut(kTPC,AliPID::kElectron,10.);
+  }
+  else if (def==16) {
+    // TPC electron inclusion
+    // TOF electron inclusion if available
+    AddCut(kTOF,AliPID::kElectron,-3.,3.,0,200,kFALSE,AliDielectronPID::kIfAvailable);
+    AddCut(kTPC,AliPID::kElectron,-3.5,+3.5);
+  }
 
 }
 
@@ -503,7 +650,7 @@ void AliDielectronPID::SetCorrVal(Double_t run)
 }
 
 //______________________________________________
-Double_t AliDielectronPID::GetEtaCorr(AliVTrack *track)
+Double_t AliDielectronPID::GetEtaCorr(const AliVTrack *track)
 {
   //
   // return eta correction
@@ -511,3 +658,41 @@ Double_t AliDielectronPID::GetEtaCorr(AliVTrack *track)
   if (!fgFunEtaCorr) return 1;
   return fgFunEtaCorr->Eval(track->Eta());
 }
+
+//______________________________________________
+void AliDielectronPID::SetCentroidCorrFunction(TF1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
+{
+  fun->GetHistogram()->GetXaxis()->SetUniqueID(varx);
+  fun->GetHistogram()->GetYaxis()->SetUniqueID(vary);
+  fun->GetHistogram()->GetZaxis()->SetUniqueID(varz);
+  fgFunCntrdCorr=fun;
+}
+//______________________________________________
+void AliDielectronPID::SetWidthCorrFunction(TF1 *fun, UInt_t varx, UInt_t vary, UInt_t varz)
+{
+  fun->GetHistogram()->GetXaxis()->SetUniqueID(varx);
+  fun->GetHistogram()->GetYaxis()->SetUniqueID(vary);
+  fun->GetHistogram()->GetZaxis()->SetUniqueID(varz);
+  fgFunWdthCorr=fun;
+}
+
+//______________________________________________
+Double_t AliDielectronPID::GetPIDCorr(const AliVTrack *track, TF1 *fun)
+{
+  //
+  // return correction value
+  //
+
+  //Fill only event and vparticle values (otherwise we end up in a circle)
+  Double_t values[AliDielectronVarManager::kNMaxValues];
+  AliDielectronVarManager::FillVarVParticle(track,values);
+
+  Int_t dim=fun->GetNdim();
+  Double_t var[3] = {0.,0.,0.};
+  if(dim>0) var[0] = values[fun->GetHistogram()->GetXaxis()->GetUniqueID()];
+  if(dim>1) var[1] = values[fun->GetHistogram()->GetYaxis()->GetUniqueID()];
+  if(dim>2) var[2] = values[fun->GetHistogram()->GetZaxis()->GetUniqueID()];
+  Double_t corr = fun->Eval(var[0],var[1],var[2]);
+  // printf(" %d-dim CORR value: %f (track %p) \n",dim,corr,track);
+  return corr;
+}