ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id: AliTRDdigitizer.cxx 44182 2010-10-10 16:23:39Z cblume $ */

////////////////////////////////////////////////////////////////////////////
//                                                                        //
// Helper class for TRD PID efficiency calculation.                       //
// Calculation of the hadron efficiency dependent on momentum and of      //
// the errors implemented in function CalculatePionEff. The pion          //
// efficiency is based on a predefined electron efficiency.               //
// The default is 90%. To change the, one has to call the function        //
// SetElectronEfficiency.                                                 //
// Other Helper functions decide based on 90% electron efficiency         //
// whether a certain track is accepted as Electron Track.                 //
// The reference data is stored in the TRD OCDB.                          //
//                                                                        //
////////////////////////////////////////////////////////////////////////////

#include "TObject.h"
#include "TObjArray.h"
#include "TMath.h"
#include "TF1.h"
#include "TH1F.h"
#include "TGraph.h"
#include "TGraphErrors.h"
#include "TPDGCode.h"

#include "AliLog.h"
#include "Cal/AliTRDCalPID.h"
#include "AliCDBManager.h"
#include "AliCDBEntry.h"
#include "AliESDtrack.h"
#include "AliPID.h"
#include "AliTRDpidUtil.h"

ClassImp(AliTRDpidUtil)

Float_t AliTRDpidUtil::fgEleEffi = 0.9;

//________________________________________________________________________
AliTRDpidUtil::AliTRDpidUtil() 
  : TObject()
  ,fCalcEleEffi(0.)
  ,fPionEffi(-1.)
  ,fError(-1.)
  ,fThreshold(-1.)
{
  //
  // Default constructor
  //
}

//________________________________________________________________________
Bool_t  AliTRDpidUtil::CalculatePionEffi(TH1* histo1, TH1* histo2)
// Double_t  AliTRDpidUtil::GetError()
{
  //
  // Calculates the pion efficiency
  //

  histo1 -> SetLineColor(kRed);
  histo2 -> SetLineColor(kBlue); 
  if(!histo1->GetEntries() || !histo2 -> GetEntries()){
    AliError("Probability histos empty !");
    return kFALSE;
  }
  if(histo1->GetNbinsX() != histo2->GetNbinsX()){
    AliError(Form("Electron probability discretized differently from pions [%d %d] !", histo1->GetNbinsX(), histo2->GetNbinsX()));
    return kFALSE;
  }
  histo1 -> Scale(1./histo1->GetEntries());
  histo2 -> Scale(1./histo2->GetEntries());

  // array of the integrated sum in each bin
  Double_t sumElecE[kBins+2], sumPionsE[kBins+2];  
  memset(sumElecE, 0, (kBins+2)*sizeof(Double_t));
  memset(sumPionsE, 0, (kBins+2)*sizeof(Double_t));

  Int_t nbinE(histo1->GetNbinsX()),
        abinE(nbinE),
        bbinE(nbinE),
        cbinE(-1);
  // calculate electron efficiency for each bin
  // and also integral distribution
  for(Bool_t bFirst(kTRUE); abinE--;){
    sumElecE[abinE] = sumElecE[abinE+1] + histo1->GetBinContent(abinE+1);
    if((sumElecE[abinE] >= fgEleEffi) && bFirst){
      cbinE = abinE;
      fCalcEleEffi = sumElecE[cbinE];
      bFirst = kFALSE;
    }
  }
  fThreshold = histo1->GetBinCenter(cbinE);

  // calculate pion efficiency of each bin
  // and also integral distribution
  for (;bbinE--;){
    sumPionsE[bbinE] = sumPionsE[bbinE+1] + histo2->GetBinContent(bbinE+1);
    if(bbinE == cbinE) fPionEffi = sumPionsE[cbinE];
  }
  

  // pion efficiency vs electron efficiency
  TGraph gEffis(nbinE, sumElecE, sumPionsE);

  // use fit function to get derivate of the TGraph for error calculation
  TF1 f1("f1","[0]*x*x+[1]*x+[2]", fgEleEffi-.05, fgEleEffi+.05);
  gEffis.Fit(&f1, "Q", "", fgEleEffi-.05, fgEleEffi+.05);
  
  // return the error of the pion efficiency
  if(((1.-fPionEffi) < 0) || ((1.-fCalcEleEffi) < 0)){
    AliError(" EleEffi or PioEffi > 1. Error can not be calculated. Please increase statistics or check your simulation!");
    return kFALSE;
  }
  fError = sqrt(((1/histo2 -> GetEntries())*fPionEffi*(1-fPionEffi))+((f1.Derivative(fgEleEffi))*(f1.Derivative(fgEleEffi))*(1/histo1 -> GetEntries())*fCalcEleEffi*(1-fCalcEleEffi)));

  AliDebug(2, Form("Pion Effi at [%f] : [%f +/- %f], Threshold[%f]", fCalcEleEffi, fPionEffi, fError, fThreshold));
  AliDebug(2, Form("Derivative at %4.2f : %f\n", fgEleEffi, f1.Derivative(fgEleEffi)));
  return kTRUE;
}


