]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - PWGDQ/dielectron/AliDielectronPID.cxx
including switch to set on/off iso-track core removal, cleaning and bug fix
[u/mrichter/AliRoot.git] / PWGDQ / dielectron / AliDielectronPID.cxx
index b4f0e424be9aa6110e92f4d4f41f71f30f09a4b7..4f029b6f98c5fca60ab9f3d85380734443b6d260 100644 (file)
@@ -28,6 +28,7 @@ Detailed description
 #include <TMath.h>
 #include <TF1.h>
 #include <TGraph.h>
+#include <THnBase.h>
 
 #include <AliVTrack.h>
 #include <AliVCluster.h>
@@ -40,19 +41,23 @@ Detailed description
 #include <AliAODPid.h>
 
 #include "AliDielectronVarManager.h"
+#include "AliDielectronVarCuts.h"
 
 #include "AliDielectronPID.h"
 
 ClassImp(AliDielectronPID)
 
-TGraph *AliDielectronPID::fgFitCorr=0x0;
+TGraph  *AliDielectronPID::fgFitCorr=0x0;
 Double_t AliDielectronPID::fgCorr=0.0;
 Double_t AliDielectronPID::fgCorrdEdx=1.0;
-TF1 *AliDielectronPID::fgFunEtaCorr=0x0;
-TGraph *AliDielectronPID::fgdEdxRunCorr=0x0;
+TF1     *AliDielectronPID::fgFunEtaCorr=0x0;
+TH1     *AliDielectronPID::fgFunCntrdCorr=0x0;
+TH1     *AliDielectronPID::fgFunWdthCorr=0x0;
+TGraph  *AliDielectronPID::fgdEdxRunCorr=0x0;
 
 AliDielectronPID::AliDielectronPID() :
   AliAnalysisCuts(),
+  fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
   fNcuts(0),
   fPIDResponse(0x0)
 {
@@ -74,12 +79,15 @@ AliDielectronPID::AliDielectronPID() :
     fSigmaFunLow[icut]=0;
     fSigmaFunUp[icut]=0;
     fFunSigma[icut]=0x0;
+    fVarCuts[icut]=0x0;
+    fMapElectronCutLow[icut]=0x0;
   }
 }
 
 //______________________________________________
 AliDielectronPID::AliDielectronPID(const char* name, const char* title) :
   AliAnalysisCuts(name, title),
+  fUsedVars(new TBits(AliDielectronVarManager::kNMaxValues)),
   fNcuts(0),
   fPIDResponse(0x0)
 {
@@ -101,6 +109,8 @@ AliDielectronPID::AliDielectronPID(const char* name, const char* title) :
     fSigmaFunLow[icut]=0;
     fSigmaFunUp[icut]=0;
     fFunSigma[icut]=0x0;
+    fVarCuts[icut]=0x0;
+    fMapElectronCutLow[icut]=0x0;
   }
 }
 
@@ -110,6 +120,7 @@ AliDielectronPID::~AliDielectronPID()
   //
   // Default Destructor
   //
+  if (fUsedVars) delete fUsedVars;
 }
 
 //______________________________________________
@@ -141,7 +152,9 @@ void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t
   fmax[fNcuts]=max;
   fExclude[fNcuts]=exclude;
   fRequirePIDbit[fNcuts]=pidBitType;
-  fActiveCuts[fNcuts]=(var==-1 ? AliDielectronVarManager::kP : var);
+  if(var==-1) var=AliDielectronVarManager::kP; // set default
+  fActiveCuts[fNcuts]=var;
+  fUsedVars->SetBitNumber(var,kTRUE);
 
   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])));
@@ -218,6 +231,62 @@ void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t
   AddCut(det,type,nSigmaLow,nSigmaUp,0,0,exclude,pidBitType,-1);
 }
 