//__________________________________________________________________________
Int_t AliTRDpidUtil::GetMomentumBin(Double_t p)
{
  //
  // returns the momentum bin for a given momentum
  //

  Int_t pBin1 = -1;                                    // check bin1
  Int_t pBin2 = -1;                                    // check bin2

  if(p < 0) return -1;                                 // return -1 if momentum < 0
  if(p < AliTRDCalPID::GetMomentum(0)) return 0;                                      // smallest momentum bin
  if(p >= AliTRDCalPID::GetMomentum(AliTRDCalPID::kNMom-1)) return AliTRDCalPID::kNMom-1; // largest momentum bin


  // calculate momentum bin for non extremal momenta
  for(Int_t iMomBin = 1; iMomBin < AliTRDCalPID::kNMom; iMomBin++){
    if(p < AliTRDCalPID::GetMomentum(iMomBin)){
      pBin1 = iMomBin - 1;
      pBin2 = iMomBin;
    }
    else
      continue;

    if(p - AliTRDCalPID::GetMomentum(pBin1) >= AliTRDCalPID::GetMomentum(pBin2) - p){
       return pBin2;
    }
    else{
      return pBin1;
    }
  }

  return -1;
}


//__________________________________________________________________________
Bool_t AliTRDpidUtil::IsElectron(const AliESDtrack *track, ETRDPIDMethod method){
  //
  // Do PID decision for the TRD based on 90% Electron efficiency threshold
  //
  // Author: Markus Fasel (M.Fasel@gsi.de)
  //
  if(method == kESD) method = kNN;
  TString histname[2] = {"fHistThreshLQ", "fHistThreshNN"};
  AliCDBManager *cdb = AliCDBManager::Instance(); 
  AliCDBEntry *cdbThresholds = cdb->Get("TRD/Calib/PIDThresholds");
  if (!cdbThresholds) return kFALSE;
  TObjArray *histos = dynamic_cast<TObjArray *>(cdbThresholds->GetObject());
  if (!histos) return kFALSE;
  TH1 *thresholdHist = dynamic_cast<TH1F *>(histos->FindObject(histname[method].Data()));
  if (!thresholdHist) return kFALSE;
  Double_t threshold = thresholdHist->GetBinContent(GetMomentumBin(track->P()) + 1);
  
  // Do Decision
  Double_t pidProbs[5];
  track->GetTRDpid(pidProbs);
  if(pidProbs[AliPID::kElectron] >= threshold) return kTRUE;
  return kFALSE; 
}

//__________________________________________________________________________
Double_t AliTRDpidUtil::GetSystematicError(const AliESDtrack *track, ETRDPIDMethod method){
  //
  // Returns the pion efficiency at 90% electron efficiency from the OCDB
  //
  // Author: Markus Fasel (M.Fasel@gsi.de)
  //
  if(method == kESD) method = kNN;
  TString histname[2] = {"fHistPionEffLQ", "fHistPionEffNN"};
  AliCDBManager *cdb = AliCDBManager::Instance(); 
  AliCDBEntry *cdbThresholds = cdb->Get("TRD/Calib/PIDThresholds");
  if (!cdbThresholds) return kFALSE;
  TObjArray *histos = dynamic_cast<TObjArray *>(cdbThresholds->GetObject());
  if (!histos) return kFALSE;
  TH1 *thresholdHist = dynamic_cast<TH1F *>(histos->FindObject(histname[method].Data()));
  if (!thresholdHist) return kFALSE;
  return thresholdHist->GetBinContent(GetMomentumBin(track->P()) + 1);
}