+//______________________________________________
+void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, THnBase * const histLow, Double_t nSigmaUp,
+                              Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
+                              UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
+{
+  //
+  // cut using a THnBase as a lower cut
+  //
+  if(histLow==0x0){
+    AliError("A valid histogram is required for the lower cut. Not adding the cut!");
+    return;
+  }
+  fMapElectronCutLow[fNcuts]=histLow;
+  // fill used variables into map
+  for(Int_t idim=0; idim<fMapElectronCutLow[fNcuts]->GetNdimensions(); idim++) {
+    TString vari(fMapElectronCutLow[fNcuts]->GetAxis(idim)->GetName());
+    fUsedVars->SetBitNumber(AliDielectronVarManager::GetValueType(vari.Data()), kTRUE);
+  }
+  AddCut(det,type,0.,nSigmaUp,min,max,exclude,pidBitType,var);
+}
+//______________________________________________
+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)
 {
@@ -244,9 +313,22 @@ Bool_t AliDielectronPID::IsSelected(TObject* track)
       pid->SetTPCsignal(origdEdx/GetEtaCorr(aodTrack)/fgCorrdEdx);
     }
   }
-  
+
+  // check for corrections and add their variables to the fill map
+  if(fgFunCntrdCorr)  {
+    fUsedVars->SetBitNumber(fgFunCntrdCorr->GetXaxis()->GetUniqueID(), kTRUE);
+    fUsedVars->SetBitNumber(fgFunCntrdCorr->GetYaxis()->GetUniqueID(), kTRUE);
+    fUsedVars->SetBitNumber(fgFunCntrdCorr->GetZaxis()->GetUniqueID(), kTRUE);
+  }
+  if(fgFunWdthCorr)  {
+    fUsedVars->SetBitNumber(fgFunWdthCorr->GetXaxis()->GetUniqueID(), kTRUE);
+    fUsedVars->SetBitNumber(fgFunWdthCorr->GetYaxis()->GetUniqueID(), kTRUE);
+    fUsedVars->SetBitNumber(fgFunWdthCorr->GetZaxis()->GetUniqueID(), kTRUE);
+  }
+
   //Fill values
   Double_t values[AliDielectronVarManager::kNMaxValues];
+  AliDielectronVarManager::SetFillMap(fUsedVars);
   AliDielectronVarManager::Fill(track,values);
 
   Bool_t selected=kFALSE;
@@ -255,10 +337,14 @@ 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;
 
+    // test var range. In case min==max do not cut
+    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]){
@@ -276,7 +362,7 @@ Bool_t AliDielectronPID::IsSelected(TObject* track)
       selected = IsSelectedITS(part,icut);
       break;
     case kTPC:
-      selected = IsSelectedTPC(part,icut);
+      selected = IsSelectedTPC(part,icut,values);
       break;
     case kTRD:
       selected = IsSelectedTRD(part,icut);
@@ -320,9 +406,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();
   
@@ -337,28 +423,55 @@ Bool_t AliDielectronPID::IsSelectedITS(AliVTrack * const part, Int_t icut)
 }
 
 //______________________________________________
-Bool_t AliDielectronPID::IsSelectedTPC(AliVTrack * const part, Int_t icut)
+Bool_t AliDielectronPID::IsSelectedTPC(AliVTrack * const part, Int_t icut, Double_t *values)
 {
   //
   // 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();
   
   Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasTPC(part, fPartType[icut]);
 
+  // eta corrections
   if (fPartType[icut]==AliPID::kElectron){
+    // old way 1D
     numberOfSigmas-=fgCorr;
+    // via functions (1-3D)
+    numberOfSigmas-=GetCntrdCorr(part);
+    numberOfSigmas/=GetWdthCorr(part);
   }
-  
-  // test if we are supposed to use a function for the cut
-  if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(mom);
-  if (fFunLowerCut[icut]) fNsigmaLow[icut]=fFunLowerCut[icut]->Eval(mom);
-  
-  Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
+
+  // matching of MC and data //
+
+  // test if we are supposed to use a function for the cut (matching via fits)
+  if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(values[AliDielectronVarManager::kPIn]);
+  if (fFunLowerCut[icut]) fNsigmaLow[icut]=fFunLowerCut[icut]->Eval(values[AliDielectronVarManager::kPIn]);
+
+  // test if we are using cut maps (in calibrated units)
+  Double_t lowElectronCut = fNsigmaLow[icut];
+  Double_t upElectronCut  = fNsigmaUp[icut];
+
+  if((fPartType[icut]==AliPID::kElectron) && (fMapElectronCutLow[icut] )) {
+    Double_t *vals = new Double_t[fMapElectronCutLow[icut]->GetNdimensions()];//={-1};
+    // get array of values for the corresponding dimensions using axis names
+    for(Int_t idim=0; idim<fMapElectronCutLow[icut]->GetNdimensions(); idim++) {
+      vals[idim] = values[AliDielectronVarManager::GetValueType(fMapElectronCutLow[icut]->GetAxis(idim)->GetName())];
+      // printf(" \t %s %.3f ",fMapElectronCutLow[icut]->GetAxis(idim)->GetName(),vals[idim]);
+    }
+    // find bin for values (w/o creating it in case it is not filled)
+    Long_t bin = fMapElectronCutLow[icut]->GetBin(vals,kFALSE);
+    if(bin>0) lowElectronCut=fMapElectronCutLow[icut]->GetBinContent(bin);
+    else lowElectronCut=100;
+    //    printf("  low cut %.3f (%ld) \n", lowElectronCut,bin);
+    delete [] vals;
+  }
+
+
+  Bool_t selected=((numberOfSigmas>=lowElectronCut)&&(numberOfSigmas<=upElectronCut))^fExclude[icut];
   return selected;
 }
 