//________________________________________________________________________
Int_t AliTRDpidUtil::Pdg2Pid(Int_t pdg){
  //
  // Private Helper function to get the paticle species (ALICE notation)
  // from the Pdg code
  //
  Int_t species;
  switch(TMath::Abs(pdg)){
  case kElectron:
    species = AliPID::kElectron;
    break;
  case kMuonMinus:
    species = AliPID::kMuon;
    break;
  case kPiPlus:
    species = AliPID::kPion;
    break;
  case kKPlus:
    species = AliPID::kKaon;
    break;
  case kProton:
    species = AliPID::kProton;
    break;
  default:
    species = -1;
  }
  return species;
}

//________________________________________________________________________
Int_t AliTRDpidUtil::Mass2Pid(Float_t m){
  //
  // Private Helper function to get the paticle species (ALICE notation)
  // from the Pdg mass
  //

  for(Int_t is(0); is<AliPID::kSPECIES; is++) if(TMath::Abs(m-AliPID::ParticleMass(is))<1.e-4) return is;
  return -1;
}

 AliTRDpidUtil.cxx:1
 AliTRDpidUtil.cxx:2
 AliTRDpidUtil.cxx:3
 AliTRDpidUtil.cxx:4
 AliTRDpidUtil.cxx:5
 AliTRDpidUtil.cxx:6
 AliTRDpidUtil.cxx:7
 AliTRDpidUtil.cxx:8
 AliTRDpidUtil.cxx:9
 AliTRDpidUtil.cxx:10
 AliTRDpidUtil.cxx:11
 AliTRDpidUtil.cxx:12
 AliTRDpidUtil.cxx:13
 AliTRDpidUtil.cxx:14
 AliTRDpidUtil.cxx:15
 AliTRDpidUtil.cxx:16
 AliTRDpidUtil.cxx:17
 AliTRDpidUtil.cxx:18
 AliTRDpidUtil.cxx:19
 AliTRDpidUtil.cxx:20
 AliTRDpidUtil.cxx:21
 AliTRDpidUtil.cxx:22
 AliTRDpidUtil.cxx:23
 AliTRDpidUtil.cxx:24
 AliTRDpidUtil.cxx:25
 AliTRDpidUtil.cxx:26
 AliTRDpidUtil.cxx:27
 AliTRDpidUtil.cxx:28
 AliTRDpidUtil.cxx:29
 AliTRDpidUtil.cxx:30
 AliTRDpidUtil.cxx:31
 AliTRDpidUtil.cxx:32
 AliTRDpidUtil.cxx:33
 AliTRDpidUtil.cxx:34
 AliTRDpidUtil.cxx:35
 AliTRDpidUtil.cxx:36
 AliTRDpidUtil.cxx:37
 AliTRDpidUtil.cxx:38
 AliTRDpidUtil.cxx:39
 AliTRDpidUtil.cxx:40
 AliTRDpidUtil.cxx:41
 AliTRDpidUtil.cxx:42
 AliTRDpidUtil.cxx:43
 AliTRDpidUtil.cxx:44
 AliTRDpidUtil.cxx:45
 AliTRDpidUtil.cxx:46
 AliTRDpidUtil.cxx:47
 AliTRDpidUtil.cxx:48
 AliTRDpidUtil.cxx:49
 AliTRDpidUtil.cxx:50
 AliTRDpidUtil.cxx:51
 AliTRDpidUtil.cxx:52
 AliTRDpidUtil.cxx:53
 AliTRDpidUtil.cxx:54
 AliTRDpidUtil.cxx:55
 AliTRDpidUtil.cxx:56
 AliTRDpidUtil.cxx:57
 AliTRDpidUtil.cxx:58
 AliTRDpidUtil.cxx:59
 AliTRDpidUtil.cxx:60
 AliTRDpidUtil.cxx:61
 AliTRDpidUtil.cxx:62
 AliTRDpidUtil.cxx:63
 AliTRDpidUtil.cxx:64
 AliTRDpidUtil.cxx:65
 AliTRDpidUtil.cxx:66
 AliTRDpidUtil.cxx:67
 AliTRDpidUtil.cxx:68
 AliTRDpidUtil.cxx:69
 AliTRDpidUtil.cxx:70
 AliTRDpidUtil.cxx:71
 AliTRDpidUtil.cxx:72
 AliTRDpidUtil.cxx:73
 AliTRDpidUtil.cxx:74
 AliTRDpidUtil.cxx:75
 AliTRDpidUtil.cxx:76
 AliTRDpidUtil.cxx:77
 AliTRDpidUtil.cxx:78
 AliTRDpidUtil.cxx:79
 AliTRDpidUtil.cxx:80
 AliTRDpidUtil.cxx:81
 AliTRDpidUtil.cxx:82
 AliTRDpidUtil.cxx:83
 AliTRDpidUtil.cxx:84
 AliTRDpidUtil.cxx:85
 AliTRDpidUtil.cxx:86
 AliTRDpidUtil.cxx:87
 AliTRDpidUtil.cxx:88
 AliTRDpidUtil.cxx:89
 AliTRDpidUtil.cxx:90
 AliTRDpidUtil.cxx:91
 AliTRDpidUtil.cxx:92
 AliTRDpidUtil.cxx:93
 AliTRDpidUtil.cxx:94
 AliTRDpidUtil.cxx:95
 AliTRDpidUtil.cxx:96
 AliTRDpidUtil.cxx:97
 AliTRDpidUtil.cxx:98
 AliTRDpidUtil.cxx:99
 AliTRDpidUtil.cxx:100
 AliTRDpidUtil.cxx:101
 AliTRDpidUtil.cxx:102
 AliTRDpidUtil.cxx:103
 AliTRDpidUtil.cxx:104
 AliTRDpidUtil.cxx:105
 AliTRDpidUtil.cxx:106
 AliTRDpidUtil.cxx:107
 AliTRDpidUtil.cxx:108
 AliTRDpidUtil.cxx:109
 AliTRDpidUtil.cxx:110
 AliTRDpidUtil.cxx:111
 AliTRDpidUtil.cxx:112
 AliTRDpidUtil.cxx:113
 AliTRDpidUtil.cxx:114
 AliTRDpidUtil.cxx:115
 AliTRDpidUtil.cxx:116
 AliTRDpidUtil.cxx:117
 AliTRDpidUtil.cxx:118
 AliTRDpidUtil.cxx:119
 AliTRDpidUtil.cxx:120
 AliTRDpidUtil.cxx:121
 AliTRDpidUtil.cxx:122
 AliTRDpidUtil.cxx:123
 AliTRDpidUtil.cxx:124
 AliTRDpidUtil.cxx:125
 AliTRDpidUtil.cxx:126
 AliTRDpidUtil.cxx:127
 AliTRDpidUtil.cxx:128
 AliTRDpidUtil.cxx:129
 AliTRDpidUtil.cxx:130
 AliTRDpidUtil.cxx:131
 AliTRDpidUtil.cxx:132
 AliTRDpidUtil.cxx:133
 AliTRDpidUtil.cxx:134
 AliTRDpidUtil.cxx:135
 AliTRDpidUtil.cxx:136
 AliTRDpidUtil.cxx:137
 AliTRDpidUtil.cxx:138
 AliTRDpidUtil.cxx:139
 AliTRDpidUtil.cxx:140
 AliTRDpidUtil.cxx:141
 AliTRDpidUtil.cxx:142
 AliTRDpidUtil.cxx:143
 AliTRDpidUtil.cxx:144
 AliTRDpidUtil.cxx:145
 AliTRDpidUtil.cxx:146
 AliTRDpidUtil.cxx:147
 AliTRDpidUtil.cxx:148
 AliTRDpidUtil.cxx:149
 AliTRDpidUtil.cxx:150
 AliTRDpidUtil.cxx:151
 AliTRDpidUtil.cxx:152
 AliTRDpidUtil.cxx:153
 AliTRDpidUtil.cxx:154
 AliTRDpidUtil.cxx:155
 AliTRDpidUtil.cxx:156
 AliTRDpidUtil.cxx:157
 AliTRDpidUtil.cxx:158
 AliTRDpidUtil.cxx:159
 AliTRDpidUtil.cxx:160
 AliTRDpidUtil.cxx:161
 AliTRDpidUtil.cxx:162
 AliTRDpidUtil.cxx:163
 AliTRDpidUtil.cxx:164
 AliTRDpidUtil.cxx:165
 AliTRDpidUtil.cxx:166
 AliTRDpidUtil.cxx:167
 AliTRDpidUtil.cxx:168
 AliTRDpidUtil.cxx:169
 AliTRDpidUtil.cxx:170
 AliTRDpidUtil.cxx:171
 AliTRDpidUtil.cxx:172
 AliTRDpidUtil.cxx:173
 AliTRDpidUtil.cxx:174
 AliTRDpidUtil.cxx:175
 AliTRDpidUtil.cxx:176
 AliTRDpidUtil.cxx:177
 AliTRDpidUtil.cxx:178
 AliTRDpidUtil.cxx:179
 AliTRDpidUtil.cxx:180
 AliTRDpidUtil.cxx:181
 AliTRDpidUtil.cxx:182
 AliTRDpidUtil.cxx:183
 AliTRDpidUtil.cxx:184
 AliTRDpidUtil.cxx:185
 AliTRDpidUtil.cxx:186
 AliTRDpidUtil.cxx:187
 AliTRDpidUtil.cxx:188
 AliTRDpidUtil.cxx:189
 AliTRDpidUtil.cxx:190
 AliTRDpidUtil.cxx:191
 AliTRDpidUtil.cxx:192
 AliTRDpidUtil.cxx:193
 AliTRDpidUtil.cxx:194
 AliTRDpidUtil.cxx:195
 AliTRDpidUtil.cxx:196
 AliTRDpidUtil.cxx:197
 AliTRDpidUtil.cxx:198
 AliTRDpidUtil.cxx:199
 AliTRDpidUtil.cxx:200
 AliTRDpidUtil.cxx:201
 AliTRDpidUtil.cxx:202
 AliTRDpidUtil.cxx:203
 AliTRDpidUtil.cxx:204
 AliTRDpidUtil.cxx:205
 AliTRDpidUtil.cxx:206
 AliTRDpidUtil.cxx:207
 AliTRDpidUtil.cxx:208
 AliTRDpidUtil.cxx:209
 AliTRDpidUtil.cxx:210
 AliTRDpidUtil.cxx:211
 AliTRDpidUtil.cxx:212
 AliTRDpidUtil.cxx:213
 AliTRDpidUtil.cxx:214
 AliTRDpidUtil.cxx:215
 AliTRDpidUtil.cxx:216
 AliTRDpidUtil.cxx:217
 AliTRDpidUtil.cxx:218
 AliTRDpidUtil.cxx:219
 AliTRDpidUtil.cxx:220
 AliTRDpidUtil.cxx:221
 AliTRDpidUtil.cxx:222
 AliTRDpidUtil.cxx:223
 AliTRDpidUtil.cxx:224
 AliTRDpidUtil.cxx:225
 AliTRDpidUtil.cxx:226
 AliTRDpidUtil.cxx:227
 AliTRDpidUtil.cxx:228
 AliTRDpidUtil.cxx:229
 AliTRDpidUtil.cxx:230
 AliTRDpidUtil.cxx:231
 AliTRDpidUtil.cxx:232
 AliTRDpidUtil.cxx:233
 AliTRDpidUtil.cxx:234
 AliTRDpidUtil.cxx:235
 AliTRDpidUtil.cxx:236
 AliTRDpidUtil.cxx:237
 AliTRDpidUtil.cxx:238
 AliTRDpidUtil.cxx:239
 AliTRDpidUtil.cxx:240
 AliTRDpidUtil.cxx:241
 AliTRDpidUtil.cxx:242
 AliTRDpidUtil.cxx:243
 AliTRDpidUtil.cxx:244
 AliTRDpidUtil.cxx:245
 AliTRDpidUtil.cxx:246
 AliTRDpidUtil.cxx:247
 AliTRDpidUtil.cxx:248
 AliTRDpidUtil.cxx:249
 AliTRDpidUtil.cxx:250
 AliTRDpidUtil.cxx:251
 AliTRDpidUtil.cxx:252
 AliTRDpidUtil.cxx:253
 AliTRDpidUtil.cxx:254
 AliTRDpidUtil.cxx:255