@@ -370,8 +483,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.};
@@ -391,8 +506,9 @@ 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())
@@ -411,9 +527,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]);
   
@@ -544,8 +660,34 @@ void AliDielectronPID::SetDefaults(Int_t def){
   else if (def==13) {
     // TPC electron inclusion
     // TOF electron inclusion if available
-    AddCut(kTOF,AliPID::kElectron,-4.,4.,0,200,kFALSE,AliDielectronPID::kIfAvailable);
-    AddCut(kTPC,AliPID::kElectron,-3.5,3.5);
+    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);
   }
 
 }
@@ -568,7 +710,7 @@ void AliDielectronPID::SetCorrVal(Double_t run)
   if (fgdEdxRunCorr){
     fgCorrdEdx=fgdEdxRunCorr->Eval(run);
     if (run<fgdEdxRunCorr->GetX()[0]) fgCorrdEdx=fgdEdxRunCorr->GetY()[0];
-    if (run>fgdEdxRunCorr->GetX()[fgFitCorr->GetN()-1]) fgCorrdEdx=fgdEdxRunCorr->GetY()[fgdEdxRunCorr->GetN()-1];
+    if (run>fgdEdxRunCorr->GetX()[fgdEdxRunCorr->GetN()-1]) fgCorrdEdx=fgdEdxRunCorr->GetY()[fgdEdxRunCorr->GetN()-1];
   }
 }
 
@@ -581,3 +723,30 @@ Double_t AliDielectronPID::GetEtaCorr(const AliVTrack *track)
   if (!fgFunEtaCorr) return 1;
   return fgFunEtaCorr->Eval(track->Eta());
 }
+
+//______________________________________________
+Double_t AliDielectronPID::GetPIDCorr(const AliVTrack *track, TH1 *hist)
+{
+  //
+  // return correction value
+  //
+  //TODO: think about taking an values array as argument to reduce # var fills
+
+  //Fill only event and vparticle values (otherwise we end up in a circle)
+  Double_t values[AliDielectronVarManager::kNMaxValues];
+  AliDielectronVarManager::FillVarVParticle(track,values);
+
+  TF1 *fun = (TF1*)hist->GetListOfFunctions()->At(0);
+  Int_t dim=(fun?fun->GetNdim():hist->GetDimension());
+
+  Double_t var[3] = {0.,0.,0.};
+  if(dim>0) var[0] = values[hist->GetXaxis()->GetUniqueID()];
+  if(dim>1) var[1] = values[hist->GetYaxis()->GetUniqueID()];
+  if(dim>2) var[2] = values[hist->GetZaxis()->GetUniqueID()];
+  Double_t corr = 0.0;
+  if(fun) corr = fun->Eval(var[0],var[1],var[2]);
+  else    corr = hist->GetBinContent( hist->FindFixBin(var[0],var[1],var[2]) );
+  //  for(Int_t i=0;i<dim;i++) printf("%d:%.3f  ",i,var[i]);
+  //  printf("%d-dim CORR value: %f (track %p) \n",dim,corr,track);
+  return corr;
+}