LCOV - code coverage report
Current view: top level - STEER/STEERBase - AliPIDResponse.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 143 1434 10.0 %
Date: 2016-06-14 17:26:59 Functions: 8 92 8.7 %

          Line data    Source code
       1             : /**************************************************************************
       2             :  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             :  *                                                                        *
       4             :  * Author: The ALICE Off-line Project.                                    *
       5             :  * Contributors are mentioned in the code where appropriate.              *
       6             :  *                                                                        *
       7             :  * Permission to use, copy, modify and distribute this software and its   *
       8             :  * documentation strictly for non-commercial purposes is hereby granted   *
       9             :  * without fee, provided that the above copyright notice appears in all   *
      10             :  * copies and that both the copyright notice and this permission notice   *
      11             :  * appear in the supporting documentation. The authors make no claims     *
      12             :  * about the suitability of this software for any purpose. It is          *
      13             :  * provided "as is" without express or implied warranty.                  *
      14             :  **************************************************************************/
      15             : 
      16             : /* $Id: AliPIDResponse.cxx 46193 2010-12-21 09:00:14Z wiechula $ */
      17             : 
      18             : //-----------------------------------------------------------------
      19             : //        Base class for handling the pid response               //
      20             : //        functions of all detectors                             //
      21             : //        and give access to the nsigmas                         //
      22             : //                                                               //
      23             : //   Origin: Jens Wiechula, Uni Tuebingen, jens.wiechula@cern.ch //
      24             : //-----------------------------------------------------------------
      25             : 
      26             : #include <TList.h>
      27             : #include <TObjArray.h>
      28             : #include <TPRegexp.h>
      29             : #include <TF1.h>
      30             : #include <TH2D.h>
      31             : #include <TSpline.h>
      32             : #include <TFile.h>
      33             : #include <TArrayI.h>
      34             : #include <TArrayF.h>
      35             : #include <TLinearFitter.h>
      36             : #include <TSystem.h>
      37             : #include <TMD5.h>
      38             : #include "TRandom.h"
      39             : 
      40             : #include <AliVEvent.h>
      41             : #include <AliVTrack.h>
      42             : #include <AliMCEvent.h>
      43             : #include <AliLog.h>
      44             : #include <AliPID.h>
      45             : #include <AliOADBContainer.h>
      46             : #include <AliTRDPIDResponseObject.h>
      47             : #include <AliTRDdEdxParams.h>
      48             : #include <AliTOFPIDParams.h>
      49             : #include <AliHMPIDPIDParams.h>
      50             : 
      51             : #include "AliPIDResponse.h"
      52             : #include "AliDetectorPID.h"
      53             : 
      54             : #include "AliCentrality.h"
      55             : 
      56         176 : ClassImp(AliPIDResponse);
      57             : 
      58             : Float_t AliPIDResponse::fgTOFmismatchProb = 0.0;
      59             : 
      60             : AliPIDResponse::AliPIDResponse(Bool_t isMC/*=kFALSE*/) :
      61          10 : TNamed("PIDResponse","PIDResponse"),
      62          10 : fITSResponse(isMC),
      63          10 : fTPCResponse(),
      64          10 : fTRDResponse(),
      65          10 : fTOFResponse(),
      66          10 : fHMPIDResponse(),
      67          10 : fEMCALResponse(),
      68          10 : fRange(5.),
      69          10 : fITSPIDmethod(kITSTruncMean),
      70          10 : fTuneMConData(kFALSE),
      71          10 : fTuneMConDataMask(kDetTOF|kDetTPC),
      72          10 : fIsMC(isMC),
      73          10 : fCachePID(kFALSE),
      74          10 : fOADBPath(),
      75          10 : fCustomTPCpidResponse(),
      76          10 : fCustomTPCpidResponseOADBFile(),
      77          10 : fCustomTPCetaMaps(),
      78          10 : fBeamType("PP"),
      79          10 : fLHCperiod(),
      80          10 : fMCperiodTPC(),
      81          10 : fMCperiodUser(),
      82          10 : fCurrentFile(),
      83          10 : fCurrentAliRootRev(-1),
      84          10 : fRecoPass(0),
      85          10 : fRecoPassUser(-1),
      86          10 : fRun(-1),
      87          10 : fOldRun(-1),
      88          10 : fResT0A(75.),
      89          10 : fResT0C(65.),
      90          10 : fResT0AC(55.),
      91          10 : fTPCPIDResponseArray(NULL),
      92          10 : fArrPidResponseMaster(NULL),
      93          10 : fResolutionCorrection(NULL),
      94          10 : fOADBvoltageMaps(NULL),
      95          10 : fUseTPCEtaCorrection(kFALSE),
      96          10 : fUseTPCMultiplicityCorrection(kFALSE),
      97          10 : fUseTPCNewResponse(kTRUE),
      98          10 : fTRDPIDResponseObject(NULL),
      99          10 : fTRDdEdxParams(NULL),
     100          10 : fUseTRDEtaCorrection(kFALSE),
     101          10 : fTOFtail(0.9),
     102          10 : fTOFPIDParams(NULL),
     103          10 : fHMPIDPIDParams(NULL),
     104          10 : fEMCALPIDParams(NULL),
     105          10 : fCurrentEvent(NULL),
     106          10 : fCurrentMCEvent(NULL),
     107          10 : fCurrCentrality(0.0),
     108          10 : fBeamTypeNum(kPP),
     109          10 : fNoTOFmism(kFALSE)
     110          20 : {
     111             :   //
     112             :   // default ctor
     113             :   //
     114          10 :   AliLog::SetClassDebugLevel("AliPIDResponse",0);
     115          10 :   AliLog::SetClassDebugLevel("AliESDpid",0);
     116          10 :   AliLog::SetClassDebugLevel("AliAODpidUtil",0);
     117             : 
     118          10 : }
     119             : 
     120             : //______________________________________________________________________________
     121             : AliPIDResponse::~AliPIDResponse()
     122          20 : {
     123             :   //
     124             :   // dtor
     125             :   //
     126          10 :   delete fTPCPIDResponseArray;
     127          10 :   delete fArrPidResponseMaster;
     128          10 :   delete fTRDPIDResponseObject;
     129          10 :   delete fTRDdEdxParams;
     130          10 :   delete fTOFPIDParams;
     131          10 : }
     132             : 
     133             : //______________________________________________________________________________
     134             : AliPIDResponse::AliPIDResponse(const AliPIDResponse &other) :
     135           0 : TNamed(other),
     136           0 : fITSResponse(other.fITSResponse),
     137           0 : fTPCResponse(other.fTPCResponse),
     138           0 : fTRDResponse(other.fTRDResponse),
     139           0 : fTOFResponse(other.fTOFResponse),
     140           0 : fHMPIDResponse(other.fHMPIDResponse),
     141           0 : fEMCALResponse(other.fEMCALResponse),
     142           0 : fRange(other.fRange),
     143           0 : fITSPIDmethod(other.fITSPIDmethod),
     144           0 : fTuneMConData(other.fTuneMConData),
     145           0 : fTuneMConDataMask(other.fTuneMConDataMask),
     146           0 : fIsMC(other.fIsMC),
     147           0 : fCachePID(other.fCachePID),
     148           0 : fOADBPath(other.fOADBPath),
     149           0 : fCustomTPCpidResponse(other.fCustomTPCpidResponse),
     150           0 : fCustomTPCpidResponseOADBFile(other.fCustomTPCpidResponseOADBFile),
     151           0 : fCustomTPCetaMaps(other.fCustomTPCetaMaps),
     152           0 : fBeamType("PP"),
     153           0 : fLHCperiod(),
     154           0 : fMCperiodTPC(),
     155           0 : fMCperiodUser(other.fMCperiodUser),
     156           0 : fCurrentFile(),
     157           0 : fCurrentAliRootRev(other.fCurrentAliRootRev),
     158           0 : fRecoPass(0),
     159           0 : fRecoPassUser(other.fRecoPassUser),
     160           0 : fRun(-1),
     161           0 : fOldRun(-1),
     162           0 : fResT0A(75.),
     163           0 : fResT0C(65.),
     164           0 : fResT0AC(55.),
     165           0 : fTPCPIDResponseArray(NULL),
     166           0 : fArrPidResponseMaster(NULL),
     167           0 : fResolutionCorrection(NULL),
     168           0 : fOADBvoltageMaps(NULL),
     169           0 : fUseTPCEtaCorrection(other.fUseTPCEtaCorrection),
     170           0 : fUseTPCMultiplicityCorrection(other.fUseTPCMultiplicityCorrection),
     171           0 : fUseTPCNewResponse(other.fUseTPCNewResponse),
     172           0 : fTRDPIDResponseObject(NULL),
     173           0 : fTRDdEdxParams(NULL),
     174           0 : fUseTRDEtaCorrection(other.fUseTRDEtaCorrection),
     175           0 : fTOFtail(0.9),
     176           0 : fTOFPIDParams(NULL),
     177           0 : fHMPIDPIDParams(NULL),
     178           0 : fEMCALPIDParams(NULL),
     179           0 : fCurrentEvent(NULL),
     180           0 : fCurrentMCEvent(NULL),
     181           0 : fCurrCentrality(0.0),
     182           0 : fBeamTypeNum(kPP),
     183           0 : fNoTOFmism(other.fNoTOFmism)
     184           0 : {
     185             :   //
     186             :   // copy ctor
     187             :   //
     188           0 : }
     189             : 
     190             : //______________________________________________________________________________
     191             : AliPIDResponse& AliPIDResponse::operator=(const AliPIDResponse &other)
     192             : {
     193             :   //
     194             :   // copy ctor
     195             :   //
     196           0 :   if(this!=&other) {
     197           0 :     delete fArrPidResponseMaster;
     198           0 :     TNamed::operator=(other);
     199           0 :     fITSResponse=other.fITSResponse;
     200           0 :     fTPCResponse=other.fTPCResponse;
     201           0 :     fTRDResponse=other.fTRDResponse;
     202           0 :     fTOFResponse=other.fTOFResponse;
     203           0 :     fHMPIDResponse=other.fHMPIDResponse;
     204           0 :     fEMCALResponse=other.fEMCALResponse;
     205           0 :     fRange=other.fRange;
     206           0 :     fITSPIDmethod=other.fITSPIDmethod;
     207           0 :     fOADBPath=other.fOADBPath;
     208           0 :     fCustomTPCpidResponse=other.fCustomTPCpidResponse;
     209           0 :     fCustomTPCpidResponseOADBFile=other.fCustomTPCpidResponseOADBFile;
     210           0 :     fCustomTPCetaMaps=other.fCustomTPCetaMaps;
     211           0 :     fTuneMConData=other.fTuneMConData;
     212           0 :     fTuneMConDataMask=other.fTuneMConDataMask;
     213           0 :     fIsMC=other.fIsMC;
     214           0 :     fCachePID=other.fCachePID;
     215           0 :     fBeamType="PP";
     216           0 :     fBeamTypeNum=kPP;
     217           0 :     fLHCperiod="";
     218           0 :     fMCperiodTPC="";
     219           0 :     fMCperiodUser=other.fMCperiodUser;
     220           0 :     fCurrentFile="";
     221           0 :     fCurrentAliRootRev=other.fCurrentAliRootRev;
     222           0 :     fRecoPass=0;
     223           0 :     fRecoPassUser=other.fRecoPassUser;
     224           0 :     fRun=-1;
     225           0 :     fOldRun=-1;
     226           0 :     fResT0A=75.;
     227           0 :     fResT0C=65.;
     228           0 :     fResT0AC=55.;
     229           0 :     fTPCPIDResponseArray=NULL;
     230           0 :     fArrPidResponseMaster=NULL;
     231           0 :     fResolutionCorrection=NULL;
     232           0 :     fOADBvoltageMaps=NULL;
     233           0 :     fUseTPCEtaCorrection=other.fUseTPCEtaCorrection;
     234           0 :     fUseTPCMultiplicityCorrection=other.fUseTPCMultiplicityCorrection;
     235           0 :     fUseTPCNewResponse=other.fUseTPCNewResponse;
     236           0 :     fTRDPIDResponseObject=NULL;
     237           0 :     fTRDdEdxParams=NULL;
     238           0 :     fUseTRDEtaCorrection=other.fUseTRDEtaCorrection;
     239           0 :     fEMCALPIDParams=NULL;
     240           0 :     fTOFtail=0.9;
     241           0 :     fTOFPIDParams=NULL;
     242           0 :     fHMPIDPIDParams=NULL;
     243           0 :     fCurrentEvent=other.fCurrentEvent;
     244           0 :     fCurrentMCEvent=other.fCurrentMCEvent;
     245           0 :     fNoTOFmism = other.fNoTOFmism;
     246             : 
     247           0 :   }
     248           0 :   return *this;
     249             : }
     250             : 
     251             : //______________________________________________________________________________
     252             : Float_t AliPIDResponse::NumberOfSigmas(EDetector detector, const AliVParticle *vtrack, AliPID::EParticleType type) const
     253             : {
     254             :   //
     255             :   // NumberOfSigmas for 'detCode'
     256             :   //
     257             : 
     258           0 :   const AliVTrack *track=static_cast<const AliVTrack*>(vtrack);
     259             :   // look for cached value first
     260           0 :   const AliDetectorPID *detPID=track->GetDetectorPID();
     261             : 
     262           0 :   if ( detPID && detPID->HasNumberOfSigmas(detector)){
     263           0 :     return detPID->GetNumberOfSigmas(detector, type);
     264           0 :   } else if (fCachePID) {
     265           0 :     FillTrackDetectorPID(track, detector);
     266           0 :     detPID=track->GetDetectorPID();
     267           0 :     return detPID->GetNumberOfSigmas(detector, type);
     268             :   }
     269             : 
     270           0 :   return GetNumberOfSigmas(detector, track, type);
     271           0 : }
     272             : 
     273             : //______________________________________________________________________________
     274             : AliPIDResponse::EDetPidStatus AliPIDResponse::NumberOfSigmas(EDetector detCode, const AliVParticle *track,
     275             :                                                              AliPID::EParticleType type, Double_t &val) const
     276             : {
     277             :   //
     278             :   // NumberOfSigmas with detector status as return value
     279             :   //
     280             : 
     281           0 :   val=NumberOfSigmas(detCode, track, type);
     282           0 :   return CheckPIDStatus(detCode, (AliVTrack*)track);
     283             : }
     284             : 
     285             : //______________________________________________________________________________
     286             : // public buffered versions of the PID calculation
     287             : //
     288             : 
     289             : //______________________________________________________________________________
     290             : Float_t AliPIDResponse::NumberOfSigmasITS(const AliVParticle *vtrack, AliPID::EParticleType type) const
     291             : {
     292             :   //
     293             :   // Calculate the number of sigmas in the ITS
     294             :   //
     295             : 
     296           0 :   return NumberOfSigmas(kITS, vtrack, type);
     297             : }
     298             : 
     299             : //______________________________________________________________________________
     300             : Float_t AliPIDResponse::NumberOfSigmasTPC(const AliVParticle *vtrack, AliPID::EParticleType type) const
     301             : {
     302             :   //
     303             :   // Calculate the number of sigmas in the TPC
     304             :   //
     305             : 
     306           0 :   return NumberOfSigmas(kTPC, vtrack, type);
     307             : }
     308             : 
     309             : //______________________________________________________________________________
     310             : Float_t AliPIDResponse::NumberOfSigmasTPC( const AliVParticle *vtrack,
     311             :                                            AliPID::EParticleType type,
     312             :                                            AliTPCPIDResponse::ETPCdEdxSource dedxSource) const
     313             : {
     314             :   //get number of sigmas according the selected TPC gain configuration scenario
     315           0 :   const AliVTrack *track=static_cast<const AliVTrack*>(vtrack);
     316             : 
     317           0 :   Float_t nSigma=fTPCResponse.GetNumberOfSigmas(track, type, dedxSource, fUseTPCEtaCorrection, fUseTPCMultiplicityCorrection);
     318             : 
     319           0 :   return nSigma;
     320             : }
     321             : 
     322             : //______________________________________________________________________________
     323             : Float_t AliPIDResponse::NumberOfSigmasTRD(const AliVParticle *vtrack, AliPID::EParticleType type) const
     324             : {
     325             :   //
     326             :   // Calculate the number of sigmas in the TRD
     327             :   //
     328           0 :   return NumberOfSigmas(kTRD, vtrack, type);
     329             : }
     330             : 
     331             : //______________________________________________________________________________
     332             : Float_t AliPIDResponse::NumberOfSigmasTOF(const AliVParticle *vtrack, AliPID::EParticleType type) const
     333             : {
     334             :   //
     335             :   // Calculate the number of sigmas in the TOF
     336             :   //
     337             : 
     338           0 :   return NumberOfSigmas(kTOF, vtrack, type);
     339             : }
     340             : 
     341             : //______________________________________________________________________________
     342             : Float_t AliPIDResponse::NumberOfSigmasHMPID(const AliVParticle *vtrack, AliPID::EParticleType type) const
     343             : {
     344             :   //
     345             :   // Calculate the number of sigmas in the EMCAL
     346             :   //
     347             : 
     348           0 :   return NumberOfSigmas(kHMPID, vtrack, type);
     349             : }
     350             : 
     351             : //______________________________________________________________________________
     352             : Float_t AliPIDResponse::NumberOfSigmasEMCAL(const AliVParticle *vtrack, AliPID::EParticleType type) const
     353             : {
     354             :   //
     355             :   // Calculate the number of sigmas in the EMCAL
     356             :   //
     357             : 
     358           0 :   return NumberOfSigmas(kEMCAL, vtrack, type);
     359             : }
     360             : 
     361             : //______________________________________________________________________________
     362             : Float_t  AliPIDResponse::NumberOfSigmasEMCAL(const AliVParticle *vtrack, AliPID::EParticleType type, Double_t &eop, Double_t showershape[4])  const
     363             : {
     364             :   //
     365             :   // emcal nsigma with eop and showershape
     366             :   //
     367           0 :   AliVTrack *track=(AliVTrack*)vtrack;
     368             : 
     369             :   AliVCluster *matchedClus = NULL;
     370             : 
     371             :   Double_t mom     = -1.;
     372             :   Double_t pt      = -1.;
     373             :   Double_t EovP    = -1.;
     374             :   Double_t fClsE   = -1.;
     375             : 
     376             :   // initialize eop and shower shape parameters
     377           0 :   eop = -1.;
     378           0 :   for(Int_t i = 0; i < 4; i++){
     379           0 :     showershape[i] = -1.;
     380             :   }
     381             : 
     382             :   Int_t nMatchClus = -1;
     383             :   Int_t charge     = 0;
     384             : 
     385             :   // Track matching
     386           0 :   nMatchClus = track->GetEMCALcluster();
     387           0 :   if(nMatchClus > -1){
     388             : 
     389           0 :     mom    = track->P();
     390           0 :     pt     = track->Pt();
     391           0 :     charge = track->Charge();
     392             : 
     393           0 :     matchedClus = (AliVCluster*)fCurrentEvent->GetCaloCluster(nMatchClus);
     394             : 
     395           0 :     if(matchedClus){
     396             : 
     397             :       // matched cluster is EMCAL
     398           0 :       if(matchedClus->IsEMCAL()){
     399             : 
     400           0 :         fClsE       = matchedClus->E();
     401           0 :         EovP        = fClsE/mom;
     402             : 
     403             :         // fill used EMCAL variables here
     404           0 :         eop            = EovP; // E/p
     405           0 :         showershape[0] = matchedClus->GetNCells(); // number of cells in cluster
     406           0 :         showershape[1] = matchedClus->GetM02(); // long axis
     407           0 :         showershape[2] = matchedClus->GetM20(); // short axis
     408           0 :         showershape[3] = matchedClus->GetDispersion(); // dispersion
     409             : 
     410             :         // look for cached value first
     411           0 :         const AliDetectorPID *detPID=track->GetDetectorPID();
     412             :         const EDetector detector=kEMCAL;
     413             : 
     414           0 :         if ( detPID && detPID->HasNumberOfSigmas(detector)){
     415           0 :           return detPID->GetNumberOfSigmas(detector, type);
     416           0 :         } else if (fCachePID) {
     417           0 :           FillTrackDetectorPID(track, detector);
     418           0 :           detPID=track->GetDetectorPID();
     419           0 :           return detPID->GetNumberOfSigmas(detector, type);
     420             :         }
     421             : 
     422             :         // NSigma value really meaningful only for electrons!
     423           0 :         return fEMCALResponse.GetNumberOfSigmas(pt,EovP,type,charge);
     424             :       }
     425             :     }
     426             :   }
     427           0 :   return -999;
     428           0 : }
     429             : 
     430             : //______________________________________________________________________________
     431             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetSignalDelta(EDetector detector, const AliVParticle *track, AliPID::EParticleType type, Double_t &val, Bool_t ratio/*=kFALSE*/) const
     432             : {
     433             :   //
     434             :   //
     435             :   //
     436           0 :   val=-9999.;
     437           0 :   switch (detector){
     438           0 :     case kITS:   return GetSignalDeltaITS(track,type,val,ratio); break;
     439           0 :     case kTPC:   return GetSignalDeltaTPC(track,type,val,ratio); break;
     440           0 :     case kTRD:   return GetSignalDeltaTRD(track,type,val,ratio); break;
     441           0 :     case kTOF:   return GetSignalDeltaTOF(track,type,val,ratio); break;
     442           0 :     case kHMPID: return GetSignalDeltaHMPID(track,type,val,ratio); break;
     443           0 :     default: return kDetNoSignal;
     444             :   }
     445             :   return kDetNoSignal;
     446           0 : }
     447             : 
     448             : //______________________________________________________________________________
     449             : Double_t AliPIDResponse::GetSignalDelta(EDetector detCode, const AliVParticle *track, AliPID::EParticleType type, Bool_t ratio/*=kFALSE*/) const
     450             : {
     451             :   //
     452             :   //
     453             :   //
     454           0 :   Double_t val=-9999.;
     455           0 :   EDetPidStatus stat=GetSignalDelta(detCode, track, type, val, ratio);
     456           0 :   if ( stat==kDetNoSignal ) val=-9999.;
     457           0 :   return val;
     458           0 : }
     459             : 
     460             : //______________________________________________________________________________
     461             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputePIDProbability  (EDetCode  detCode, const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     462             : {
     463             :   // Compute PID response of 'detCode'
     464             : 
     465             :   // find detector code from detector bit mask
     466             :   Int_t detector=-1;
     467           0 :   for (Int_t idet=0; idet<kNdetectors; ++idet) if ( (detCode&(1<<idet)) ) { detector=idet; break; }
     468           0 :   if (detector==-1) return kDetNoSignal;
     469             : 
     470           0 :   return ComputePIDProbability((EDetector)detector, track, nSpecies, p);
     471           0 : }
     472             : 
     473             : //______________________________________________________________________________
     474             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputePIDProbability  (EDetector detector,  const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     475             : {
     476             :   //
     477             :   // Compute PID response of 'detector'
     478             :   //
     479             : 
     480         576 :   const AliDetectorPID *detPID=track->GetDetectorPID();
     481             : 
     482         288 :   if ( detPID && detPID->HasRawProbability(detector)){
     483           0 :     return detPID->GetRawProbability(detector, p, nSpecies);
     484         288 :   } else if (fCachePID) {
     485           0 :     FillTrackDetectorPID(track, detector);
     486           0 :     detPID=track->GetDetectorPID();
     487           0 :     return detPID->GetRawProbability(detector, p, nSpecies);
     488             :   }
     489             : 
     490             :   //if no caching return values calculated from scratch
     491         288 :   return GetComputePIDProbability(detector, track, nSpecies, p);
     492         288 : }
     493             : 
     494             : //______________________________________________________________________________
     495             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeITSProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     496             : {
     497             :   // Compute PID response for the ITS
     498           0 :   return ComputePIDProbability(kITS, track, nSpecies, p);
     499             : }
     500             : 
     501             : //______________________________________________________________________________
     502             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeTPCProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     503             : {
     504             :   // Compute PID response for the TPC
     505           0 :   return ComputePIDProbability(kTPC, track, nSpecies, p);
     506             : }
     507             : 
     508             : //______________________________________________________________________________
     509             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeTOFProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     510             : {
     511             :   // Compute PID response for the
     512           0 :   return ComputePIDProbability(kTOF, track, nSpecies, p);
     513             : }
     514             : 
     515             : //______________________________________________________________________________
     516             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeTRDProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     517             : {
     518             :   // Compute PID response for the
     519           0 :   return ComputePIDProbability(kTRD, track, nSpecies, p);
     520             : }
     521             : 
     522             : //______________________________________________________________________________
     523             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeEMCALProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     524             : {
     525             :   // Compute PID response for the EMCAL
     526           0 :   return ComputePIDProbability(kEMCAL, track, nSpecies, p);
     527             : }
     528             : //______________________________________________________________________________
     529             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputePHOSProbability (const AliVTrack */*track*/, Int_t nSpecies, Double_t p[]) const
     530             : {
     531             :   // Compute PID response for the PHOS
     532             : 
     533             :   // set flat distribution (no decision)
     534           0 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
     535           0 :   return kDetNoSignal;
     536             : }
     537             : 
     538             : //______________________________________________________________________________
     539             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeHMPIDProbability(const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
     540             : {
     541             :   // Compute PID response for the HMPID
     542           0 :   return ComputePIDProbability(kHMPID, track, nSpecies, p);
     543             : }
     544             : 
     545             : //______________________________________________________________________________
     546             : AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeTRDProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[],AliTRDPIDResponse::ETRDPIDMethod PIDmethod) const
     547             : {
     548             :   // Compute PID response for the
     549           0 :   return GetComputeTRDProbability(track, nSpecies, p, PIDmethod);
     550             : }
     551             : 
     552             : //______________________________________________________________________________
     553             : AliPIDResponse::EDetPidStatus AliPIDResponse::CheckPIDStatus(EDetector detector, const AliVTrack *track) const
     554             : {
     555             :   // calculate detector pid status
     556             : 
     557             :   const Int_t iDetCode=(Int_t)detector;
     558           0 :   if (iDetCode<0||iDetCode>=kNdetectors) return kDetNoSignal;
     559           0 :   const AliDetectorPID *detPID=track->GetDetectorPID();
     560             : 
     561           0 :   if ( detPID ){
     562           0 :     return detPID->GetPIDStatus(detector);
     563           0 :   } else if (fCachePID) {
     564           0 :     FillTrackDetectorPID(track, detector);
     565           0 :     detPID=track->GetDetectorPID();
     566           0 :     return detPID->GetPIDStatus(detector);
     567             :   }
     568             : 
     569             :   // if not buffered and no buffering is requested
     570           0 :   return GetPIDStatus(detector, track);
     571           0 : }
     572             : 
     573             : //______________________________________________________________________________
     574             : void AliPIDResponse::InitialiseEvent(AliVEvent *event, Int_t pass, Int_t run)
     575             : {
     576             :   //
     577             :   // Apply settings for the current event
     578             :   //
     579           0 :   fRecoPass=pass;
     580             : 
     581             : 
     582           0 :   fCurrentEvent=NULL;
     583           0 :   if (!event) return;
     584           0 :   fCurrentEvent=event;
     585           0 :   if (run>0) fRun=run;
     586           0 :   else fRun=event->GetRunNumber();
     587             : 
     588           0 :   if (fRun!=fOldRun){
     589           0 :     ExecNewRun();
     590           0 :     fOldRun=fRun;
     591           0 :   }
     592             : 
     593             :   //TPC resolution parametrisation PbPb
     594           0 :   if ( fResolutionCorrection ){
     595           0 :     Double_t corrSigma=fResolutionCorrection->Eval(GetTPCMultiplicityBin(event));
     596           0 :     fTPCResponse.SetSigma(3.79301e-03*corrSigma, 2.21280e+04);
     597           0 :   }
     598             : 
     599             :   // Set up TPC multiplicity for PbPb
     600           0 :   if (fUseTPCMultiplicityCorrection) {
     601           0 :     Int_t numESDtracks = event->GetNumberOfESDTracks();
     602           0 :     if (numESDtracks < 0) {
     603           0 :       AliError("Cannot obtain event multiplicity (number of ESD tracks < 0). If you are using AODs, this might be a too old production. Please disable the multiplicity correction to get a reliable PID result!");
     604             :       numESDtracks = 0;
     605           0 :     }
     606           0 :     fTPCResponse.SetCurrentEventMultiplicity(numESDtracks);
     607           0 :   }
     608             :   else
     609           0 :     fTPCResponse.SetCurrentEventMultiplicity(0);
     610             : 
     611             :   //TOF resolution
     612           0 :   SetTOFResponse(event, (AliPIDResponse::EStartTimeType_t)fTOFPIDParams->GetStartTimeMethod());
     613             : 
     614             : 
     615             :   // Get and set centrality
     616           0 :   AliCentrality *centrality = event->GetCentrality();
     617           0 :   if(centrality){
     618           0 :     fCurrCentrality = centrality->GetCentralityPercentile("V0M");
     619           0 :   }
     620             :   else{
     621           0 :     fCurrCentrality = -1;
     622             :   }
     623             : 
     624             :   // Set centrality percentile for EMCAL
     625           0 :   fEMCALResponse.SetCentrality(fCurrCentrality);
     626             : 
     627             :   // switch off some TOF channel according to OADB to match data TOF matching eff
     628           0 :   if (fTuneMConData && ((fTuneMConDataMask & kDetTOF) == kDetTOF) && fTOFPIDParams->GetTOFmatchingLossMC() > 0.01){
     629           0 :     Int_t ntrk = event->GetNumberOfTracks();
     630           0 :     for(Int_t i=0;i < ntrk;i++){
     631           0 :       AliVParticle *trk = event->GetTrack(i);
     632           0 :       Int_t channel = GetTOFResponse().GetTOFchannel(trk);
     633           0 :       Int_t swoffEachOfThem = Int_t(100./fTOFPIDParams->GetTOFmatchingLossMC() + 0.5);
     634           0 :       if(!(channel%swoffEachOfThem)) ((AliVTrack *) trk)->ResetStatus(AliVTrack::kTOFout);
     635             :     }
     636           0 :   }
     637             : 
     638           0 : }
     639             : 
     640             : //______________________________________________________________________________
     641             : void AliPIDResponse::ExecNewRun()
     642             : {
     643             :   //
     644             :   // Things to Execute upon a new run
     645             :   //
     646           0 :   SetRecoInfo();
     647             : 
     648             :   // ===| ITS part |============================================================
     649           0 :   SetITSParametrisation();
     650             : 
     651             :   // ===| TPC part |============================================================
     652             :   // new treatment for loading the TPC PID response if requested
     653             :   // for the moment fall back to old method if no PID response array is found
     654             :   // by the new method for backward compatibility
     655             :   Bool_t doOldTPCPID=kTRUE;
     656           0 :   if (fUseTPCNewResponse) {
     657           0 :     doOldTPCPID = !InitializeTPCResponse();
     658           0 :     if (doOldTPCPID) {
     659           0 :       AliWarning("No TPC response parametrisations found using the new method. Falling back to the old method.");
     660           0 :     }
     661             :   }
     662             : 
     663           0 :   if (doOldTPCPID) {
     664           0 :     SetTPCPidResponseMaster();
     665           0 :     SetTPCParametrisation();
     666           0 :   }
     667           0 :   SetTPCEtaMaps();
     668             : 
     669             :   // ===| TRD part |============================================================
     670           0 :   SetTRDPidResponseMaster();
     671             :   //has to precede InitializeTRDResponse(), otherwise the read-out fTRDdEdxParams is not pased in TRDResponse!
     672           0 :   SetTRDdEdxParams();
     673           0 :   SetTRDEtaMaps();
     674           0 :   InitializeTRDResponse();
     675             : 
     676             :   // ===| TOF part |============================================================
     677           0 :   SetTOFPidResponseMaster();
     678           0 :   InitializeTOFResponse();
     679             : 
     680             :   // ===| EMCAL part |==========================================================
     681           0 :   SetEMCALPidResponseMaster();
     682           0 :   InitializeEMCALResponse();
     683             : 
     684             :   // ===| HMPID part |==========================================================
     685           0 :   SetHMPIDPidResponseMaster();
     686           0 :   InitializeHMPIDResponse();
     687             : 
     688           0 :   if (fCurrentEvent) fTPCResponse.SetMagField(fCurrentEvent->GetMagneticField());
     689           0 :   if (fCurrentEvent) fTRDResponse.SetMagField(fCurrentEvent->GetMagneticField());
     690           0 : }
     691             : 
     692             : //______________________________________________________________________________
     693             : Double_t AliPIDResponse::GetTPCMultiplicityBin(const AliVEvent * const event)
     694             : {
     695             :   //
     696             :   // Get TPC multiplicity in bins of 150
     697             :   //
     698             : 
     699           0 :   const AliVVertex* vertexTPC = event->GetPrimaryVertex();
     700             :   Double_t tpcMulti=0.;
     701           0 :   if(vertexTPC){
     702           0 :     Double_t vertexContribTPC=vertexTPC->GetNContributors();
     703           0 :     tpcMulti=vertexContribTPC/150.;
     704           0 :     if (tpcMulti>20.) tpcMulti=20.;
     705           0 :   }
     706             : 
     707           0 :   return tpcMulti;
     708             : }
     709             : 
     710             : //______________________________________________________________________________
     711             : void AliPIDResponse::SetRecoInfo()
     712             : {
     713             :   //
     714             :   // Set reconstruction information
     715             :   //
     716             : 
     717             :   //reset information
     718           0 :   fLHCperiod="";
     719           0 :   fMCperiodTPC="";
     720             : 
     721           0 :   fBeamType="";
     722             : 
     723           0 :   fBeamType="PP";
     724           0 :   fBeamTypeNum=kPP;
     725             : 
     726           0 :   Bool_t hasProdInfo=(fCurrentFile.BeginsWith("LHC"));
     727             : 
     728           0 :   TPRegexp reg(".*(LHC1[1-3][a-z]+[0-9]+[a-z_]*)[/_].*");
     729           0 :   if (hasProdInfo) reg=TPRegexp("LHC1[1-2][a-z]+[0-9]+[a-z_]*");
     730           0 :   TPRegexp reg12a17("LHC1[2-4][a-z]");
     731             : 
     732             :   //find the period by run number (UGLY, but not stored in ESD and AOD... )
     733           0 :   if (fRun>=114737&&fRun<=117223)      { fLHCperiod="LHC10B"; fMCperiodTPC="LHC10D1";  }
     734           0 :   else if (fRun>=118503&&fRun<=121040) { fLHCperiod="LHC10C"; fMCperiodTPC="LHC10D1";  }
     735           0 :   else if (fRun>=122195&&fRun<=126437) { fLHCperiod="LHC10D"; fMCperiodTPC="LHC10F6A"; }
     736           0 :   else if (fRun>=127710&&fRun<=130850) { fLHCperiod="LHC10E"; fMCperiodTPC="LHC10F6A"; }
     737           0 :   else if (fRun>=133004&&fRun<=135029) { fLHCperiod="LHC10F"; fMCperiodTPC="LHC10F6A"; }
     738           0 :   else if (fRun>=135654&&fRun<=136377) { fLHCperiod="LHC10G"; fMCperiodTPC="LHC10F6A"; }
     739           0 :   else if (fRun>=136851&&fRun<=139846) {
     740           0 :     fLHCperiod="LHC10H";
     741           0 :     fMCperiodTPC="LHC10H8";
     742           0 :     if (reg.MatchB(fCurrentFile)) fMCperiodTPC="LHC11A10";
     743             :     // exception for 13d2 and later
     744           0 :     if (fCurrentAliRootRev >= 62714) fMCperiodTPC="LHC13D2";
     745           0 :     fBeamType="PBPB";
     746           0 :     fBeamTypeNum=kPBPB;
     747           0 :   }
     748           0 :   else if (fRun>=139847&&fRun<=146974) { fLHCperiod="LHC11A"; fMCperiodTPC="LHC10F6A"; }
     749             :   //TODO: periods 11B (146975-150721), 11C (150722-155837) are not yet treated assume 11d for the moment
     750           0 :   else if (fRun>=146975&&fRun<=155837) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
     751           0 :   else if (fRun>=155838&&fRun<=159649) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
     752             :   // also for 11e (159650-162750),f(162751-165771) use 11d
     753           0 :   else if (fRun>=159650&&fRun<=162750) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
     754           0 :   else if (fRun>=162751&&fRun<=165771) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
     755             : 
     756           0 :   else if (fRun>=165772 && fRun<=170718) {
     757           0 :     fLHCperiod="LHC11H";
     758           0 :     fMCperiodTPC="LHC11A10";
     759           0 :     fBeamType="PBPB";
     760           0 :     fBeamTypeNum=kPBPB;
     761           0 :     if (reg12a17.MatchB(fCurrentFile)) fMCperiodTPC="LHC12A17";
     762             :   }
     763           0 :   if (fRun>=170719 && fRun<=177311) {
     764           0 :     fLHCperiod="LHC12A";
     765           0 :     fBeamType="PP";
     766           0 :     fBeamTypeNum=kPP;
     767           0 :     fMCperiodTPC="LHC10F6A";
     768           0 :     if (fCurrentAliRootRev >= 62714)
     769           0 :       fMCperiodTPC="LHC14E2";
     770             :   }
     771             :   // for the moment use LHC12b parameters up to LHC12d
     772           0 :   if (fRun>=177312 /*&& fRun<=179356*/) {
     773           0 :     fLHCperiod="LHC12B";
     774           0 :     fBeamType="PP";
     775           0 :     fBeamTypeNum=kPP;
     776           0 :     fMCperiodTPC="LHC10F6A";
     777           0 :     if (fCurrentAliRootRev >= 62714)
     778           0 :       fMCperiodTPC="LHC14E2";
     779             :   }
     780             : //   if (fRun>=179357 && fRun<=183173) { fLHCperiod="LHC12C"; fBeamType="PP"; fBeamTypeNum=kPP;/*fMCperiodTPC="";*/ }
     781             : //   if (fRun>=183174 && fRun<=186345) { fLHCperiod="LHC12D"; fBeamType="PP"; fBeamTypeNum=kPP;/*fMCperiodTPC="";*/ }
     782             : //   if (fRun>=186346 && fRun<=186635) { fLHCperiod="LHC12E"; fBeamType="PP"; fBeamTypeNum=kPP;/*fMCperiodTPC="";*/ }
     783             : 
     784             : //   if (fRun>=186636 && fRun<=188166) { fLHCperiod="LHC12F"; fBeamType="PP"; fBeamTypeNum=kPP;/*fMCperiodTPC="";*/ }
     785             : //   if (fRun >= 188167 && fRun <= 188355 ) { fLHCperiod="LHC12G"; fBeamType="PP"; fBeamTypeNum=kPP;/*fMCperiodTPC="";*/ }
     786             : //   if (fRun >= 188356 && fRun <= 188503 ) { fLHCperiod="LHC12G"; fBeamType="PPB"; fBeamTypeNum=kPPB;/*fMCperiodTPC="";*/ }
     787             : // for the moment use 12g parametrisation for all full gain runs (LHC12e+)
     788             : 
     789             :   // Dedicated splines for periods 12g and 12i(j) (and use more appropriate MC)
     790           0 :   if (fRun >= 188720 && fRun <= 192738) {
     791           0 :     fLHCperiod="LHC12H";
     792           0 :     fBeamType="PP";
     793           0 :     fBeamTypeNum=kPP;
     794           0 :     fMCperiodTPC="LHC10F6A";
     795           0 :     if (fCurrentAliRootRev >= 62714)
     796           0 :       fMCperiodTPC="LHC13B2_FIXn1";
     797             :   }
     798           0 :   if (fRun >= 192739 && fRun <= 194479) {
     799           0 :     fLHCperiod="LHC12I";
     800           0 :     fBeamType="PP";
     801           0 :     fBeamTypeNum=kPP;
     802           0 :     fMCperiodTPC="LHC10F6A";
     803           0 :     if (fCurrentAliRootRev >= 62714)
     804           0 :       fMCperiodTPC="LHC13B2_FIXn1";
     805             :   }
     806             : 
     807             :   // Use for pp and pPb 12E-G pass 1 the PPB runs
     808           0 :   if (fRecoPass==1 && fRun >= 186346 && fRun < 188719) { fLHCperiod="LHC12G"; fBeamType="PPB";fBeamTypeNum=kPPB; fMCperiodTPC="LHC12G"; }
     809             : 
     810             :   // settings for pass2 of 2012 data
     811           0 :   if (fRecoPass>=2 && fRun>=170719 && fRun<=194479) {
     812           0 :     fBeamType    = "PP";
     813           0 :     fBeamTypeNum = kPP;
     814           0 :     fMCperiodTPC = "";
     815           0 :     if (fRun >= 170719 && fRun <= 177311) { fLHCperiod="LHC12A"; }
     816           0 :     if (fRun >= 177312 && fRun <= 179356) { fLHCperiod="LHC12B"; }
     817           0 :     if (fRun >= 179357 && fRun <= 183173) { fLHCperiod="LHC12C"; }
     818           0 :     if (fRun >= 183174 && fRun <= 186345) { fLHCperiod="LHC12D"; }
     819           0 :     if (fRun >= 186346 && fRun <= 186635) { fLHCperiod="LHC12E"; }
     820           0 :     if (fRun >= 186636 && fRun <= 188166) { fLHCperiod="LHC12F"; }
     821           0 :     if (fRun >= 188167 && fRun <= 188719) { fLHCperiod="LHC12G"; }
     822           0 :     if (fRun >= 188720 && fRun <= 192738) { fLHCperiod="LHC12H"; }
     823           0 :     if (fRun >= 192739 && fRun <= 193766) { fLHCperiod="LHC12I"; }
     824             :     // no special parametrisations for 12J, use 12I instead
     825           0 :     if (fRun >= 193767 && fRun <= 194479) { /*fLHCperiod="LHC12J";*/ fLHCperiod="LHC12I"; }
     826             : 
     827             :     // overwriting for the PPB period
     828           0 :     if (fRun >= 188167 && fRun <= 188418) { fLHCperiod="LHC12G"; fBeamType="PPB";fBeamTypeNum=kPPB; fMCperiodTPC="LHC12G"; }
     829             :   }
     830             : 
     831             :   // New parametrisation for 2013 pPb runs
     832           0 :   if (fRun >= 194480) {
     833           0 :     fLHCperiod="LHC13B";
     834           0 :     fBeamType="PPB";
     835           0 :     fBeamTypeNum=kPPB;
     836           0 :     fMCperiodTPC="LHC12G";
     837             : 
     838           0 :     if (fCurrentAliRootRev >= 61605)
     839           0 :       fMCperiodTPC="LHC13B2_FIX";
     840           0 :     if (fCurrentAliRootRev >= 62714)
     841           0 :       fMCperiodTPC="LHC13B2_FIXn1";
     842             : 
     843             :     // High luminosity pPb runs require different parametrisations
     844           0 :     if (fRun >= 195875 && fRun <= 197411) {
     845           0 :       fLHCperiod="LHC13F";
     846             :     }
     847             :   }
     848             : 
     849             :   // New parametrisation for the first 2015 pp runs
     850           0 :   if (fRun >= 208505) { // <<< This is the first run in 15a
     851           0 :     fLHCperiod="LHC15F";
     852           0 :     fBeamType="PP";
     853           0 :     fBeamTypeNum=kPP;
     854           0 :     fMCperiodTPC="LHC15G3";
     855             :   }
     856             : 
     857             :   //exception new pp MC productions from 2011 (11a periods have 10f6a splines!)
     858           0 :   if (fBeamType=="PP" && reg.MatchB(fCurrentFile) && !fCurrentFile.Contains("LHC11a")) { fMCperiodTPC="LHC11B2"; fBeamType="PP";fBeamTypeNum=kPP; }
     859             :   // exception for 11f1
     860           0 :   if (fCurrentFile.Contains("LHC11f1")) fMCperiodTPC="LHC11F1";
     861             :   // exception for 12f1a, 12f1b and 12i3
     862           0 :   if (fCurrentFile.Contains("LHC12f1") || fCurrentFile.Contains("LHC12i3")) fMCperiodTPC="LHC12F1";
     863             :   // exception for 12c4
     864           0 :   if (fCurrentFile.Contains("LHC12c4")) fMCperiodTPC="LHC12C4";
     865             :   // exception for 13d1 11d anchored prod
     866           0 :   if (fLHCperiod=="LHC11D" && fCurrentFile.Contains("LHC13d1")) fMCperiodTPC="LHC13D1";
     867           0 : }
     868             : 
     869             : //______________________________________________________________________________
     870             : void AliPIDResponse::SetITSParametrisation()
     871             : {
     872             :   //
     873             :   // Set the ITS parametrisation
     874             :   //
     875           0 : }
     876             : 
     877             : 
     878             : //______________________________________________________________________________
     879             : void AliPIDResponse::AddPointToHyperplane(TH2D* h, TLinearFitter* linExtrapolation, Int_t binX, Int_t binY)
     880             : {
     881           0 :   if (h->GetBinContent(binX, binY) <= 1e-4)
     882             :     return; // Reject bins without content (within some numerical precision) or with strange content
     883             : 
     884           0 :   Double_t coord[2] = {0, 0};
     885           0 :   coord[0] = h->GetXaxis()->GetBinCenter(binX);
     886           0 :   coord[1] = h->GetYaxis()->GetBinCenter(binY);
     887           0 :   Double_t binError = h->GetBinError(binX, binY);
     888           0 :   if (binError <= 0) {
     889             :     binError = 1000; // Should not happen because bins without content are rejected for the map (TH2D* h)
     890           0 :     printf("ERROR: This should never happen: Trying to add bin in addPointToHyperplane with error not set....\n");
     891           0 :   }
     892           0 :   linExtrapolation->AddPoint(coord, h->GetBinContent(binX, binY, binError));
     893           0 : }
     894             : 
     895             : 
     896             : //______________________________________________________________________________
     897             : TH2D* AliPIDResponse::RefineHistoViaLinearInterpolation(TH2D* h, Double_t refineFactorX, Double_t refineFactorY)
     898             : {
     899           0 :   if (!h)
     900           0 :     return 0x0;
     901             : 
     902             :   // Interpolate to finer map
     903           0 :   TLinearFitter* linExtrapolation = new TLinearFitter(2, "hyp2", "");
     904             : 
     905           0 :   Double_t upperMapBoundY = h->GetYaxis()->GetBinUpEdge(h->GetYaxis()->GetNbins());
     906           0 :   Double_t lowerMapBoundY = h->GetYaxis()->GetBinLowEdge(1);
     907             :   Int_t nBinsX = 30;
     908             :   // Binning was find to yield good results, if 40 bins are chosen for the range 0.0016 to 0.02. For the new variable range,
     909             :   // scale the number of bins correspondingly
     910           0 :   Int_t nBinsY = TMath::Nint((upperMapBoundY - lowerMapBoundY) / (0.02 - 0.0016) * 40);
     911           0 :   Int_t nBinsXrefined = nBinsX * refineFactorX;
     912           0 :   Int_t nBinsYrefined = nBinsY * refineFactorY;
     913             : 
     914           0 :   TH2D* hRefined = new TH2D(Form("%s_refined", h->GetName()),  Form("%s (refined)", h->GetTitle()),
     915           0 :                             nBinsXrefined, h->GetXaxis()->GetBinLowEdge(1), h->GetXaxis()->GetBinUpEdge(h->GetXaxis()->GetNbins()),
     916             :                             nBinsYrefined, lowerMapBoundY, upperMapBoundY);
     917             : 
     918           0 :   for (Int_t binX = 1; binX <= nBinsXrefined; binX++)  {
     919           0 :     for (Int_t binY = 1; binY <= nBinsYrefined; binY++)  {
     920             : 
     921           0 :       hRefined->SetBinContent(binX, binY, 1); // Default value is 1
     922             : 
     923           0 :       Double_t centerX = hRefined->GetXaxis()->GetBinCenter(binX);
     924           0 :       Double_t centerY = hRefined->GetYaxis()->GetBinCenter(binY);
     925             : 
     926             :       /*OLD
     927             :       linExtrapolation->ClearPoints();
     928             : 
     929             :       // For interpolation: Just take the corresponding bin from the old histo.
     930             :       // For extrapolation: take the last available bin from the old histo.
     931             :       // If the boundaries are to be skipped, also skip the corresponding bins
     932             :       Int_t oldBinX = h->GetXaxis()->FindBin(centerX);
     933             :       if (oldBinX < 1)
     934             :         oldBinX = 1;
     935             :       if (oldBinX > nBinsX)
     936             :         oldBinX = nBinsX;
     937             : 
     938             :       Int_t oldBinY = h->GetYaxis()->FindBin(centerY);
     939             :       if (oldBinY < 1)
     940             :         oldBinY = 1;
     941             :       if (oldBinY > nBinsY)
     942             :         oldBinY = nBinsY;
     943             : 
     944             :       // Neighbours left column
     945             :       if (oldBinX >= 2) {
     946             :         if (oldBinY >= 2) {
     947             :           AddPointToHyperplane(h, linExtrapolation, oldBinX - 1, oldBinY - 1);
     948             :         }
     949             : 
     950             :         AddPointToHyperplane(h, linExtrapolation, oldBinX - 1, oldBinY);
     951             : 
     952             :         if (oldBinY < nBinsY) {
     953             :           AddPointToHyperplane(h, linExtrapolation, oldBinX - 1, oldBinY + 1);
     954             :         }
     955             :       }
     956             : 
     957             :       // Neighbours (and point itself) same column
     958             :       if (oldBinY >= 2) {
     959             :         AddPointToHyperplane(h, linExtrapolation, oldBinX, oldBinY - 1);
     960             :       }
     961             : 
     962             :       AddPointToHyperplane(h, linExtrapolation, oldBinX, oldBinY);
     963             : 
     964             :       if (oldBinY < nBinsY) {
     965             :         AddPointToHyperplane(h, linExtrapolation, oldBinX, oldBinY + 1);
     966             :       }
     967             : 
     968             :       // Neighbours right column
     969             :       if (oldBinX < nBinsX) {
     970             :         if (oldBinY >= 2) {
     971             :           AddPointToHyperplane(h, linExtrapolation, oldBinX + 1, oldBinY - 1);
     972             :         }
     973             : 
     974             :         AddPointToHyperplane(h, linExtrapolation, oldBinX + 1, oldBinY);
     975             : 
     976             :         if (oldBinY < nBinsY) {
     977             :           AddPointToHyperplane(h, linExtrapolation, oldBinX + 1, oldBinY + 1);
     978             :         }
     979             :       }
     980             : 
     981             : 
     982             :       // Fit 2D-hyperplane
     983             :       if (linExtrapolation->GetNpoints() <= 0)
     984             :         continue;
     985             : 
     986             :       if (linExtrapolation->Eval() != 0)// EvalRobust -> Takes much, much, [...], much more time (~hours instead of seconds)
     987             :         continue;
     988             : 
     989             :       // Fill the bin of the refined histogram with the extrapolated value
     990             :       Double_t interpolatedValue = linExtrapolation->GetParameter(0) + linExtrapolation->GetParameter(1) * centerX
     991             :                                  + linExtrapolation->GetParameter(2) * centerY;
     992             :       */
     993           0 :       Double_t interpolatedValue = h->Interpolate(centerX, centerY) ;
     994           0 :       hRefined->SetBinContent(binX, binY, interpolatedValue);
     995             :     }
     996             :   }
     997             : 
     998             : 
     999             :   // Problem: Interpolation does not work before/beyond center of first/last bin (as the name suggests).
    1000             :   // Therefore, for each row in dEdx: Take last bin from old map and interpolate values from center and edge.
    1001             :   // Assume line through these points and extropolate to last bin of refined map
    1002           0 :   const Double_t firstOldXbinUpEdge = h->GetXaxis()->GetBinUpEdge(1);
    1003           0 :   const Double_t firstOldXbinCenter = h->GetXaxis()->GetBinCenter(1);
    1004             : 
    1005           0 :   const Double_t oldXbinHalfWidth = firstOldXbinUpEdge - firstOldXbinCenter;
    1006             : 
    1007           0 :   const Double_t lastOldXbinLowEdge = h->GetXaxis()->GetBinLowEdge(h->GetNbinsX());
    1008           0 :   const Double_t lastOldXbinCenter = h->GetXaxis()->GetBinCenter(h->GetNbinsX());
    1009             : 
    1010           0 :   for (Int_t binY = 1; binY <= nBinsYrefined; binY++)  {
    1011           0 :     Double_t centerY = hRefined->GetYaxis()->GetBinCenter(binY);
    1012             : 
    1013           0 :     const Double_t interpolatedCenterFirstXbin = h->Interpolate(firstOldXbinCenter, centerY);
    1014           0 :     const Double_t interpolatedUpEdgeFirstXbin = h->Interpolate(firstOldXbinUpEdge, centerY);
    1015             : 
    1016           0 :     const Double_t extrapolationSlopeFirstXbin = (interpolatedUpEdgeFirstXbin - interpolatedCenterFirstXbin) / oldXbinHalfWidth;
    1017             :     const Double_t extrapolationOffsetFirstXbin = interpolatedCenterFirstXbin;
    1018             : 
    1019             : 
    1020           0 :     const Double_t interpolatedCenterLastXbin = h->Interpolate(lastOldXbinCenter, centerY);
    1021           0 :     const Double_t interpolatedLowEdgeLastXbin = h->Interpolate(lastOldXbinLowEdge, centerY);
    1022             : 
    1023           0 :     const Double_t extrapolationSlopeLastXbin = (interpolatedCenterLastXbin - interpolatedLowEdgeLastXbin) / oldXbinHalfWidth;
    1024             :     const Double_t extrapolationOffsetLastXbin = interpolatedCenterLastXbin;
    1025             : 
    1026           0 :     for (Int_t binX = 1; binX <= nBinsXrefined; binX++)  {
    1027           0 :       Double_t centerX = hRefined->GetXaxis()->GetBinCenter(binX);
    1028             : 
    1029           0 :       if (centerX < firstOldXbinCenter) {
    1030           0 :         Double_t extrapolatedValue = extrapolationOffsetFirstXbin + (centerX - firstOldXbinCenter) * extrapolationSlopeFirstXbin;
    1031           0 :         hRefined->SetBinContent(binX, binY, extrapolatedValue);
    1032           0 :       }
    1033           0 :       else if (centerX <= lastOldXbinCenter) {
    1034           0 :         continue;
    1035             :       }
    1036             :       else {
    1037           0 :         Double_t extrapolatedValue = extrapolationOffsetLastXbin + (centerX - lastOldXbinCenter) * extrapolationSlopeLastXbin;
    1038           0 :         hRefined->SetBinContent(binX, binY, extrapolatedValue);
    1039             :       }
    1040           0 :     }
    1041             :   }
    1042             : 
    1043           0 :   delete linExtrapolation;
    1044             : 
    1045             :   return hRefined;
    1046           0 : }
    1047             : 
    1048             : //______________________________________________________________________________
    1049             : void AliPIDResponse::SetTPCEtaMaps(Double_t refineFactorMapX, Double_t refineFactorMapY,
    1050             :                                    Double_t refineFactorSigmaMapX, Double_t refineFactorSigmaMapY)
    1051             : {
    1052             :   //
    1053             :   // Load the TPC eta correction maps from the OADB
    1054             :   //
    1055             : 
    1056           0 :   if (fUseTPCEtaCorrection == kFALSE) {
    1057             :     // Disable eta correction via setting no maps
    1058           0 :     if (!fTPCResponse.SetEtaCorrMap(0x0))
    1059           0 :       AliInfo("Request to disable TPC eta correction -> Eta correction has been disabled");
    1060             :     else
    1061           0 :       AliError("Request to disable TPC eta correction -> Some error occured when unloading the correction maps");
    1062             : 
    1063           0 :     if (!fTPCResponse.SetSigmaParams(0x0, 0))
    1064           0 :       AliInfo("Request to disable TPC eta correction -> Using old parametrisation for sigma");
    1065             :     else
    1066           0 :       AliError("Request to disable TPC eta correction -> Some error occured when unloading the sigma maps");
    1067             : 
    1068             :     return;
    1069             :   }
    1070             : 
    1071           0 :   TString dataType = "DATA";
    1072           0 :   TString period = fLHCperiod.IsNull() ? "No period information" : fLHCperiod;
    1073             : 
    1074           0 :   if (fIsMC)  {
    1075           0 :     if (!(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))) {
    1076           0 :       period=fMCperiodTPC;
    1077           0 :       dataType="MC";
    1078             :     }
    1079           0 :     fRecoPass = 1;
    1080             : 
    1081           0 :     if (!(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC)) && fMCperiodTPC.IsNull()) {
    1082           0 :       AliError("***** Risk for unreliable TPC PID detected:                      ********");
    1083           0 :       AliError("      MC detected, but no MC period set -> Not changing eta maps!");
    1084           0 :       return;
    1085             :     }
    1086             :   }
    1087             : 
    1088           0 :   Int_t recopass = fRecoPass;
    1089           0 :   if (fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC) )
    1090           0 :     recopass = fRecoPassUser;
    1091             : 
    1092           0 :   TString defaultObj = Form("Default_%s_pass%d", dataType.Data(), recopass);
    1093             : 
    1094           0 :   AliInfo(Form("Current period and reco pass: %s.pass%d", period.Data(), recopass));
    1095             : 
    1096             :   // Invalidate old maps
    1097           0 :   fTPCResponse.SetEtaCorrMap(0x0);
    1098           0 :   fTPCResponse.SetSigmaParams(0x0, 0);
    1099             : 
    1100             : 
    1101           0 :   TString fileNameMaps(Form("%s/COMMON/PID/data/TPCetaMaps.root", fOADBPath.Data()));
    1102           0 :   if (!fCustomTPCetaMaps.IsNull()) fileNameMaps=fCustomTPCetaMaps;
    1103             : 
    1104             :   // Load the eta correction maps
    1105           0 :   AliOADBContainer etaMapsCont(Form("TPCetaMaps_%s_pass%d", dataType.Data(), recopass));
    1106             : 
    1107           0 :   Int_t statusCont = etaMapsCont.InitFromFile(fileNameMaps.Data(), Form("TPCetaMaps_%s_pass%d", dataType.Data(), recopass));
    1108           0 :   if (statusCont) {
    1109           0 :     AliError("Failed initializing TPC eta correction maps from OADB -> Disabled eta correction");
    1110           0 :     fUseTPCEtaCorrection = kFALSE;
    1111           0 :   }
    1112             :   else {
    1113           0 :     AliInfo(Form("Loading TPC eta correction map from %s", fileNameMaps.Data()));
    1114             : 
    1115             :     TH2D* etaMap = 0x0;
    1116             : 
    1117           0 :     if (fIsMC && !(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))) {
    1118           0 :       TString searchMap = Form("TPCetaMaps_%s_%s_pass%d", dataType.Data(), period.Data(), recopass);
    1119           0 :       etaMap = dynamic_cast<TH2D *>(etaMapsCont.GetDefaultObject(searchMap.Data()));
    1120           0 :       if (!etaMap) {
    1121             :         // Try default object
    1122           0 :         etaMap = dynamic_cast<TH2D *>(etaMapsCont.GetDefaultObject(defaultObj.Data()));
    1123           0 :       }
    1124           0 :     }
    1125             :     else {
    1126           0 :       etaMap = dynamic_cast<TH2D *>(etaMapsCont.GetObject(fRun, defaultObj.Data()));
    1127             :     }
    1128             : 
    1129             : 
    1130           0 :     if (!etaMap) {
    1131           0 :       AliError(Form("TPC eta correction map not found for run %d and also no default map found -> Disabled eta correction!!!", fRun));
    1132           0 :       fUseTPCEtaCorrection = kFALSE;
    1133           0 :     }
    1134             :     else {
    1135           0 :       TH2D* etaMapRefined = RefineHistoViaLinearInterpolation(etaMap, refineFactorMapX, refineFactorMapY);
    1136             : 
    1137           0 :       if (etaMapRefined) {
    1138           0 :         if (!fTPCResponse.SetEtaCorrMap(etaMapRefined)) {
    1139           0 :           AliError(Form("Failed to set TPC eta correction map for run %d -> Disabled eta correction!!!", fRun));
    1140           0 :           fTPCResponse.SetEtaCorrMap(0x0);
    1141           0 :           fUseTPCEtaCorrection = kFALSE;
    1142           0 :         }
    1143             :         else {
    1144           0 :           AliInfo(Form("Loaded TPC eta correction map (refine factors %.2f/%.2f) from %s: %s (MD5(map) = %s)",
    1145             :                        refineFactorMapX, refineFactorMapY, fileNameMaps.Data(), fTPCResponse.GetEtaCorrMap()->GetTitle(),
    1146             :                        AliTPCPIDResponse::GetChecksum(fTPCResponse.GetEtaCorrMap()).Data()));
    1147             :         }
    1148             : 
    1149           0 :         delete etaMapRefined;
    1150             :       }
    1151             :       else {
    1152           0 :         AliError(Form("Failed to set TPC eta correction map for run %d (map was loaded, but couldn't be refined) -> Disabled eta correction!!!", fRun));
    1153           0 :         fUseTPCEtaCorrection = kFALSE;
    1154             :       }
    1155             :     }
    1156             :   }
    1157             : 
    1158             :   // If there was some problem loading the eta maps, it makes no sense to load the sigma maps (that require eta corrected data)
    1159           0 :   if (fUseTPCEtaCorrection == kFALSE) {
    1160           0 :     AliError("Failed to load TPC eta correction map required by sigma maps -> Using old parametrisation for sigma");
    1161           0 :     return;
    1162             :   }
    1163             : 
    1164             :   // Load the sigma parametrisation (1/dEdx vs tanTheta_local (~eta))
    1165           0 :   AliOADBContainer etaSigmaMapsCont(Form("TPCetaSigmaMaps_%s_pass%d", dataType.Data(), recopass));
    1166             : 
    1167           0 :   statusCont = etaSigmaMapsCont.InitFromFile(fileNameMaps.Data(), Form("TPCetaSigmaMaps_%s_pass%d", dataType.Data(), recopass));
    1168           0 :   if (statusCont) {
    1169           0 :     AliError("Failed initializing TPC eta sigma maps from OADB -> Using old sigma parametrisation");
    1170             :   }
    1171             :   else {
    1172           0 :     AliInfo(Form("Loading TPC eta sigma map from %s", fileNameMaps.Data()));
    1173             : 
    1174             :     TObjArray* etaSigmaPars = 0x0;
    1175             : 
    1176           0 :     if (fIsMC && !(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))) {
    1177           0 :       TString searchMap = Form("TPCetaSigmaMaps_%s_%s_pass%d", dataType.Data(), period.Data(), recopass);
    1178           0 :       etaSigmaPars = dynamic_cast<TObjArray *>(etaSigmaMapsCont.GetDefaultObject(searchMap.Data()));
    1179           0 :       if (!etaSigmaPars) {
    1180             :         // Try default object
    1181           0 :         etaSigmaPars = dynamic_cast<TObjArray *>(etaSigmaMapsCont.GetDefaultObject(defaultObj.Data()));
    1182           0 :       }
    1183           0 :     }
    1184             :     else {
    1185           0 :       etaSigmaPars = dynamic_cast<TObjArray *>(etaSigmaMapsCont.GetObject(fRun, defaultObj.Data()));
    1186             :     }
    1187             : 
    1188           0 :     if (!etaSigmaPars) {
    1189           0 :       AliError(Form("TPC eta sigma parametrisation not found for run %d -> Using old sigma parametrisation!!!", fRun));
    1190             :     }
    1191             :     else {
    1192           0 :       TH2D* etaSigmaPar1Map = dynamic_cast<TH2D *>(etaSigmaPars->FindObject("sigmaPar1Map"));
    1193           0 :       TNamed* sigmaPar0Info = dynamic_cast<TNamed *>(etaSigmaPars->FindObject("sigmaPar0"));
    1194             :       Double_t sigmaPar0 = 0.0;
    1195             : 
    1196           0 :       if (sigmaPar0Info) {
    1197           0 :         TString sigmaPar0String = sigmaPar0Info->GetTitle();
    1198           0 :         sigmaPar0 = sigmaPar0String.Atof();
    1199           0 :       }
    1200             :       else {
    1201             :         // Something is weired because the object for parameter 0 could not be loaded -> New sigma parametrisation can not be used!
    1202             :         etaSigmaPar1Map = 0x0;
    1203             :       }
    1204             : 
    1205           0 :       TH2D* etaSigmaPar1MapRefined = RefineHistoViaLinearInterpolation(etaSigmaPar1Map, refineFactorSigmaMapX, refineFactorSigmaMapY);
    1206             : 
    1207             : 
    1208           0 :       if (etaSigmaPar1MapRefined) {
    1209           0 :         if (!fTPCResponse.SetSigmaParams(etaSigmaPar1MapRefined, sigmaPar0)) {
    1210           0 :           AliError(Form("Failed to set TPC eta sigma map for run %d -> Using old sigma parametrisation!!!", fRun));
    1211           0 :           fTPCResponse.SetSigmaParams(0x0, 0);
    1212             :         }
    1213             :         else {
    1214           0 :           AliInfo(Form("Loaded TPC sigma correction map (refine factors %.2f/%.2f) from %s: %s (MD5(map) = %s, sigmaPar0 = %f)",
    1215             :                        refineFactorSigmaMapX, refineFactorSigmaMapY, fileNameMaps.Data(), fTPCResponse.GetSigmaPar1Map()->GetTitle(),
    1216             :                        AliTPCPIDResponse::GetChecksum(fTPCResponse.GetSigmaPar1Map()).Data(), sigmaPar0));
    1217             :         }
    1218             : 
    1219           0 :         delete etaSigmaPar1MapRefined;
    1220             :       }
    1221             :       else {
    1222           0 :         AliError(Form("Failed to set TPC eta sigma map for run %d (map was loaded, but couldn't be refined) -> Using old sigma parametrisation!!!",
    1223             :                       fRun));
    1224             :       }
    1225             :     }
    1226             :   }
    1227           0 : }
    1228             : 
    1229             : 
    1230             : //______________________________________________________________________________
    1231             : Bool_t AliPIDResponse::InitializeTPCResponse()
    1232             : {
    1233             :   // Load the Array with TPC PID response information
    1234             :   // This is the new method which will completely replace the old one at some point
    1235             : 
    1236             :   //
    1237             :   // Setup old resolution parametrisation
    1238             :   // TODO: This should be moved to the initialisation and vanish completely at some point
    1239             : 
    1240             :   //default
    1241           0 :   fTPCResponse.SetSigma(3.79301e-03, 2.21280e+04);
    1242             : 
    1243           0 :   if (fRun>=122195){ //LHC10d
    1244           0 :     fTPCResponse.SetSigma(2.30176e-02, 5.60422e+02);
    1245           0 :   }
    1246             : 
    1247           0 :   if (fRun>=170719){ // LHC12a
    1248           0 :     fTPCResponse.SetSigma(2.95714e-03, 1.01953e+05);
    1249           0 :   }
    1250             : 
    1251           0 :   if (fRun>=177312){ // LHC12b
    1252           0 :     fTPCResponse.SetSigma(3.74633e-03, 7.11829e+04 );
    1253           0 :   }
    1254             : 
    1255           0 :   if (fRun>=186346){ // LHC12e
    1256           0 :     fTPCResponse.SetSigma(8.62022e-04, 9.08156e+05);
    1257           0 :   }
    1258             : 
    1259             :   
    1260           0 :   AliInfo("---------------------------- TPC Response Configuration (New) ----------------------------");
    1261             :   // ===| load TPC response array from OADB |===================================
    1262           0 :   TString fileNamePIDresponse(Form("%s/COMMON/PID/data/TPCPIDResponseOADB.root", fOADBPath.Data()));
    1263           0 :   if (!fCustomTPCpidResponseOADBFile.IsNull()) fileNamePIDresponse=fCustomTPCpidResponseOADBFile;
    1264             : 
    1265             : 
    1266             :   // ---| In case of MC and NO tune on data fall back to old method |-----------
    1267           0 :   if (fIsMC) {
    1268           0 :     if(!(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))) return kFALSE;
    1269             :   }
    1270             : 
    1271             :   // ---| set reco pass |-------------------------------------------------------
    1272           0 :   Int_t recopass = fRecoPass;
    1273           0 :   if(fIsMC && fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC)) recopass = fRecoPassUser;
    1274             : 
    1275           0 :   const Bool_t returnValue = fTPCResponse.InitFromOADB(fRun, TString::Format("%d", recopass), fileNamePIDresponse, fUseTPCMultiplicityCorrection);
    1276           0 :   AliInfo("------------------------------------------------------------------------------------------");
    1277             : 
    1278           0 :   return returnValue;
    1279           0 : }
    1280             : 
    1281             : //______________________________________________________________________________
    1282             : void AliPIDResponse::SetTPCPidResponseMaster()
    1283             : {
    1284             :   //
    1285             :   // Load the TPC pid response functions from the OADB
    1286             :   // Load the TPC voltage maps from OADB
    1287             :   //
    1288             :   //don't load twice for the moment
    1289           0 :    if (fArrPidResponseMaster) return;
    1290             : 
    1291             : 
    1292             :   //reset the PID response functions
    1293           0 :   delete fArrPidResponseMaster;
    1294           0 :   fArrPidResponseMaster=NULL;
    1295             : 
    1296             :   TFile *f=NULL;
    1297             : 
    1298           0 :   TString fileNamePIDresponse(Form("%s/COMMON/PID/data/TPCPIDResponse.root", fOADBPath.Data()));
    1299           0 :   if (!fCustomTPCpidResponse.IsNull()) fileNamePIDresponse=fCustomTPCpidResponse;
    1300             : 
    1301           0 :   f=TFile::Open(fileNamePIDresponse.Data());
    1302           0 :   if (f && f->IsOpen() && !f->IsZombie()){
    1303           0 :     fArrPidResponseMaster=dynamic_cast<TObjArray*>(f->Get("TPCPIDResponse"));
    1304           0 :   }
    1305           0 :   delete f;
    1306             : 
    1307           0 :   TString fileNameVoltageMaps(Form("%s/COMMON/PID/data/TPCvoltageSettings.root", fOADBPath.Data()));
    1308           0 :   f=TFile::Open(fileNameVoltageMaps.Data());
    1309           0 :   if (f && f->IsOpen() && !f->IsZombie()){
    1310           0 :     fOADBvoltageMaps=dynamic_cast<AliOADBContainer*>(f->Get("TPCvoltageSettings"));
    1311           0 :   }
    1312           0 :   delete f;
    1313             : 
    1314           0 :   if (!fArrPidResponseMaster){
    1315           0 :     AliFatal(Form("Could not retrieve the TPC pid response from: %s",fileNamePIDresponse.Data()));
    1316           0 :     return;
    1317             :   }
    1318           0 :   fArrPidResponseMaster->SetOwner();
    1319             : 
    1320           0 :   if (!fOADBvoltageMaps)
    1321             :   {
    1322           0 :     AliFatal(Form("Could not retrieve the TPC voltage maps from: %s",fileNameVoltageMaps.Data()));
    1323             :   }
    1324           0 :   fArrPidResponseMaster->SetOwner();
    1325           0 : }
    1326             : 
    1327             : //______________________________________________________________________________
    1328             : void AliPIDResponse::SetTPCParametrisation()
    1329             : {
    1330             :   //
    1331             :   // Change BB parametrisation for current run
    1332             :   //
    1333             : 
    1334           0 :   AliInfo("---------------------------- TPC Response Configuration (Old) ----------------------------");
    1335             : 
    1336             :   //
    1337             :   //reset old splines
    1338             :   //
    1339           0 :   fTPCResponse.ResetSplines();
    1340             : 
    1341           0 :   if (fLHCperiod.IsNull()) {
    1342           0 :     AliError("No period set, not changing parametrisation");
    1343           0 :     AliInfo("------------------------------------------------------------------------------------------");
    1344           0 :     return;
    1345             :   }
    1346             : 
    1347             :   //
    1348             :   // Set default parametrisations for data and MC
    1349             :   //
    1350             : 
    1351             :   //data type
    1352           0 :   TString datatype="DATA";
    1353             :   //in case of mc fRecoPass is per default 1
    1354           0 :   if (fIsMC) {
    1355           0 :       if(!(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))) datatype="MC";
    1356           0 :       fRecoPass=1;
    1357           0 :   } else {
    1358           0 :     if (fRecoPass<=0) {
    1359           0 :       fTPCResponse.SetUseDatabase(kFALSE);
    1360           0 :       AliError("******** Risk for unreliable TPC PID detected               **********");
    1361           0 :       AliError("         no proper reco pass was set, no splines can be set");
    1362           0 :       AliError("         an outdate Bethe Bloch parametrisation will be used");
    1363           0 :       AliInfo("------------------------------------------------------------------------------------------");
    1364           0 :       return;
    1365             :     }
    1366             :   }
    1367             : 
    1368             :   // period
    1369           0 :   TString period=fLHCperiod;
    1370           0 :   if (fIsMC && !(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))) period=fMCperiodTPC;
    1371             : 
    1372           0 :   Int_t recopass = fRecoPass;
    1373           0 :   if(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC)) recopass = fRecoPassUser;
    1374             : 
    1375           0 :   AliInfo(Form("Searching splines for: %s %s PASS%d %s",datatype.Data(),period.Data(),recopass,fBeamType.Data()));
    1376             :   Bool_t found=kFALSE;
    1377             :   //
    1378             :   //set the new PID splines
    1379             :   //
    1380           0 :   if (fArrPidResponseMaster){
    1381             :     //for MC don't use period information
    1382             :     //if (fIsMC) period="[A-Z0-9]*";
    1383             :     //for MC use MC period information
    1384             :     //pattern for the default entry (valid for all particles)
    1385           0 :     TPRegexp reg(Form("TSPLINE3_%s_([A-Z]*)_%s_PASS%d_%s_MEAN(_*)([A-Z1-9]*)",datatype.Data(),period.Data(),recopass,fBeamType.Data()));
    1386             : 
    1387             :     //find particle id and gain scenario
    1388           0 :     for (Int_t igainScenario=0; igainScenario<AliTPCPIDResponse::fgkNumberOfGainScenarios; igainScenario++)
    1389             :     {
    1390             :       TObject *grAll=NULL;
    1391           0 :       TString gainScenario = AliTPCPIDResponse::GainScenarioName(igainScenario);
    1392           0 :       gainScenario.ToUpper();
    1393             :       //loop over entries and filter them
    1394           0 :       for (Int_t iresp=0; iresp<fArrPidResponseMaster->GetEntriesFast();++iresp)
    1395             :       {
    1396           0 :         TObject *responseFunction=fArrPidResponseMaster->At(iresp);
    1397           0 :         if (responseFunction==NULL) continue;
    1398           0 :         TString responseName=responseFunction->GetName();
    1399             : 
    1400           0 :         if (!reg.MatchB(responseName)) continue;
    1401             : 
    1402           0 :         TObjArray *arr=reg.MatchS(responseName); if (!arr) continue;
    1403             :         TObject* tmp=NULL;
    1404           0 :         tmp=arr->At(1); if (!tmp) continue;
    1405           0 :         TString particleName=tmp->GetName();
    1406           0 :         tmp=arr->At(3); if (!tmp) continue;
    1407           0 :         TString gainScenarioName=tmp->GetName();
    1408           0 :         delete arr;
    1409           0 :         if (particleName.IsNull()) continue;
    1410           0 :         if (!grAll && particleName=="ALL" && gainScenarioName==gainScenario) grAll=responseFunction;
    1411             :         else
    1412             :         {
    1413           0 :           for (Int_t ispec=0; ispec<(AliTPCPIDResponse::fgkNumberOfParticleSpecies); ++ispec)
    1414             :           {
    1415           0 :             TString particle=AliPID::ParticleName(ispec);
    1416           0 :             particle.ToUpper();
    1417             :             //std::cout<<responseName<<" "<<particle<<" "<<particleName<<" "<<gainScenario<<" "<<gainScenarioName<<std::endl;
    1418           0 :             if ( particle == particleName && gainScenario == gainScenarioName )
    1419             :             {
    1420           0 :               fTPCResponse.SetResponseFunction( responseFunction,
    1421             :                                                 (AliPID::EParticleType)ispec,
    1422             :                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
    1423           0 :               fTPCResponse.SetUseDatabase(kTRUE);
    1424           0 :               AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,responseFunction->GetName(),
    1425             :                            AliTPCPIDResponse::GetChecksum((TSpline3*)responseFunction).Data()));
    1426             :               found=kTRUE;
    1427           0 :               break;
    1428             :             }
    1429           0 :           }
    1430             :         }
    1431           0 :       }
    1432             : 
    1433             :       // Retrieve responsefunction for pions - will (if available) be used for muons if there are no dedicated muon splines.
    1434             :       // For light nuclei, try to set the proton spline, if no dedicated splines are available.
    1435             :       // In both cases: Use default splines, if no dedicated splines and no pion/proton splines are available.
    1436           0 :       TObject* responseFunctionPion = fTPCResponse.GetResponseFunction( (AliPID::EParticleType)AliPID::kPion,
    1437             :                                                                         (AliTPCPIDResponse::ETPCgainScenario)igainScenario);
    1438           0 :       TObject* responseFunctionProton = fTPCResponse.GetResponseFunction( (AliPID::EParticleType)AliPID::kProton,
    1439             :                                                                           (AliTPCPIDResponse::ETPCgainScenario)igainScenario);
    1440             : 
    1441           0 :       for (Int_t ispec=0; ispec<(AliTPCPIDResponse::fgkNumberOfParticleSpecies); ++ispec)
    1442             :       {
    1443           0 :         if (!fTPCResponse.GetResponseFunction( (AliPID::EParticleType)ispec,
    1444             :           (AliTPCPIDResponse::ETPCgainScenario)igainScenario))
    1445             :         {
    1446           0 :           if (ispec == AliPID::kMuon) { // Muons
    1447           0 :             if (responseFunctionPion) {
    1448           0 :               fTPCResponse.SetResponseFunction( responseFunctionPion,
    1449             :                                                 (AliPID::EParticleType)ispec,
    1450             :                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
    1451           0 :               fTPCResponse.SetUseDatabase(kTRUE);
    1452           0 :               AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,responseFunctionPion->GetName(),
    1453             :                            AliTPCPIDResponse::GetChecksum((TSpline3*)responseFunctionPion).Data()));
    1454             :               found=kTRUE;
    1455           0 :             }
    1456           0 :             else if (grAll) {
    1457           0 :               fTPCResponse.SetResponseFunction( grAll,
    1458             :                                                 (AliPID::EParticleType)ispec,
    1459             :                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
    1460           0 :               fTPCResponse.SetUseDatabase(kTRUE);
    1461           0 :               AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,grAll->GetName(),
    1462             :                            AliTPCPIDResponse::GetChecksum((TSpline3*)grAll).Data()));
    1463             :               found=kTRUE;
    1464           0 :             }
    1465             :             //else
    1466             :             //  AliError(Form("No splines found for muons (also no pion splines and no default splines) for gain scenario %d!", igainScenario));
    1467             :           }
    1468           0 :           else if (ispec >= AliPID::kSPECIES) { // Light nuclei
    1469           0 :             if (responseFunctionProton) {
    1470           0 :               fTPCResponse.SetResponseFunction( responseFunctionProton,
    1471             :                                                 (AliPID::EParticleType)ispec,
    1472             :                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
    1473           0 :               fTPCResponse.SetUseDatabase(kTRUE);
    1474           0 :               AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,responseFunctionProton->GetName(),
    1475             :                            AliTPCPIDResponse::GetChecksum((TSpline3*)responseFunctionProton).Data()));
    1476             :               found=kTRUE;
    1477           0 :             }
    1478           0 :             else if (grAll) {
    1479           0 :               fTPCResponse.SetResponseFunction( grAll,
    1480             :                                                 (AliPID::EParticleType)ispec,
    1481             :                                                 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
    1482           0 :               fTPCResponse.SetUseDatabase(kTRUE);
    1483           0 :               AliInfo(Form("Adding graph: %d %d - %s (MD5(spline) = %s)",ispec,igainScenario,grAll->GetName(),
    1484             :                            AliTPCPIDResponse::GetChecksum((TSpline3*)grAll).Data()));
    1485             :               found=kTRUE;
    1486           0 :             }
    1487             :             //else
    1488             :             //  AliError(Form("No splines found for species %d (also no proton splines and no default splines) for gain scenario %d!",
    1489             :             //                ispec, igainScenario));
    1490             :           }
    1491             :         }
    1492             :       }
    1493           0 :     }
    1494           0 :   }
    1495           0 :   else AliInfo("no fArrPidResponseMaster");
    1496             : 
    1497           0 :   if (!found){
    1498           0 :     AliError("***** Risk for unreliable TPC PID detected:                      ********");
    1499           0 :     AliError(Form("No splines found for: %s %s PASS%d %s",datatype.Data(),period.Data(),recopass,fBeamType.Data()));
    1500             :   }
    1501             : 
    1502             : 
    1503             :   //
    1504             :   // Setup multiplicity correction (only used for non-pp collisions)
    1505             :   //
    1506             : 
    1507           0 :   const Bool_t isPP = (fBeamType.CompareTo("PP") == 0);
    1508             : 
    1509             :   // 2013 pPb data taking at low luminosity
    1510           0 :   const Bool_t isPPb2013LowLuminosity = period.Contains("LHC13B") || period.Contains("LHC13C") || period.Contains("LHC13D");
    1511             :   // PbPb 2010, period 10h.pass2
    1512             :   //TODO Needs further development const Bool_t is10hpass2 = period.Contains("LHC10H") && recopass == 2;
    1513             : 
    1514             : 
    1515             :   // In case of MC without(!) tune on data activated for the TPC, don't use the multiplicity correction for the moment
    1516           0 :   Bool_t isMCandNotTPCtuneOnData = fIsMC && !(fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC));
    1517             : 
    1518             :   // If correction is available, but disabled (highly NOT recommended!), print warning
    1519           0 :   if (!fUseTPCMultiplicityCorrection && !isPP && !isMCandNotTPCtuneOnData) {
    1520             :     //TODO: Needs further development if (is10hpass2 || isPPb2013LowLuminosity) {
    1521           0 :     if (isPPb2013LowLuminosity) {
    1522           0 :       AliWarning("Mulitplicity correction disabled, but correction parameters for this period exist. It is highly recommended to use enable the correction. Otherwise the splines might be off!");
    1523             :     }
    1524             :   }
    1525             : 
    1526           0 :   if (fUseTPCMultiplicityCorrection && !isPP && !isMCandNotTPCtuneOnData) {
    1527           0 :     AliInfo("Multiplicity correction enabled!");
    1528             : 
    1529             :     //TODO After testing, load parameters from outside
    1530             :     /*TODO no correction for MC
    1531             :     if (period.Contains("LHC11A10"))  {//LHC11A10A
    1532             :       AliInfo("Using multiplicity correction parameters for 11a10!");
    1533             :       fTPCResponse.SetParameterMultiplicityCorrection(0, 6.90133e-06);
    1534             :       fTPCResponse.SetParameterMultiplicityCorrection(1, -1.22123e-03);
    1535             :       fTPCResponse.SetParameterMultiplicityCorrection(2, 1.80220e-02);
    1536             :       fTPCResponse.SetParameterMultiplicityCorrection(3, 0.1);
    1537             :       fTPCResponse.SetParameterMultiplicityCorrection(4, 6.45306e-03);
    1538             : 
    1539             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(0, -2.85505e-07);
    1540             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(1, -1.31911e-06);
    1541             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(2, -0.5);
    1542             : 
    1543             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(0, -4.29665e-05);
    1544             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(1, 1.37023e-02);
    1545             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(2, -6.36337e-01);
    1546             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(3, 1.13479e-02);
    1547             :     }
    1548           0 :     else*/ if (isPPb2013LowLuminosity)  {// 2013 pPb data taking at low luminosity
    1549           0 :       AliInfo("Using multiplicity correction parameters for 13b.pass2 (at least also valid for 13{c,d} and pass 3)!");
    1550             : 
    1551           0 :       fTPCResponse.SetParameterMultiplicityCorrection(0, -5.906e-06);
    1552           0 :       fTPCResponse.SetParameterMultiplicityCorrection(1, -5.064e-04);
    1553           0 :       fTPCResponse.SetParameterMultiplicityCorrection(2, -3.521e-02);
    1554           0 :       fTPCResponse.SetParameterMultiplicityCorrection(3, 2.469e-02);
    1555           0 :       fTPCResponse.SetParameterMultiplicityCorrection(4, 0);
    1556             : 
    1557           0 :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(0, -5.32e-06);
    1558           0 :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(1, 1.177e-05);
    1559           0 :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(2, -0.5);
    1560             : 
    1561           0 :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(0, 0.);
    1562           0 :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(1, 0.);
    1563           0 :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(2, 0.);
    1564           0 :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(3, 0.);
    1565             : 
    1566             :       /* Not too bad, but far from perfect in the details
    1567             :       fTPCResponse.SetParameterMultiplicityCorrection(0, -6.27187e-06);
    1568             :       fTPCResponse.SetParameterMultiplicityCorrection(1, -4.60649e-04);
    1569             :       fTPCResponse.SetParameterMultiplicityCorrection(2, -4.26450e-02);
    1570             :       fTPCResponse.SetParameterMultiplicityCorrection(3, 2.40590e-02);
    1571             :       fTPCResponse.SetParameterMultiplicityCorrection(4, 0);
    1572             : 
    1573             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(0, -5.338e-06);
    1574             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(1, 1.220e-05);
    1575             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(2, -0.5);
    1576             : 
    1577             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(0, 7.89237e-05);
    1578             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(1, -1.30662e-02);
    1579             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(2, 8.91548e-01);
    1580             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(3, 1.47931e-02);
    1581             :       */
    1582             :     }
    1583             :     /*TODO: Needs further development
    1584             :     else if (is10hpass2) {
    1585             :       AliInfo("Using multiplicity correction parameters for 10h.pass2!");
    1586             :       fTPCResponse.SetParameterMultiplicityCorrection(0, 3.21636e-07);
    1587             :       fTPCResponse.SetParameterMultiplicityCorrection(1, -6.65876e-04);
    1588             :       fTPCResponse.SetParameterMultiplicityCorrection(2, 1.28786e-03);
    1589             :       fTPCResponse.SetParameterMultiplicityCorrection(3, 1.47677e-02);
    1590             :       fTPCResponse.SetParameterMultiplicityCorrection(4, 0);
    1591             : 
    1592             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(0, 7.23591e-08);
    1593             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(1, 2.7469e-06);
    1594             :       fTPCResponse.SetParameterMultiplicityCorrectionTanTheta(2, -0.5);
    1595             : 
    1596             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(0, -1.22590e-05);
    1597             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(1, 6.88888e-03);
    1598             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(2, -3.20788e-01);
    1599             :       fTPCResponse.SetParameterMultiplicitySigmaCorrection(3, 1.07345e-02);
    1600             :     }
    1601             :     */
    1602             :     else {
    1603           0 :       AliError(Form("Multiplicity correction is enabled, but no multiplicity correction parameters have been found for period %s.pass%d -> Mulitplicity correction DISABLED!", period.Data(), recopass));
    1604           0 :       fUseTPCMultiplicityCorrection = kFALSE;
    1605           0 :       fTPCResponse.ResetMultiplicityCorrectionFunctions();
    1606             :     }
    1607             :   }
    1608             :   else {
    1609             :     // Just set parameters such that overall correction factor is 1, i.e. no correction.
    1610             :     // This is just a reasonable choice for the parameters for safety reasons. Disabling
    1611             :     // the multiplicity correction will anyhow skip the calculation of the corresponding
    1612             :     // correction factor inside THIS class. Nevertheless, experts can access the TPCPIDResponse
    1613             :     // directly and use it for calculations - which should still give valid results, even if
    1614             :     // the multiplicity correction is explicitely enabled in such expert calls.
    1615             : 
    1616           0 :     TString reasonForDisabling = "requested by user";
    1617           0 :     if (fUseTPCMultiplicityCorrection) {
    1618           0 :       if (isPP)
    1619           0 :         reasonForDisabling = "pp collisions";
    1620             :       else
    1621           0 :         reasonForDisabling = "MC w/o tune on data";
    1622             :     }
    1623             : 
    1624           0 :     AliInfo(Form("Multiplicity correction %sdisabled (%s)!", fUseTPCMultiplicityCorrection ? "automatically " : "",
    1625             :                  reasonForDisabling.Data()));
    1626             : 
    1627           0 :     fUseTPCMultiplicityCorrection = kFALSE;
    1628           0 :     fTPCResponse.ResetMultiplicityCorrectionFunctions();
    1629           0 :   }
    1630             : 
    1631           0 :   if (fUseTPCMultiplicityCorrection) {
    1632           0 :     for (Int_t i = 0; i <= 4 + 1; i++) {
    1633           0 :       AliInfo(Form("parMultCorr: %d, %e", i, fTPCResponse.GetMultiplicityCorrectionFunction()->GetParameter(i)));
    1634             :     }
    1635           0 :     for (Int_t j = 0; j <= 2 + 1; j++) {
    1636           0 :       AliInfo(Form("parMultCorrTanTheta: %d, %e", j, fTPCResponse.GetMultiplicityCorrectionFunctionTanTheta()->GetParameter(j)));
    1637             :     }
    1638           0 :     for (Int_t j = 0; j <= 3 + 1; j++) {
    1639           0 :       AliInfo(Form("parMultSigmaCorr: %d, %e", j, fTPCResponse.GetMultiplicitySigmaCorrectionFunction()->GetParameter(j)));
    1640             :     }
    1641           0 :   }
    1642             : 
    1643             :   //
    1644             :   // Setup old resolution parametrisation
    1645             :   //
    1646             : 
    1647             :   //default
    1648           0 :   fTPCResponse.SetSigma(3.79301e-03, 2.21280e+04);
    1649             : 
    1650           0 :   if (fRun>=122195){ //LHC10d
    1651           0 :     fTPCResponse.SetSigma(2.30176e-02, 5.60422e+02);
    1652             :   }
    1653             : 
    1654           0 :   if (fRun>=170719){ // LHC12a
    1655           0 :     fTPCResponse.SetSigma(2.95714e-03, 1.01953e+05);
    1656             :   }
    1657             : 
    1658           0 :   if (fRun>=177312){ // LHC12b
    1659           0 :     fTPCResponse.SetSigma(3.74633e-03, 7.11829e+04 );
    1660             :   }
    1661             : 
    1662           0 :   if (fRun>=186346){ // LHC12e
    1663           0 :     fTPCResponse.SetSigma(8.62022e-04, 9.08156e+05);
    1664             :   }
    1665             : 
    1666           0 :   if (fArrPidResponseMaster)
    1667           0 :   fResolutionCorrection=(TF1*)fArrPidResponseMaster->FindObject(Form("TF1_%s_ALL_%s_PASS%d_%s_SIGMA",datatype.Data(),period.Data(),recopass,fBeamType.Data()));
    1668             : 
    1669           0 :   if (fResolutionCorrection) AliInfo(Form("Setting multiplicity correction function: %s  (MD5(corr function) = %s)",
    1670             :                                           fResolutionCorrection->GetName(), AliTPCPIDResponse::GetChecksum(fResolutionCorrection).Data()));
    1671             : 
    1672             :   //read in the voltage map
    1673             :   TVectorF* gsm = 0x0;
    1674           0 :   if (fOADBvoltageMaps) gsm=dynamic_cast<TVectorF*>(fOADBvoltageMaps->GetObject(fRun));
    1675           0 :   if (gsm)
    1676             :   {
    1677           0 :     fTPCResponse.SetVoltageMap(*gsm);
    1678           0 :     TString vals;
    1679           0 :     AliInfo(Form("Reading the voltage map for run %d\n",fRun));
    1680           0 :     vals="IROC A: "; for (Int_t i=0; i<18; i++){vals+=Form("%.2f ",(*gsm)[i]);}
    1681           0 :     AliInfo(vals.Data());
    1682           0 :     vals="IROC C: "; for (Int_t i=18; i<36; i++){vals+=Form("%.2f ",(*gsm)[i]);}
    1683           0 :     AliInfo(vals.Data());
    1684           0 :     vals="OROC A: "; for (Int_t i=36; i<54; i++){vals+=Form("%.2f ",(*gsm)[i]);}
    1685           0 :     AliInfo(vals.Data());
    1686           0 :     vals="OROC C: "; for (Int_t i=54; i<72; i++){vals+=Form("%.2f ",(*gsm)[i]);}
    1687           0 :     AliInfo(vals.Data());
    1688           0 :   }
    1689           0 :   else AliInfo("no voltage map, ideal default assumed");
    1690           0 :   AliInfo("------------------------------------------------------------------------------------------");
    1691           0 : }
    1692             : 
    1693             : //______________________________________________________________________________
    1694             : void AliPIDResponse::SetTRDPidResponseMaster()
    1695             : {
    1696             :   //
    1697             :   // Load the TRD pid params and references from the OADB
    1698             :   //
    1699           0 :   if(fTRDPIDResponseObject) return;
    1700           0 :   AliOADBContainer contParams("contParams");
    1701             : 
    1702           0 :   Int_t statusResponse = contParams.InitFromFile(Form("%s/COMMON/PID/data/TRDPIDResponse.root", fOADBPath.Data()), "AliTRDPIDResponseObject");
    1703           0 :   if(statusResponse){
    1704           0 :     AliError("Failed initializing PID Response Object from OADB");
    1705             :   } else {
    1706           0 :     AliInfo(Form("Loading TRD Response from %s/COMMON/PID/data/TRDPIDResponse.root", fOADBPath.Data()));
    1707           0 :     fTRDPIDResponseObject = dynamic_cast<AliTRDPIDResponseObject *>(contParams.GetObject(fRun));
    1708           0 :     if(!fTRDPIDResponseObject){
    1709           0 :       AliError(Form("TRD Response not found in run %d", fRun));
    1710             :     }
    1711             :   }
    1712           0 : }
    1713             : 
    1714             : //______________________________________________________________________________
    1715             : void AliPIDResponse::InitializeTRDResponse(){
    1716             :   //
    1717             :   // Set PID Params and references to the TRD PID response
    1718             :   //
    1719           0 :     fTRDResponse.SetPIDResponseObject(fTRDPIDResponseObject);
    1720           0 :     fTRDResponse.SetdEdxParams(fTRDdEdxParams);
    1721           0 : }
    1722             : 
    1723             : //______________________________________________________________________________
    1724             : void AliPIDResponse::SetTRDSlices(UInt_t TRDslicesForPID[2],AliTRDPIDResponse::ETRDPIDMethod method) const{
    1725             : 
    1726           0 :     if(fLHCperiod.Contains("LHC10D") || fLHCperiod.Contains("LHC10E")){
    1727             :         // backward compatibility for setting with 8 slices
    1728           0 :         TRDslicesForPID[0] = 0;
    1729           0 :         TRDslicesForPID[1] = 7;
    1730           0 :     }
    1731             :     else{
    1732           0 :         if(method==AliTRDPIDResponse::kLQ1D){
    1733           0 :             TRDslicesForPID[0] = 0; // first Slice contains normalized dEdx
    1734           0 :             TRDslicesForPID[1] = 0;
    1735           0 :         }
    1736           0 :         if((method==AliTRDPIDResponse::kLQ2D)||(method==AliTRDPIDResponse::kLQ3D)||(method==AliTRDPIDResponse::kLQ7D)){
    1737           0 :             TRDslicesForPID[0] = 1;
    1738           0 :             TRDslicesForPID[1] = 7;
    1739           0 :         }
    1740             :     }
    1741           0 :     AliDebug(1,Form("Slice Range set to %d - %d",TRDslicesForPID[0],TRDslicesForPID[1]));
    1742           0 : }
    1743             : //______________________________________________________________________________
    1744             : void AliPIDResponse::SetTRDdEdxParams()
    1745             : {
    1746           0 :   if(fTRDdEdxParams) return;
    1747             : 
    1748           0 :   const TString containerName = "TRDdEdxParamsContainer";
    1749           0 :   AliOADBContainer cont(containerName.Data());
    1750             : 
    1751           0 :   const TString filePathNamePackage=Form("%s/COMMON/PID/data/TRDdEdxParams.root", fOADBPath.Data());
    1752             : 
    1753           0 :   const Int_t statusCont = cont.InitFromFile(filePathNamePackage.Data(), cont.GetName());
    1754           0 :   if (statusCont){
    1755           0 :     AliFatal("Failed initializing settings from OADB");
    1756             :   }
    1757             :   else{
    1758           0 :     AliInfo(Form("Loading %s from %s\n", cont.GetName(), filePathNamePackage.Data()));
    1759             : 
    1760           0 :     fTRDdEdxParams = (AliTRDdEdxParams*)(cont.GetObject(fRun, "default"));
    1761             : 
    1762           0 :     if(!fTRDdEdxParams){
    1763           0 :       AliError(Form("TRD dEdx Params default not found"));
    1764             :     }
    1765             :   }
    1766           0 : }
    1767             : 
    1768             : //______________________________________________________________________________
    1769             : void AliPIDResponse::SetTRDEtaMaps()
    1770             : {
    1771             :   //
    1772             :   // Load the TRD eta correction map from the OADB
    1773             :   //
    1774             : 
    1775           0 :     if (fIsMC) fUseTRDEtaCorrection = kFALSE;
    1776           0 :     if (fUseTRDEtaCorrection == kFALSE) {
    1777             :       //  fTRDResponse.SetEtaCorrMap(0,0x0);
    1778           0 :         AliInfo("Request to disable TRD eta correction -> Eta correction has been disabled");
    1779           0 :         return;
    1780             :     }
    1781             :     TH2D* etaMap[1];
    1782             :     etaMap[0] = 0x0;
    1783             : 
    1784             : 
    1785           0 :     const TString containerName = "TRDEtaCorrectionMap";
    1786           0 :     AliOADBContainer cont(containerName.Data());
    1787             : 
    1788           0 :     const TString filePathNamePackage=Form("%s/COMMON/PID/data/TRDdEdxEtaCorrectionParams.root", fOADBPath.Data());
    1789             : 
    1790           0 :     const Int_t statusCont = cont.InitFromFile(filePathNamePackage.Data(), cont.GetName());
    1791           0 :     if (statusCont){
    1792           0 :         AliFatal("Failed initializing TRD Eta Correction settings from OADB");
    1793           0 :         return;
    1794             :     }
    1795             :     else{
    1796           0 :         AliInfo(Form("Loading %s from %s\n", cont.GetName(), filePathNamePackage.Data()));
    1797             : 
    1798           0 :         TObject* etaarray=(TObject*)cont.GetObject(fRun);
    1799             : 
    1800           0 :         if(etaarray){
    1801           0 :                 etaMap[0] = (TH2D *)etaarray->FindObject("TRDEtaMap");
    1802           0 :                 fTRDResponse.SetEtaCorrMap(0,etaMap[0]);
    1803             :         }
    1804             :         else{
    1805           0 :             AliError(Form("TRD Eta Correction Params not found"));
    1806           0 :             fUseTRDEtaCorrection = kFALSE;
    1807           0 :             return;
    1808             :             //fTRDResponse.SetEtaCorrMap(0,0x0);
    1809             :         }
    1810             : 
    1811             : 
    1812             : 
    1813           0 :         if (!etaMap[0]) {
    1814           0 :             AliError(Form("TRD Eta Correction Params not found"));
    1815           0 :             fUseTRDEtaCorrection = kFALSE;
    1816           0 :             return;
    1817             :             //fTRDResponse.SetEtaCorrMap(0,0x0);
    1818             :         }
    1819             : 
    1820             : 
    1821           0 :     }
    1822             : 
    1823             : 
    1824           0 : }
    1825             : 
    1826             : 
    1827             : //______________________________________________________________________________
    1828             : void AliPIDResponse::SetTOFPidResponseMaster()
    1829             : {
    1830             :   //
    1831             :   // Load the TOF pid params from the OADB
    1832             :   //
    1833             : 
    1834           0 :   if (fTOFPIDParams) delete fTOFPIDParams;
    1835           0 :   fTOFPIDParams=NULL;
    1836             : 
    1837           0 :   TFile *oadbf = new TFile(Form("%s/COMMON/PID/data/TOFPIDParams.root",fOADBPath.Data()));
    1838           0 :   if (oadbf && oadbf->IsOpen()) {
    1839           0 :     Int_t recoPass = fRecoPass;
    1840           0 :     if (fTuneMConData && ((fTuneMConDataMask & kDetTOF) == kDetTOF) ) recoPass = fRecoPassUser;
    1841           0 :     TString passName = Form("pass%d",recoPass);
    1842           0 :     AliInfo(Form("Loading TOF Params from %s/COMMON/PID/data/TOFPIDParams.root for run %d (pass: %s)", fOADBPath.Data(),fRun,passName.Data()));
    1843           0 :     AliOADBContainer *oadbc = (AliOADBContainer *)oadbf->Get("TOFoadb");
    1844           0 :     if (oadbc) fTOFPIDParams = dynamic_cast<AliTOFPIDParams *>(oadbc->GetObject(fRun,"TOFparams",passName));
    1845           0 :     oadbf->Close();
    1846           0 :     delete oadbc;
    1847           0 :   } else {
    1848           0 :     AliError(Form("TOF OADB file not found!!! %s/COMMON/PID/data/TOFPIDParams.root",fOADBPath.Data()));
    1849             :   }
    1850           0 :   delete oadbf;
    1851             : 
    1852           0 :   if (!fTOFPIDParams) AliFatal("TOFPIDParams could not be retrieved");
    1853             : 
    1854           0 :   if (TString(fTOFPIDParams->GetOADBentryTag()) == "default") {
    1855           0 :     AliWarning("******* Risk for unreliable TOF PID detected *********");
    1856           0 :     if (!fIsMC && fRecoPass<=0) {
    1857           0 :       AliWarningF("        Invalid reco pass for data (%d) was detected", fRecoPass);
    1858           0 :     }
    1859           0 :     AliWarning("        The default object was loaded");
    1860           0 :   }
    1861           0 : }
    1862             : 
    1863             : //______________________________________________________________________________
    1864             : void AliPIDResponse::InitializeTOFResponse()
    1865             : {
    1866             :   //
    1867             :   // Set PID Params to the TOF PID response
    1868             :   //
    1869           0 :   AliInfo("---------------------------- TOF Response Configuration ----------------------------");
    1870           0 :   AliInfo(Form("TOF PID Params loaded from OADB [entryTag: %s]",fTOFPIDParams->GetOADBentryTag()));
    1871           0 :   AliInfo(Form("  TOF resolution %5.2f [ps]",fTOFPIDParams->GetTOFresolution()));
    1872           0 :   AliInfo(Form("  StartTime method %d",fTOFPIDParams->GetStartTimeMethod()));
    1873           0 :   AliInfo(Form("  TOF res. mom. params: %6.3f %6.3f %6.3f %6.3f",
    1874             :                fTOFPIDParams->GetSigParams(0),fTOFPIDParams->GetSigParams(1),fTOFPIDParams->GetSigParams(2),fTOFPIDParams->GetSigParams(3)));
    1875           0 :   AliInfo(Form("  Start Time Offset %6.2f ps",fTOFPIDParams->GetTOFtimeOffset()));
    1876           0 :   AliInfo(Form("  Fraction of tracks within gaussian behaviour: %6.4f",fTOFPIDParams->GetTOFtail()));
    1877             : 
    1878           0 :   if (fIsMC) {
    1879           0 :     AliInfo("MC data:");
    1880           0 :     if (fTuneMConData && ((fTuneMConDataMask & kDetTOF) == kDetTOF) ) {
    1881           0 :       AliInfo(Form("  MC: TuneOnData option enabled for TOF data (target data reco pass is %d)",fRecoPassUser));
    1882           0 :     } else AliInfo("  MC: TuneOnData option NOT enabled for TOF data");
    1883             :   }
    1884           0 :   AliInfo(Form("  MC: Fraction of tracks (percentage) to cut to fit matching in data: %6.2f%%",fTOFPIDParams->GetTOFmatchingLossMC()));
    1885           0 :   AliInfo(Form("  MC: Fraction of random hits (percentage) to add to fit mismatch in data: %6.2f%%",fTOFPIDParams->GetTOFadditionalMismForMC()));
    1886             : 
    1887           0 :   for (Int_t i=0;i<4;i++) {
    1888           0 :     fTOFResponse.SetTrackParameter(i,fTOFPIDParams->GetSigParams(i));
    1889             :   }
    1890           0 :   fTOFResponse.SetTimeResolution(fTOFPIDParams->GetTOFresolution());
    1891             : 
    1892           0 :   AliInfo("TZERO resolution loaded from ESDrun/AODheader");
    1893           0 :   Float_t t0Spread[4];
    1894           0 :   for (Int_t i=0;i<4;i++) t0Spread[i]=fCurrentEvent->GetT0spread(i);
    1895           0 :   AliInfo(Form("  TZERO spreads from data: (A+C)/2 %f A %f C %f (A'-C')/2: %f",t0Spread[0],t0Spread[1],t0Spread[2],t0Spread[3]));
    1896           0 :   Float_t a = t0Spread[1]*t0Spread[1]-t0Spread[0]*t0Spread[0]+t0Spread[3]*t0Spread[3];
    1897           0 :   Float_t c = t0Spread[2]*t0Spread[2]-t0Spread[0]*t0Spread[0]+t0Spread[3]*t0Spread[3];
    1898           0 :   if ( (t0Spread[0] > 50. && t0Spread[0] < 400.) && (a > 0.) && (c>0.)) {
    1899           0 :     fResT0AC=t0Spread[3];
    1900           0 :     fResT0A=TMath::Sqrt(a);
    1901           0 :     fResT0C=TMath::Sqrt(c);
    1902           0 :   } else {
    1903           0 :     AliInfo("  TZERO spreads not present or inconsistent, loading default");
    1904           0 :     fResT0A=75.;
    1905           0 :     fResT0C=65.;
    1906           0 :     fResT0AC=55.;
    1907             :   }
    1908           0 :   AliInfo(Form("  TZERO resolution set to: T0A: %f [ps] T0C: %f [ps] T0AC %f [ps]",fResT0A,fResT0C,fResT0AC));
    1909           0 :   AliInfo("------------------------------------------------------------------------------------");
    1910             : 
    1911           0 : }
    1912             : 
    1913             : //______________________________________________________________________________
    1914             : void AliPIDResponse::SetHMPIDPidResponseMaster()
    1915             : {
    1916             :   //
    1917             :   // Load the HMPID pid params from the OADB
    1918             :   //
    1919             : 
    1920           0 :   if (fHMPIDPIDParams) delete fHMPIDPIDParams;
    1921           0 :   fHMPIDPIDParams=NULL;
    1922             : 
    1923             :   TFile *oadbf;
    1924           0 :   if(!fIsMC) oadbf = new TFile(Form("%s/COMMON/PID/data/HMPIDPIDParams.root",fOADBPath.Data()));
    1925           0 :   else       oadbf = new TFile(Form("%s/COMMON/PID/MC/HMPIDPIDParams.root",fOADBPath.Data()));
    1926           0 :   if (oadbf && oadbf->IsOpen()) {
    1927           0 :     AliInfo(Form("Loading HMPID Params from %s/COMMON/PID/data/HMPIDPIDParams.root", fOADBPath.Data()));
    1928           0 :     AliOADBContainer *oadbc = (AliOADBContainer *)oadbf->Get("HMPoadb");
    1929           0 :     if (oadbc) fHMPIDPIDParams = dynamic_cast<AliHMPIDPIDParams *>(oadbc->GetObject(fRun,"HMPparams"));
    1930           0 :     oadbf->Close();
    1931           0 :     delete oadbc;
    1932           0 :   }
    1933           0 :   delete oadbf;
    1934             : 
    1935           0 :   if (!fHMPIDPIDParams) AliFatal("HMPIDPIDParams could not be retrieved");
    1936           0 : }
    1937             : 
    1938             : //______________________________________________________________________________
    1939             : void AliPIDResponse::InitializeHMPIDResponse(){
    1940             :   //
    1941             :   // Set PID Params to the HMPID PID response
    1942             :   //
    1943             : 
    1944           0 :   fHMPIDResponse.SetRefIndexArray(fHMPIDPIDParams->GetHMPIDrefIndex());
    1945           0 : }
    1946             : 
    1947             : //______________________________________________________________________________
    1948             : Bool_t AliPIDResponse::IdentifiedAsElectronTRD(const AliVTrack *vtrack,Double_t efficiencyLevel,Double_t centrality,AliTRDPIDResponse::ETRDPIDMethod PIDmethod) const {
    1949             :     // old function for compatibility
    1950           0 :     Int_t ntracklets=0;
    1951           0 :     return IdentifiedAsElectronTRD(vtrack,ntracklets,efficiencyLevel,centrality,PIDmethod);
    1952           0 : }
    1953             : 
    1954             : //______________________________________________________________________________
    1955             : Bool_t AliPIDResponse::IdentifiedAsElectronTRD(const AliVTrack *vtrack, Int_t &ntracklets,Double_t efficiencyLevel,Double_t centrality,AliTRDPIDResponse::ETRDPIDMethod PIDmethod) const {
    1956             :   //
    1957             :   // Check whether track is identified as electron under a given electron efficiency hypothesis
    1958             :   //
    1959             :   // ntracklets is the number of tracklets that has been used to calculate the PID signal
    1960             : 
    1961           0 :   Double_t probs[AliPID::kSPECIES];
    1962             : 
    1963           0 :   ntracklets =CalculateTRDResponse(vtrack,probs,PIDmethod);
    1964             : 
    1965             :   // Take mean of the TRD momenta in the given tracklets
    1966           0 :   Float_t p = 0, trdmomenta[AliVTrack::kTRDnPlanes];
    1967             :   Int_t nmomenta = 0;
    1968           0 :   for(Int_t iPl=0;iPl<AliVTrack::kTRDnPlanes;iPl++){
    1969           0 :     if(vtrack->GetTRDmomentum(iPl) > 0.){
    1970           0 :       trdmomenta[nmomenta++] = vtrack->GetTRDmomentum(iPl);
    1971           0 :     }
    1972             :   }
    1973           0 :   p = TMath::Mean(nmomenta, trdmomenta);
    1974             : 
    1975           0 :   return fTRDResponse.IdentifiedAsElectron(ntracklets, probs, p, efficiencyLevel,centrality,PIDmethod);
    1976           0 : }
    1977             : 
    1978             : //______________________________________________________________________________
    1979             : void AliPIDResponse::SetEMCALPidResponseMaster()
    1980             : {
    1981             :   //
    1982             :   // Load the EMCAL pid response functions from the OADB
    1983             :   //
    1984             :   TObjArray* fEMCALPIDParamsRun      = NULL;
    1985             :   TObjArray* fEMCALPIDParamsPass     = NULL;
    1986             : 
    1987           0 :   if(fEMCALPIDParams) return;
    1988           0 :   AliOADBContainer contParams("contParams");
    1989             : 
    1990           0 :   Int_t statusPars = contParams.InitFromFile(Form("%s/COMMON/PID/data/EMCALPIDParams.root", fOADBPath.Data()), "AliEMCALPIDParams");
    1991           0 :   if(statusPars){
    1992           0 :     AliError("Failed initializing PID Params from OADB");
    1993             :   }
    1994             :   else {
    1995           0 :     AliInfo(Form("Loading EMCAL Params from %s/COMMON/PID/data/EMCALPIDParams.root", fOADBPath.Data()));
    1996             : 
    1997           0 :     fEMCALPIDParamsRun = dynamic_cast<TObjArray *>(contParams.GetObject(fRun));
    1998           0 :     if(fEMCALPIDParamsRun)  fEMCALPIDParamsPass = dynamic_cast<TObjArray *>(fEMCALPIDParamsRun->FindObject(Form("pass%d",fRecoPass)));
    1999           0 :     if(fEMCALPIDParamsPass) fEMCALPIDParams     = dynamic_cast<TObjArray *>(fEMCALPIDParamsPass->FindObject(Form("EMCALPIDParams_Particles")));
    2000             : 
    2001           0 :     if(!fEMCALPIDParams){
    2002           0 :       AliInfo(Form("EMCAL Params not found in run %d pass %d", fRun, fRecoPass));
    2003           0 :       AliInfo("Will take the standard LHC11d instead ...");
    2004             : 
    2005           0 :       fEMCALPIDParamsRun = dynamic_cast<TObjArray *>(contParams.GetObject(156477));
    2006           0 :       if(fEMCALPIDParamsRun)  fEMCALPIDParamsPass = dynamic_cast<TObjArray *>(fEMCALPIDParamsRun->FindObject(Form("pass%d",1)));
    2007           0 :       if(fEMCALPIDParamsPass) fEMCALPIDParams     = dynamic_cast<TObjArray *>(fEMCALPIDParamsPass->FindObject(Form("EMCALPIDParams_Particles")));
    2008             : 
    2009           0 :       if(!fEMCALPIDParams){
    2010           0 :         AliError(Form("DEFAULT EMCAL Params (LHC11d) not found in file %s/COMMON/PID/data/EMCALPIDParams.root", fOADBPath.Data()));
    2011             :       }
    2012             :     }
    2013             :   }
    2014           0 : }
    2015             : 
    2016             : //______________________________________________________________________________
    2017             : void AliPIDResponse::InitializeEMCALResponse(){
    2018             :   //
    2019             :   // Set PID Params to the EMCAL PID response
    2020             :   //
    2021           0 :   fEMCALResponse.SetPIDParams(fEMCALPIDParams);
    2022             : 
    2023           0 : }
    2024             : 
    2025             : //______________________________________________________________________________
    2026             : void AliPIDResponse::FillTrackDetectorPID(const AliVTrack *track, EDetector detector) const
    2027             : {
    2028             :   //
    2029             :   // create detector PID information and setup the transient pointer in the track
    2030             :   //
    2031             : 
    2032             :   // check if detector number is inside accepted range
    2033           0 :   if (detector == kNdetectors) return;
    2034             : 
    2035             :   // get detector pid
    2036           0 :   AliDetectorPID *detPID=const_cast<AliDetectorPID*>(track->GetDetectorPID());
    2037           0 :   if (!detPID) {
    2038           0 :     detPID=new AliDetectorPID;
    2039           0 :     (const_cast<AliVTrack*>(track))->SetDetectorPID(detPID);
    2040           0 :   }
    2041             : 
    2042             :   //check if values exist
    2043           0 :   if (detPID->HasRawProbability(detector) && detPID->HasNumberOfSigmas(detector)) return;
    2044             : 
    2045             :   //TODO: which particles to include? See also the loops below...
    2046           0 :   Double_t values[AliPID::kSPECIESC]={0};
    2047             : 
    2048             :   //probabilities
    2049           0 :   EDetPidStatus status=GetComputePIDProbability(detector,track,AliPID::kSPECIESC,values);
    2050           0 :   detPID->SetRawProbability(detector, values, (Int_t)AliPID::kSPECIESC, status);
    2051             : 
    2052             :   //nsigmas
    2053           0 :   for (Int_t ipart=0; ipart<AliPID::kSPECIESC; ++ipart)
    2054           0 :     values[ipart]=GetNumberOfSigmas(detector,track,(AliPID::EParticleType)ipart);
    2055             :   // the pid status is the same for probabilities and nSigmas, so it is
    2056             :   // fine to use the one from the probabilities also here
    2057           0 :   detPID->SetNumberOfSigmas(detector, values, (Int_t)AliPID::kSPECIESC, status);
    2058             : 
    2059           0 : }
    2060             : 
    2061             : //______________________________________________________________________________
    2062             : void AliPIDResponse::FillTrackDetectorPID()
    2063             : {
    2064             :   //
    2065             :   // create detector PID information and setup the transient pointer in the track
    2066             :   //
    2067             : 
    2068           0 :   if (!fCurrentEvent) return;
    2069             : 
    2070           0 :   for (Int_t itrack=0; itrack<fCurrentEvent->GetNumberOfTracks(); ++itrack){
    2071           0 :     AliVTrack *track=dynamic_cast<AliVTrack*>(fCurrentEvent->GetTrack(itrack));
    2072           0 :     if (!track) continue;
    2073             : 
    2074           0 :     for (Int_t idet=0; idet<kNdetectors; ++idet){
    2075           0 :       FillTrackDetectorPID(track, (EDetector)idet);
    2076             :     }
    2077           0 :   }
    2078           0 : }
    2079             : 
    2080             : //______________________________________________________________________________
    2081             : void AliPIDResponse::SetTOFResponse(AliVEvent *vevent,EStartTimeType_t option){
    2082             :   //
    2083             :   // Set TOF response function
    2084             :   // Input option for event_time used
    2085             :   //
    2086             : 
    2087             :     Float_t t0spread = 0.; //vevent->GetEventTimeSpread();
    2088          24 :     if(t0spread < 10) t0spread = 80;
    2089             : 
    2090             :     // T0-FILL and T0-TO offset (because of TOF misallignment
    2091             :     Float_t starttimeoffset = 0;
    2092           8 :     if(fTOFPIDParams && !(fIsMC)) starttimeoffset=fTOFPIDParams->GetTOFtimeOffset();
    2093           8 :     if(fTOFPIDParams){
    2094           0 :       fTOFtail = fTOFPIDParams->GetTOFtail();
    2095           0 :       GetTOFResponse().SetTOFtail(fTOFtail);
    2096           0 :     }
    2097             : 
    2098             :     // T0 from TOF algorithm
    2099             :     Bool_t flagT0TOF=kFALSE;
    2100             :     Bool_t flagT0T0=kFALSE;
    2101           8 :     Float_t *startTime = new Float_t[fTOFResponse.GetNmomBins()];
    2102           8 :     Float_t *startTimeRes = new Float_t[fTOFResponse.GetNmomBins()];
    2103           8 :     Int_t *startTimeMask = new Int_t[fTOFResponse.GetNmomBins()];
    2104             : 
    2105             :     // T0-TOF arrays
    2106           8 :     Float_t *estimatedT0event = new Float_t[fTOFResponse.GetNmomBins()];
    2107           8 :     Float_t *estimatedT0resolution = new Float_t[fTOFResponse.GetNmomBins()];
    2108         176 :     for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2109          80 :       estimatedT0event[i]=0.0;
    2110          80 :       estimatedT0resolution[i]=0.0;
    2111          80 :       startTimeMask[i] = 0;
    2112             :     }
    2113             : 
    2114           8 :     Float_t resT0A=fResT0A;
    2115           8 :     Float_t resT0C=fResT0C;
    2116           8 :     Float_t resT0AC=fResT0AC;
    2117           8 :     if(vevent->GetT0TOF()){ // check if T0 detector information is available
    2118             :         flagT0T0=kTRUE;
    2119           8 :     }
    2120             : 
    2121             : 
    2122           8 :     AliTOFHeader *tofHeader = (AliTOFHeader*)vevent->GetTOFHeader();
    2123             : 
    2124           8 :     if (tofHeader) { // read global info and T0-TOF
    2125             :       //      fTOFResponse.SetTimeResolution(tofHeader->GetTOFResolution()); // read from OADB in the initialization
    2126           8 :       t0spread = tofHeader->GetT0spread(); // read t0 sprad
    2127           8 :       if(t0spread < 10) t0spread = 80;
    2128             : 
    2129             :       flagT0TOF=kTRUE;
    2130         176 :       for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){ // read T0-TOF default value
    2131          80 :         startTime[i]=tofHeader->GetDefaultEventTimeVal();
    2132          80 :         startTimeRes[i]=tofHeader->GetDefaultEventTimeRes();
    2133          80 :         if(startTimeRes[i] < 1.e-5) startTimeRes[i] = t0spread;
    2134             : 
    2135          80 :         if(startTimeRes[i] > t0spread - 10 && TMath::Abs(startTime[i]) < 0.001) startTime[i] = -starttimeoffset; // apply offset for T0-fill
    2136             :       }
    2137             : 
    2138           8 :       TArrayI *ibin=(TArrayI*)tofHeader->GetNvalues();
    2139           8 :       TArrayF *t0Bin=(TArrayF*)tofHeader->GetEventTimeValues();
    2140           8 :       TArrayF *t0ResBin=(TArrayF*)tofHeader->GetEventTimeRes();
    2141         102 :       for(Int_t j=0;j < tofHeader->GetNbins();j++){ // fill T0-TOF in p-bins
    2142          43 :         Int_t icurrent = (Int_t)ibin->GetAt(j);
    2143          43 :         startTime[icurrent]=t0Bin->GetAt(j);
    2144          43 :         startTimeRes[icurrent]=t0ResBin->GetAt(j);
    2145          43 :         if(startTimeRes[icurrent] < 1.e-5) startTimeRes[icurrent] = t0spread;
    2146          43 :         if(startTimeRes[icurrent] > t0spread - 10 && TMath::Abs(startTime[icurrent]) < 0.001) startTime[icurrent] = -starttimeoffset; // apply offset for T0-fill
    2147             :       }
    2148           8 :     }
    2149             : 
    2150             :     // for cut of 3 sigma on t0 spread
    2151           8 :     Float_t t0cut = 3 * t0spread;
    2152           8 :     if(t0cut < 500) t0cut = 500;
    2153             : 
    2154           8 :     if(option == kFILL_T0){ // T0-FILL is used
    2155           0 :         for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2156           0 :           estimatedT0event[i]=0.0-starttimeoffset;
    2157           0 :           estimatedT0resolution[i]=t0spread;
    2158             :         }
    2159           0 :         fTOFResponse.SetT0event(estimatedT0event);
    2160           0 :         fTOFResponse.SetT0resolution(estimatedT0resolution);
    2161           0 :     }
    2162             : 
    2163           8 :     if(option == kTOF_T0){ // T0-TOF is used when available (T0-FILL otherwise) from ESD
    2164           8 :         if(flagT0TOF){
    2165           8 :             fTOFResponse.SetT0event(startTime);
    2166           8 :             fTOFResponse.SetT0resolution(startTimeRes);
    2167         176 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2168         160 :               if(startTimeRes[i]<t0spread) startTimeMask[i]=1;
    2169          80 :               fTOFResponse.SetT0binMask(i,startTimeMask[i]);
    2170             :             }
    2171           8 :         }
    2172             :         else{
    2173           0 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2174           0 :               estimatedT0event[i]=0.0-starttimeoffset;
    2175           0 :               estimatedT0resolution[i]=t0spread;
    2176           0 :               fTOFResponse.SetT0binMask(i,startTimeMask[i]);
    2177             :             }
    2178           0 :             fTOFResponse.SetT0event(estimatedT0event);
    2179           0 :             fTOFResponse.SetT0resolution(estimatedT0resolution);
    2180             :         }
    2181             :     }
    2182           0 :     else if(option == kBest_T0){ // T0-T0 or T0-TOF are used when available (T0-FILL otherwise) from ESD
    2183             :         Float_t t0AC=-10000;
    2184             :         Float_t t0A=-10000;
    2185             :         Float_t t0C=-10000;
    2186           0 :         if(flagT0T0){
    2187           0 :             t0A= vevent->GetT0TOF()[1] - starttimeoffset;
    2188           0 :             t0C= vevent->GetT0TOF()[2] - starttimeoffset;
    2189           0 :             t0AC= vevent->GetT0TOF()[0] - starttimeoffset;
    2190             :             //t0AC= t0A/resT0A/resT0A + t0C/resT0C/resT0C;
    2191             :             //    resT0AC= 1./TMath::Sqrt(1./resT0A/resT0A + 1./resT0C/resT0C);
    2192             :             //    t0AC *= resT0AC*resT0AC;
    2193           0 :         }
    2194             : 
    2195             :         Float_t t0t0Best = 0;
    2196             :         Float_t t0t0BestRes = 9999;
    2197             :         Int_t t0used=0;
    2198           0 :         if(TMath::Abs(t0A) < t0cut && TMath::Abs(t0C) < t0cut && TMath::Abs(t0C-t0A) < 500){
    2199             :             t0t0Best = t0AC;
    2200             :             t0t0BestRes = resT0AC;
    2201             :             t0used=6;
    2202           0 :         }
    2203           0 :         else if(TMath::Abs(t0C) < t0cut){
    2204             :             t0t0Best = t0C;
    2205             :             t0t0BestRes = resT0C;
    2206             :             t0used=4;
    2207           0 :         }
    2208           0 :         else if(TMath::Abs(t0A) < t0cut){
    2209             :             t0t0Best = t0A;
    2210             :             t0t0BestRes = resT0A;
    2211             :             t0used=2;
    2212           0 :         }
    2213             : 
    2214           0 :         if(flagT0TOF){ // if T0-TOF info is available
    2215           0 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2216           0 :                 if(t0t0BestRes < 999){
    2217           0 :                   if(startTimeRes[i] < t0spread){
    2218           0 :                     Double_t wtot = 1./startTimeRes[i]/startTimeRes[i] + 1./t0t0BestRes/t0t0BestRes;
    2219           0 :                     Double_t t0best = startTime[i]/startTimeRes[i]/startTimeRes[i] + t0t0Best/t0t0BestRes/t0t0BestRes;
    2220           0 :                     estimatedT0event[i]=t0best / wtot;
    2221           0 :                     estimatedT0resolution[i]=1./TMath::Sqrt(wtot);
    2222           0 :                     startTimeMask[i] = t0used+1;
    2223           0 :                   }
    2224             :                   else {
    2225           0 :                     estimatedT0event[i]=t0t0Best;
    2226           0 :                     estimatedT0resolution[i]=t0t0BestRes;
    2227           0 :                     startTimeMask[i] = t0used;
    2228             :                   }
    2229             :                 }
    2230             :                 else{
    2231           0 :                   estimatedT0event[i]=startTime[i];
    2232           0 :                   estimatedT0resolution[i]=startTimeRes[i];
    2233           0 :                   if(startTimeRes[i]<t0spread) startTimeMask[i]=1;
    2234             :                 }
    2235           0 :                 fTOFResponse.SetT0binMask(i,startTimeMask[i]);
    2236             :             }
    2237           0 :             fTOFResponse.SetT0event(estimatedT0event);
    2238           0 :             fTOFResponse.SetT0resolution(estimatedT0resolution);
    2239           0 :         }
    2240             :         else{ // if no T0-TOF info is available
    2241           0 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2242           0 :               fTOFResponse.SetT0binMask(i,t0used);
    2243           0 :               if(t0t0BestRes < 999){
    2244           0 :                 estimatedT0event[i]=t0t0Best;
    2245           0 :                 estimatedT0resolution[i]=t0t0BestRes;
    2246           0 :               }
    2247             :               else{
    2248           0 :                 estimatedT0event[i]=0.0-starttimeoffset;
    2249           0 :                 estimatedT0resolution[i]=t0spread;
    2250             :               }
    2251             :             }
    2252           0 :             fTOFResponse.SetT0event(estimatedT0event);
    2253           0 :             fTOFResponse.SetT0resolution(estimatedT0resolution);
    2254             :         }
    2255           0 :     }
    2256             : 
    2257           0 :     else if(option == kT0_T0){ // T0-T0 is used when available (T0-FILL otherwise)
    2258             :         Float_t t0AC=-10000;
    2259             :         Float_t t0A=-10000;
    2260             :         Float_t t0C=-10000;
    2261           0 :         if(flagT0T0){
    2262           0 :             t0A= vevent->GetT0TOF()[1] - starttimeoffset;
    2263           0 :             t0C= vevent->GetT0TOF()[2] - starttimeoffset;
    2264           0 :             t0AC= vevent->GetT0TOF()[0] - starttimeoffset;
    2265             :             //    t0AC= t0A/resT0A/resT0A + t0C/resT0C/resT0C;
    2266             :             //    resT0AC= 1./TMath::Sqrt(1./resT0A/resT0A + 1./resT0C/resT0C);
    2267             :             //    t0AC *= resT0AC*resT0AC;
    2268           0 :         }
    2269             : 
    2270           0 :         if(TMath::Abs(t0A) < t0cut && TMath::Abs(t0C) < t0cut && TMath::Abs(t0C-t0A) < 500){
    2271           0 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2272           0 :               estimatedT0event[i]=t0AC;
    2273           0 :               estimatedT0resolution[i]=resT0AC;
    2274           0 :               fTOFResponse.SetT0binMask(i,6);
    2275             :             }
    2276           0 :         }
    2277           0 :         else if(TMath::Abs(t0C) < t0cut){
    2278           0 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2279           0 :               estimatedT0event[i]=t0C;
    2280           0 :               estimatedT0resolution[i]=resT0C;
    2281           0 :               fTOFResponse.SetT0binMask(i,4);
    2282             :             }
    2283           0 :         }
    2284           0 :         else if(TMath::Abs(t0A) < t0cut){
    2285           0 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2286           0 :               estimatedT0event[i]=t0A;
    2287           0 :               estimatedT0resolution[i]=resT0A;
    2288           0 :               fTOFResponse.SetT0binMask(i,2);
    2289             :             }
    2290           0 :         }
    2291             :         else{
    2292           0 :             for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
    2293           0 :               estimatedT0event[i]= 0.0 - starttimeoffset;
    2294           0 :               estimatedT0resolution[i]=t0spread;
    2295           0 :               fTOFResponse.SetT0binMask(i,0);
    2296             :             }
    2297             :         }
    2298           0 :         fTOFResponse.SetT0event(estimatedT0event);
    2299           0 :         fTOFResponse.SetT0resolution(estimatedT0resolution);
    2300           0 :     }
    2301             : 
    2302          16 :     delete [] startTime;
    2303          16 :     delete [] startTimeRes;
    2304          16 :     delete [] startTimeMask;
    2305          16 :     delete [] estimatedT0event;
    2306          16 :     delete [] estimatedT0resolution;
    2307           8 : }
    2308             : 
    2309             : //______________________________________________________________________________
    2310             : // private non cached versions of the PID calculation
    2311             : //
    2312             : 
    2313             : 
    2314             : //______________________________________________________________________________
    2315             : Float_t AliPIDResponse::GetNumberOfSigmas(EDetector detector, const AliVParticle *vtrack, AliPID::EParticleType type) const
    2316             : {
    2317             :   //
    2318             :   // NumberOfSigmas for 'detCode'
    2319             :   //
    2320             : 
    2321           0 :   const AliVTrack *track=static_cast<const AliVTrack*>(vtrack);
    2322             : 
    2323           0 :   switch (detector){
    2324           0 :     case kITS:   return GetNumberOfSigmasITS(track, type);   break;
    2325           0 :     case kTPC:   return GetNumberOfSigmasTPC(track, type);   break;
    2326           0 :     case kTRD:   return GetNumberOfSigmasTRD(track, type);   break;
    2327           0 :     case kTOF:   return GetNumberOfSigmasTOF(track, type);   break;
    2328           0 :     case kHMPID: return GetNumberOfSigmasHMPID(track, type); break;
    2329           0 :     case kEMCAL: return GetNumberOfSigmasEMCAL(track, type); break;
    2330           0 :     default: return -999.;
    2331             :   }
    2332             : 
    2333             :   return -999.;
    2334           0 : }
    2335             : 
    2336             : //______________________________________________________________________________
    2337             : Float_t AliPIDResponse::GetNumberOfSigmasITS(const AliVParticle *vtrack, AliPID::EParticleType type) const
    2338             : {
    2339             :   //
    2340             :   // Calculate the number of sigmas in the ITS
    2341             :   //
    2342             : 
    2343           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2344             : 
    2345           0 :   const EDetPidStatus pidStatus=GetITSPIDStatus(track);
    2346           0 :   if (pidStatus!=kDetPidOk) return -999.;
    2347             : 
    2348             :   // the following call is needed in order to fill the transient data member
    2349             :   // fITSsignalTuned which is used in the ITSPIDResponse to judge
    2350             :   // if using tuned on data
    2351           0 :   if (fTuneMConData && ((fTuneMConDataMask & kDetITS) == kDetITS))
    2352           0 :     GetITSsignalTunedOnData(track);
    2353             : 
    2354           0 :   return fITSResponse.GetNumberOfSigmas(track,type);
    2355           0 : }
    2356             : 
    2357             : //______________________________________________________________________________
    2358             : Float_t AliPIDResponse::GetNumberOfSigmasTPC(const AliVParticle *vtrack, AliPID::EParticleType type) const
    2359             : {
    2360             :   //
    2361             :   // Calculate the number of sigmas in the TPC
    2362             :   //
    2363             : 
    2364           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2365             : 
    2366           0 :   const EDetPidStatus pidStatus=GetTPCPIDStatus(track);
    2367           0 :   if (pidStatus==kDetNoSignal) return -999.;
    2368             : 
    2369             :   // the following call is needed in order to fill the transient data member
    2370             :   // fTPCsignalTuned which is used in the TPCPIDResponse to judge
    2371             :   // if using tuned on data
    2372           0 :   if (fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))
    2373           0 :     GetTPCsignalTunedOnData(track);
    2374             : 
    2375           0 :   return fTPCResponse.GetNumberOfSigmas(track, type, AliTPCPIDResponse::kdEdxDefault, fUseTPCEtaCorrection, fUseTPCMultiplicityCorrection);
    2376           0 : }
    2377             : 
    2378             : //______________________________________________________________________________
    2379             : Float_t AliPIDResponse::GetNumberOfSigmasTRD(const AliVParticle *vtrack, AliPID::EParticleType type) const
    2380             : {
    2381             :   //
    2382             :   // Calculate the number of sigmas in the TRD
    2383             :   //
    2384             : 
    2385           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2386             : 
    2387           0 :   const EDetPidStatus pidStatus=GetTRDPIDStatus(track);
    2388           0 :   if (pidStatus!=kDetPidOk) return -999.;
    2389             : 
    2390           0 :   return fTRDResponse.GetNumberOfSigmas(track,type, fUseTRDEtaCorrection);
    2391           0 : }
    2392             : 
    2393             : //______________________________________________________________________________
    2394             : Float_t AliPIDResponse::GetNumberOfSigmasTOF(const AliVParticle *vtrack, AliPID::EParticleType type) const
    2395             : {
    2396             :   //
    2397             :   // Calculate the number of sigmas in the TOF
    2398             :   //
    2399             : 
    2400           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2401             : 
    2402           0 :   const EDetPidStatus pidStatus=GetTOFPIDStatus(track);
    2403           0 :   if (pidStatus!=kDetPidOk) return -999.;
    2404             : 
    2405           0 :   return GetNumberOfSigmasTOFold(vtrack, type);
    2406           0 : }
    2407             : //______________________________________________________________________________
    2408             : 
    2409             : Float_t AliPIDResponse::GetNumberOfSigmasHMPID(const AliVParticle *vtrack, AliPID::EParticleType type) const
    2410             : {
    2411             :   //
    2412             :   // Calculate the number of sigmas in the HMPID
    2413             :   //
    2414           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2415             : 
    2416           0 :   const EDetPidStatus pidStatus=GetHMPIDPIDStatus(track);
    2417           0 :   if (pidStatus!=kDetPidOk) return -999.;
    2418             : 
    2419           0 :   return fHMPIDResponse.GetNumberOfSigmas(track, type);
    2420           0 : }
    2421             : 
    2422             : //______________________________________________________________________________
    2423             : Float_t AliPIDResponse::GetNumberOfSigmasEMCAL(const AliVParticle *vtrack, AliPID::EParticleType type) const
    2424             : {
    2425             :   //
    2426             :   // Calculate the number of sigmas in the EMCAL
    2427             :   //
    2428             : 
    2429           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2430             : 
    2431           0 :   const EDetPidStatus pidStatus=GetEMCALPIDStatus(track);
    2432           0 :   if (pidStatus!=kDetPidOk) return -999.;
    2433             : 
    2434           0 :   const Int_t nMatchClus = track->GetEMCALcluster();
    2435           0 :   AliVCluster *matchedClus = (AliVCluster*)fCurrentEvent->GetCaloCluster(nMatchClus);
    2436             : 
    2437           0 :   const Double_t mom    = track->P();
    2438           0 :   const Double_t pt     = track->Pt();
    2439           0 :   const Int_t    charge = track->Charge();
    2440           0 :   const Double_t fClsE  = matchedClus->E();
    2441           0 :   const Double_t EovP   = fClsE/mom;
    2442             : 
    2443           0 :   return fEMCALResponse.GetNumberOfSigmas(pt,EovP,type,charge);
    2444           0 : }
    2445             : 
    2446             : //______________________________________________________________________________
    2447             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetSignalDeltaITS(const AliVParticle *vtrack, AliPID::EParticleType type, Double_t &val, Bool_t ratio/*=kFALSE*/) const
    2448             : {
    2449             :   //
    2450             :   // Signal minus expected Signal for ITS
    2451             :   //
    2452           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2453             : 
    2454             :   // the following call is needed in order to fill the transient data member
    2455             :   // fITSsignalTuned which is used in the ITSPIDResponse to judge
    2456             :   // if using tuned on data
    2457           0 :   if (fTuneMConData && ((fTuneMConDataMask & kDetITS) == kDetITS))
    2458           0 :     GetITSsignalTunedOnData(track);
    2459             : 
    2460           0 :   val=fITSResponse.GetSignalDelta(track,type,ratio);
    2461             : 
    2462           0 :   return GetITSPIDStatus(track);
    2463             : }
    2464             : 
    2465             : //______________________________________________________________________________
    2466             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetSignalDeltaTPC(const AliVParticle *vtrack, AliPID::EParticleType type, Double_t &val, Bool_t ratio/*=kFALSE*/) const
    2467             : {
    2468             :   //
    2469             :   // Signal minus expected Signal for TPC
    2470             :   //
    2471           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2472             : 
    2473             :   // the following call is needed in order to fill the transient data member
    2474             :   // fTPCsignalTuned which is used in the TPCPIDResponse to judge
    2475             :   // if using tuned on data
    2476           0 :   if (fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC))
    2477           0 :     GetTPCsignalTunedOnData(track);
    2478             : 
    2479           0 :   val=fTPCResponse.GetSignalDelta(track, type, AliTPCPIDResponse::kdEdxDefault, fUseTPCEtaCorrection, fUseTPCMultiplicityCorrection, ratio);
    2480             : 
    2481           0 :   return GetTPCPIDStatus(track);
    2482             : }
    2483             : 
    2484             : //______________________________________________________________________________
    2485             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetSignalDeltaTRD(const AliVParticle *vtrack, AliPID::EParticleType type, Double_t &val, Bool_t ratio/*=kFALSE*/) const
    2486             : {
    2487             :   //
    2488             :   // Signal minus expected Signal for TRD
    2489             :   //
    2490           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2491           0 :   val=fTRDResponse.GetSignalDelta(track,type,ratio,fUseTRDEtaCorrection);
    2492             : 
    2493           0 :   return GetTRDPIDStatus(track);
    2494             : }
    2495             : 
    2496             : //______________________________________________________________________________
    2497             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetSignalDeltaTOF(const AliVParticle *vtrack, AliPID::EParticleType type, Double_t &val, Bool_t ratio/*=kFALSE*/) const
    2498             : {
    2499             :   //
    2500             :   // Signal minus expected Signal for TOF
    2501             :   //
    2502           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2503           0 :   val=GetSignalDeltaTOFold(track, type, ratio);
    2504             : 
    2505           0 :   return GetTOFPIDStatus(track);
    2506             : }
    2507             : 
    2508             : //______________________________________________________________________________
    2509             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetSignalDeltaHMPID(const AliVParticle *vtrack, AliPID::EParticleType type, Double_t &val, Bool_t ratio/*=kFALSE*/) const
    2510             : {
    2511             :   //
    2512             :   // Signal minus expected Signal for HMPID
    2513             :   //
    2514           0 :   AliVTrack *track=(AliVTrack*)vtrack;
    2515           0 :   val=fHMPIDResponse.GetSignalDelta(track, type, ratio);
    2516             : 
    2517           0 :   return GetHMPIDPIDStatus(track);
    2518             : }
    2519             : 
    2520             : //______________________________________________________________________________
    2521             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputePIDProbability  (EDetector detCode,  const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
    2522             : {
    2523             :   //
    2524             :   // Compute PID response of 'detCode'
    2525             :   //
    2526             : 
    2527         576 :   switch (detCode){
    2528           0 :     case kITS: return GetComputeITSProbability(track, nSpecies, p); break;
    2529         288 :     case kTPC: return GetComputeTPCProbability(track, nSpecies, p); break;
    2530           0 :     case kTRD: return GetComputeTRDProbability(track, nSpecies, p); break;
    2531           0 :     case kTOF: return GetComputeTOFProbability(track, nSpecies, p); break;
    2532           0 :     case kPHOS: return GetComputePHOSProbability(track, nSpecies, p); break;
    2533           0 :     case kEMCAL: return GetComputeEMCALProbability(track, nSpecies, p); break;
    2534           0 :     case kHMPID: return GetComputeHMPIDProbability(track, nSpecies, p); break;
    2535           0 :     default: return kDetNoSignal;
    2536             :   }
    2537         288 : }
    2538             : 
    2539             : //______________________________________________________________________________
    2540             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeITSProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
    2541             : {
    2542             :   //
    2543             :   // Compute PID response for the ITS
    2544             :   //
    2545             : 
    2546             :   // set flat distribution (no decision)
    2547           0 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2548             : 
    2549           0 :   const EDetPidStatus pidStatus=GetITSPIDStatus(track);
    2550           0 :   if (pidStatus!=kDetPidOk) return pidStatus;
    2551             : 
    2552           0 :   if (track->GetDetectorPID()){
    2553           0 :     return track->GetDetectorPID()->GetRawProbability(kITS, p, nSpecies);
    2554             :   }
    2555             : 
    2556             :   //check for ITS standalone tracks
    2557             :   Bool_t isSA=kTRUE;
    2558           0 :   if( track->GetStatus() & AliVTrack::kTPCin ) isSA=kFALSE;
    2559             : 
    2560           0 :   Double_t mom=track->P();
    2561           0 :   Double_t dedx=track->GetITSsignal();
    2562           0 :   if (fTuneMConData && ((fTuneMConDataMask & kDetITS) == kDetITS)) dedx = GetITSsignalTunedOnData(track);
    2563             : 
    2564             :   Double_t momITS=mom;
    2565           0 :   UChar_t clumap=track->GetITSClusterMap();
    2566             :   Int_t nPointsForPid=0;
    2567           0 :   for(Int_t i=2; i<6; i++){
    2568           0 :     if(clumap&(1<<i)) ++nPointsForPid;
    2569             :   }
    2570             : 
    2571             :   Bool_t mismatch=kTRUE/*, heavy=kTRUE*/;
    2572           0 :   for (Int_t j=0; j<nSpecies; j++) {
    2573           0 :     const Double_t chargeFactor = TMath::Power(AliPID::ParticleCharge(j),2.);
    2574             :     //TODO: in case of the electron, use the SA parametrisation,
    2575             :     //      this needs to be changed if ITS provides a parametrisation
    2576             :     //      for electrons also for ITS+TPC tracks
    2577           0 :     Double_t bethe=fITSResponse.Bethe(momITS,(AliPID::EParticleType)j,isSA || (j==(Int_t)AliPID::kElectron))*chargeFactor;
    2578           0 :     Double_t sigma=fITSResponse.GetResolution(bethe,nPointsForPid,isSA || (j==(Int_t)AliPID::kElectron));
    2579           0 :     Double_t nSigma=fITSResponse.GetNumberOfSigmas(track, (AliPID::EParticleType)j);
    2580           0 :     if (TMath::Abs(nSigma) > fRange) {
    2581           0 :       p[j]=TMath::Exp(-0.5*fRange*fRange)/sigma;
    2582           0 :     } else {
    2583           0 :       p[j]=TMath::Exp(-0.5*nSigma*nSigma)/sigma;
    2584             :       mismatch=kFALSE;
    2585             :     }
    2586             :   }
    2587             : 
    2588           0 :   if (mismatch){
    2589           0 :     for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2590           0 :   }
    2591             : 
    2592             :   return kDetPidOk;
    2593           0 : }
    2594             : //______________________________________________________________________________
    2595             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeTPCProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
    2596             : {
    2597             :   //
    2598             :   // Compute PID response for the TPC
    2599             :   //
    2600             : 
    2601             :   // set flat distribution (no decision)
    2602        6048 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2603             : 
    2604         288 :   const EDetPidStatus pidStatus=GetTPCPIDStatus(track);
    2605         442 :   if (pidStatus==kDetNoSignal) return pidStatus;
    2606             : 
    2607         134 :   Double_t dedx=track->GetTPCsignal();
    2608             :   Bool_t mismatch=kTRUE/*, heavy=kTRUE*/;
    2609             : 
    2610         134 :   if (fTuneMConData && ((fTuneMConDataMask & kDetTPC) == kDetTPC)) dedx = GetTPCsignalTunedOnData(track);
    2611             : 
    2612             :   Double_t bethe = 0.;
    2613             :   Double_t sigma = 0.;
    2614             : 
    2615        2680 :   for (Int_t j=0; j<nSpecies; j++) {
    2616             :     AliPID::EParticleType type=AliPID::EParticleType(j);
    2617             : 
    2618        1206 :     bethe=fTPCResponse.GetExpectedSignal(track, type, AliTPCPIDResponse::kdEdxDefault, fUseTPCEtaCorrection, fUseTPCMultiplicityCorrection);
    2619        1206 :     sigma=fTPCResponse.GetExpectedSigma(track, type, AliTPCPIDResponse::kdEdxDefault, fUseTPCEtaCorrection, fUseTPCMultiplicityCorrection);
    2620             : 
    2621        1206 :     if (TMath::Abs(dedx-bethe) > fRange*sigma) {
    2622         710 :       p[j]=TMath::Exp(-0.5*fRange*fRange)/sigma;
    2623         710 :     } else {
    2624         496 :       p[j]=TMath::Exp(-0.5*(dedx-bethe)*(dedx-bethe)/(sigma*sigma))/sigma;
    2625             :       mismatch=kFALSE;
    2626             :     }
    2627             :   }
    2628             : 
    2629         134 :   if (mismatch){
    2630           0 :     for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2631           0 :   }
    2632             : 
    2633             :   return pidStatus;
    2634         288 : }
    2635             : //______________________________________________________________________________
    2636             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeTOFProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[],Bool_t kNoMism) const
    2637             : {
    2638             :   //
    2639             :   // Compute PID probabilities for TOF
    2640             :   //
    2641             : 
    2642           0 :   fgTOFmismatchProb = 1E-8;
    2643             : 
    2644             :   // centrality --> fCurrCentrality
    2645             :   // Beam type --> fBeamTypeNum
    2646             :   // N TOF cluster --> TOF header --> to get the TOF header we need to add a virtual method in AliVTrack extended to ESD and AOD tracks
    2647             :   // isMC --> fIsMC
    2648           0 :   Float_t pt = track->Pt();
    2649           0 :   Float_t mismPropagationFactor[10] = {1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};
    2650           0 :   if(! (kNoMism | fNoTOFmism)){ // this flag allows to disable mismatch for iterative procedure to get priors
    2651           0 :     mismPropagationFactor[3] = 1 + TMath::Exp(1 - 1.12*pt);// it has to be alligned with the one in AliPIDCombined
    2652           0 :     mismPropagationFactor[4] = 1 + 1./(4.71114 - 5.72372*pt + 2.94715*pt*pt);// it has to be alligned with the one in AliPIDCombined
    2653             : 
    2654             :   Int_t nTOFcluster = 0;
    2655           0 :   if(track->GetTOFHeader() && track->GetTOFHeader()->GetTriggerMask() && track->GetTOFHeader()->GetNumberOfTOFclusters() > -1){ // N TOF clusters available
    2656           0 :     nTOFcluster = track->GetTOFHeader()->GetNumberOfTOFclusters();
    2657           0 :     if(fIsMC) nTOFcluster = Int_t(nTOFcluster * 1.5); // +50% in MC
    2658             :   }
    2659             :   else{
    2660           0 :     switch(fBeamTypeNum){
    2661             :       case kPP: // pp
    2662             :         nTOFcluster = 80;
    2663           0 :         break;
    2664             :       case kPPB: // pPb 5.05 ATeV
    2665           0 :         nTOFcluster = Int_t(308 - 2.12*fCurrCentrality + TMath::Exp(4.917 -0.1604*fCurrCentrality));
    2666           0 :         break;
    2667             :       case kPBPB: // PbPb 2.76 ATeV
    2668           0 :         nTOFcluster = Int_t(TMath::Exp(9.4 - 0.022*fCurrCentrality));
    2669           0 :         break;
    2670             :     }
    2671             :   }
    2672             : 
    2673           0 :     switch(fBeamTypeNum){ // matching window factors for 3 cm and 10 cm (about (10/3)^2)
    2674             :     case kPP: // pp 7 TeV
    2675           0 :       nTOFcluster *= 10;
    2676           0 :       break;
    2677             :     case kPPB: // pPb 5.05 ATeV
    2678           0 :       nTOFcluster *= 10;
    2679           0 :       break;
    2680             :     case kPBPB: // pPb 5.05 ATeV
    2681             :       //       nTOFcluster *= 1;
    2682             :       break;
    2683             :     }
    2684             : 
    2685           0 :     if(nTOFcluster < 0) nTOFcluster = 10;
    2686             : 
    2687             : 
    2688           0 :     fgTOFmismatchProb=fTOFResponse.GetMismatchProbability(track->GetTOFsignal(),track->Eta()) * nTOFcluster *6E-6 * (1 + 2.90505e-01/pt/pt); // mism weight * tof occupancy (including matching window factor) * pt dependence
    2689             : 
    2690           0 :   }
    2691             : 
    2692             :   // set flat distribution (no decision)
    2693           0 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2694             : 
    2695           0 :   const EDetPidStatus pidStatus=GetTOFPIDStatus(track);
    2696           0 :   if (pidStatus!=kDetPidOk) return pidStatus;
    2697             : 
    2698           0 :   const Double_t meanCorrFactor = 0.07/fTOFtail; // Correction factor on the mean because of the tail (should be ~ 0.1 with tail = 1.1)
    2699             : 
    2700           0 :   for (Int_t j=0; j<nSpecies; j++) {
    2701             :     AliPID::EParticleType type=AliPID::EParticleType(j);
    2702           0 :     const Double_t nsigmas=GetNumberOfSigmasTOFold(track,type) + meanCorrFactor;
    2703             : 
    2704           0 :     const Double_t expTime = fTOFResponse.GetExpectedSignal(track,type);
    2705           0 :     const Double_t sig     = fTOFResponse.GetExpectedSigma(track->P(),expTime,AliPID::ParticleMassZ(type));
    2706             : 
    2707           0 :     if(nsigmas < fTOFtail)
    2708           0 :       p[j] = TMath::Exp(-0.5*nsigmas*nsigmas)/sig;
    2709             :     else
    2710           0 :       p[j] = TMath::Exp(-(nsigmas - fTOFtail*0.5)*fTOFtail)/sig;
    2711             : 
    2712           0 :     p[j] += fgTOFmismatchProb*mismPropagationFactor[j];
    2713             :   }
    2714             : 
    2715             :   return kDetPidOk;
    2716           0 : }
    2717             : 
    2718             : Int_t AliPIDResponse::CalculateTRDResponse(const AliVTrack *track,Double_t p[],AliTRDPIDResponse::ETRDPIDMethod PIDmethod) const
    2719             : {
    2720             :     // new function for backward compatibility
    2721             :     // returns number of tracklets PID
    2722             : 
    2723           0 :     UInt_t TRDslicesForPID[2];
    2724           0 :     SetTRDSlices(TRDslicesForPID,PIDmethod);
    2725             : 
    2726           0 :     Float_t mom[6]={0.};
    2727           0 :     Double_t dedx[48]={0.};  // Allocate space for the maximum number of TRD slices
    2728           0 :     Int_t nslices = TRDslicesForPID[1] - TRDslicesForPID[0] + 1;
    2729           0 :     for(UInt_t ilayer = 0; ilayer < 6; ilayer++){
    2730           0 :         mom[ilayer] = track->GetTRDmomentum(ilayer);
    2731           0 :         for(UInt_t islice = TRDslicesForPID[0]; islice <= TRDslicesForPID[1]; islice++){
    2732             :             // do not consider tracklets with no momentum (should be non functioning chambers)
    2733           0 :             if(mom[ilayer]>0) dedx[ilayer*nslices+islice-TRDslicesForPID[0]] = track->GetTRDslice(ilayer, islice);
    2734             :         }
    2735             :     }
    2736             : 
    2737           0 :     return fTRDResponse.GetResponse(nslices, dedx, mom, p,PIDmethod);
    2738             : 
    2739           0 : }
    2740             : //______________________________________________________________________________
    2741             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeTRDProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[],AliTRDPIDResponse::ETRDPIDMethod PIDmethod) const
    2742             : {
    2743             :   //
    2744             :   // Compute PID probabilities for the TRD
    2745             :   //
    2746             : 
    2747             :   // set flat distribution (no decision)
    2748           0 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2749           0 :   const EDetPidStatus pidStatus=GetTRDPIDStatus(track);
    2750           0 :   if (pidStatus!=kDetPidOk) return pidStatus;
    2751             : 
    2752           0 :   CalculateTRDResponse(track,p,PIDmethod);
    2753             : 
    2754           0 :   return kDetPidOk;
    2755           0 : }
    2756             : 
    2757             : //______________________________________________________________________________
    2758             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeEMCALProbability  (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
    2759             : {
    2760             :   //
    2761             :   // Compute PID response for the EMCAL
    2762             :   //
    2763             : 
    2764           0 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2765             : 
    2766           0 :   const EDetPidStatus pidStatus=GetEMCALPIDStatus(track);
    2767           0 :   if (pidStatus!=kDetPidOk) return pidStatus;
    2768             : 
    2769           0 :   const Int_t nMatchClus = track->GetEMCALcluster();
    2770           0 :   AliVCluster *matchedClus = (AliVCluster*)fCurrentEvent->GetCaloCluster(nMatchClus);
    2771             : 
    2772           0 :   const Double_t mom    = track->P();
    2773           0 :   const Double_t pt     = track->Pt();
    2774           0 :   const Int_t    charge = track->Charge();
    2775           0 :   const Double_t fClsE  = matchedClus->E();
    2776           0 :   const Double_t EovP   = fClsE/mom;
    2777             : 
    2778             :   // compute the probabilities
    2779           0 :   fEMCALResponse.ComputeEMCALProbability(nSpecies,pt,EovP,charge,p);
    2780             :   return kDetPidOk;
    2781           0 : }
    2782             : 
    2783             : //______________________________________________________________________________
    2784             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputePHOSProbability (const AliVTrack */*track*/, Int_t nSpecies, Double_t p[]) const
    2785             : {
    2786             :   //
    2787             :   // Compute PID response for the PHOS
    2788             :   //
    2789             : 
    2790             :   // set flat distribution (no decision)
    2791           0 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2792           0 :   return kDetNoSignal;
    2793             : }
    2794             : 
    2795             : //______________________________________________________________________________
    2796             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeHMPIDProbability(const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
    2797             : {
    2798             :   //
    2799             :   // Compute PID response for the HMPID
    2800             :   //
    2801             : 
    2802             :   // set flat distribution (no decision)
    2803           0 :   for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
    2804             : 
    2805           0 :   const EDetPidStatus pidStatus=GetHMPIDPIDStatus(track);
    2806           0 :   if (pidStatus!=kDetPidOk) return pidStatus;
    2807             : 
    2808           0 :   fHMPIDResponse.GetProbability(track,nSpecies,p);
    2809             : 
    2810           0 :   return kDetPidOk;
    2811           0 : }
    2812             : 
    2813             : //______________________________________________________________________________
    2814             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetITSPIDStatus(const AliVTrack *track) const
    2815             : {
    2816             :   // compute ITS pid status
    2817             : 
    2818             :   // check status bits
    2819           0 :   if ((track->GetStatus()&AliVTrack::kITSin)==0 &&
    2820           0 :     (track->GetStatus()&AliVTrack::kITSout)==0) return kDetNoSignal;
    2821             : 
    2822           0 :   const Float_t dEdx=track->GetITSsignal();
    2823           0 :   if (dEdx<=0) return kDetNoSignal;
    2824             : 
    2825             :   // requite at least 3 pid clusters
    2826           0 :   const UChar_t clumap=track->GetITSClusterMap();
    2827             :   Int_t nPointsForPid=0;
    2828           0 :   for(Int_t i=2; i<6; i++){
    2829           0 :     if(clumap&(1<<i)) ++nPointsForPid;
    2830             :   }
    2831             : 
    2832           0 :   if(nPointsForPid<3) {
    2833           0 :     return kDetNoSignal;
    2834             :   }
    2835             : 
    2836           0 :   return kDetPidOk;
    2837           0 : }
    2838             : 
    2839             : //______________________________________________________________________________
    2840             : AliPIDResponse::EDetPidStatus AliPIDResponse:: GetTPCPIDStatus(const AliVTrack *track) const
    2841             : {
    2842             :   // compute TPC pid status
    2843             : 
    2844             :   // check quality of the track
    2845         608 :   if ( (track->GetStatus()&AliVTrack::kTPCin )==0 && (track->GetStatus()&AliVTrack::kTPCout)==0 ) return kDetNoSignal;
    2846             : 
    2847             :   // check pid values
    2848         272 :   const Double_t dedx=track->GetTPCsignal();
    2849         272 :   const UShort_t signalN=track->GetTPCsignalN();
    2850         410 :   if (signalN<10 || dedx<10) return kDetNoSignal;
    2851             : 
    2852         268 :   if (!fTPCResponse.GetResponseFunction(AliPID::kPion)) return kDetNoParams;
    2853             : 
    2854           0 :   return kDetPidOk;
    2855         288 : }
    2856             : 
    2857             : //______________________________________________________________________________
    2858             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetTRDPIDStatus(const AliVTrack *track) const
    2859             : {
    2860             :   // compute TRD pid status
    2861             : 
    2862           0 :   if((track->GetStatus()&AliVTrack::kTRDout)==0) return kDetNoSignal;
    2863           0 :   return kDetPidOk;
    2864           0 : }
    2865             : 
    2866             : //______________________________________________________________________________
    2867             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetTOFPIDStatus(const AliVTrack *track) const
    2868             : {
    2869             :   // compute TOF pid status
    2870             : 
    2871           0 :   if ((track->GetStatus()&AliVTrack::kTOFout)==0) return kDetNoSignal;
    2872           0 :   if ((track->GetStatus()&AliVTrack::kTIME)==0) return kDetNoSignal;
    2873             : 
    2874           0 :   return kDetPidOk;
    2875           0 : }
    2876             : 
    2877             : //______________________________________________________________________________
    2878             : Float_t AliPIDResponse::GetTOFMismatchProbability(const AliVTrack *track) const
    2879             : {
    2880             :   // compute mismatch probability cross-checking at 5 sigmas with TPC
    2881             :   // currently just implemented as a 5 sigma compatibility cut
    2882             : 
    2883           0 :   if(!track) return fgTOFmismatchProb;
    2884             : 
    2885             :   // check pid status
    2886           0 :   const EDetPidStatus tofStatus=GetTOFPIDStatus(track);
    2887           0 :   if (tofStatus!=kDetPidOk) return 0.;
    2888             : 
    2889             :   //mismatch
    2890           0 :   const EDetPidStatus tpcStatus=GetTPCPIDStatus(track);
    2891           0 :   if (tpcStatus==kDetNoSignal) return 0.;
    2892             : 
    2893           0 :   const Double_t meanCorrFactor = 0.11/fTOFtail; // Correction factor on the mean because of the tail (should be ~ 0.1 with tail = 1.1)
    2894             :   Bool_t mismatch = kTRUE/*, heavy = kTRUE*/;
    2895           0 :   for (Int_t j=0; j<AliPID::kSPECIESC; j++) {
    2896             :     AliPID::EParticleType type=AliPID::EParticleType(j);
    2897           0 :     const Double_t nsigmas=GetNumberOfSigmasTOFold(track,type) + meanCorrFactor;
    2898             : 
    2899           0 :     if (TMath::Abs(nsigmas)<5.){
    2900           0 :       const Double_t nsigmasTPC=GetNumberOfSigmasTPC(track,type);
    2901           0 :       if (TMath::Abs(nsigmasTPC)<5.) mismatch=kFALSE;
    2902           0 :     }
    2903             :   }
    2904             : 
    2905           0 :   if (mismatch){
    2906           0 :     return 1.;
    2907             :   }
    2908             : 
    2909           0 :   return 0.;
    2910           0 : }
    2911             : 
    2912             : //______________________________________________________________________________
    2913             : AliPIDResponse::EDetPidStatus AliPIDResponse:: GetHMPIDPIDStatus(const AliVTrack *track) const
    2914             : {
    2915             :   // compute HMPID pid status
    2916             : 
    2917           0 :   Int_t ch = track->GetHMPIDcluIdx()/1000000;
    2918           0 :   Double_t HMPIDsignal = track->GetHMPIDsignal();
    2919             : 
    2920           0 :   if((track->GetStatus()&AliVTrack::kHMPIDpid)==0 || ch<0 || ch>6 || HMPIDsignal<0) return kDetNoSignal;
    2921             : 
    2922           0 :   return kDetPidOk;
    2923           0 : }
    2924             : 
    2925             : //______________________________________________________________________________
    2926             : AliPIDResponse::EDetPidStatus AliPIDResponse:: GetPHOSPIDStatus(const AliVTrack */*track*/) const
    2927             : {
    2928             :   // compute PHOS pid status
    2929           0 :   return kDetNoSignal;
    2930             : }
    2931             : 
    2932             : //______________________________________________________________________________
    2933             : AliPIDResponse::EDetPidStatus AliPIDResponse:: GetEMCALPIDStatus(const AliVTrack *track) const
    2934             : {
    2935             :   // compute EMCAL pid status
    2936             : 
    2937             : 
    2938             :   // Track matching
    2939           0 :   const Int_t nMatchClus = track->GetEMCALcluster();
    2940           0 :   if (nMatchClus<0) return kDetNoSignal;
    2941             : 
    2942           0 :   AliVCluster *matchedClus = (AliVCluster*)fCurrentEvent->GetCaloCluster(nMatchClus);
    2943             : 
    2944           0 :   if (!(matchedClus && matchedClus->IsEMCAL())) return kDetNoSignal;
    2945             : 
    2946           0 :   const Int_t charge = track->Charge();
    2947           0 :   if (TMath::Abs(charge)!=1) return kDetNoSignal;
    2948             : 
    2949           0 :   if (!(fEMCALPIDParams && fEMCALPIDParams->At(AliPID::kElectron))) return kDetNoParams;
    2950             : 
    2951           0 :   return kDetPidOk;
    2952             : 
    2953           0 : }
    2954             : 
    2955             : //______________________________________________________________________________
    2956             : AliPIDResponse::EDetPidStatus AliPIDResponse::GetPIDStatus(EDetector detector, const AliVTrack *track) const
    2957             : {
    2958             :   //
    2959             :   // check pid status for a track
    2960             :   //
    2961             : 
    2962           0 :   switch (detector){
    2963           0 :     case kITS:   return GetITSPIDStatus(track);   break;
    2964           0 :     case kTPC:   return GetTPCPIDStatus(track);   break;
    2965           0 :     case kTRD:   return GetTRDPIDStatus(track);   break;
    2966           0 :     case kTOF:   return GetTOFPIDStatus(track);   break;
    2967           0 :     case kPHOS:  return GetPHOSPIDStatus(track);  break;
    2968           0 :     case kEMCAL: return GetEMCALPIDStatus(track); break;
    2969           0 :     case kHMPID: return GetHMPIDPIDStatus(track); break;
    2970           0 :     default: return kDetNoSignal;
    2971             :   }
    2972             :   return kDetNoSignal;
    2973             : 
    2974           0 : }
    2975             : 
    2976             : //_________________________________________________________________________
    2977             : Float_t AliPIDResponse::GetITSsignalTunedOnData(const AliVTrack *t) const
    2978             : {
    2979             :   /// Create gaussian signal response based on the dE/dx response observed in data
    2980             :   /// Currently only for deuterons and triton. The other particles are fine in MC
    2981             : 
    2982           0 :   Float_t dedx = t->GetITSsignalTunedOnData();
    2983           0 :   if(dedx > 0) return dedx;
    2984             : 
    2985           0 :   dedx = t->GetITSsignal();
    2986           0 :   ((AliVTrack*)t)->SetITSsignalTunedOnData(dedx);
    2987           0 :   if(dedx < 20) return dedx;
    2988             : 
    2989             :   Int_t nITSpid = 0;
    2990           0 :   for(Int_t i=2; i<6; i++){
    2991           0 :     if(t->HasPointOnITSLayer(i)) nITSpid++;
    2992             :   }
    2993             : 
    2994             :   Bool_t isSA=kTRUE;
    2995           0 :   if( t->GetStatus() & AliVTrack::kTPCin ) isSA=kFALSE;
    2996             : 
    2997             :   // check if we have MC information
    2998           0 :   if (!fCurrentMCEvent) {
    2999           0 :     AliError("Tune On Data requested, but MC event not set. Call 'SetCurrentMCEvent' before!");
    3000           0 :     return dedx;
    3001             :   }
    3002             : 
    3003             :   // get MC particle
    3004           0 :   AliVParticle *mcPart = fCurrentMCEvent->GetTrack(TMath::Abs(t->GetLabel()));
    3005             : 
    3006           0 :   if (mcPart != NULL) { // protect against label-0 track (initial proton in Pythia events)
    3007             :     AliPID::EParticleType type = AliPID::kPion;
    3008             :     Bool_t kGood = kFALSE;
    3009           0 :     Int_t iS = TMath::Abs(mcPart->PdgCode());
    3010             : 
    3011           0 :     for (Int_t ipart=0; ipart<AliPID::kSPECIESC; ++ipart) {
    3012           0 :       if (iS == AliPID::ParticleCode(ipart)) {
    3013             :         type = static_cast<AliPID::EParticleType>(ipart);
    3014             :         kGood=kTRUE;
    3015           0 :         break;
    3016             :       }
    3017             :     }
    3018             : 
    3019             :     // NOTE: currently only tune for deuterons and triton
    3020           0 :     if(kGood && (iS == AliPID::ParticleCode(AliPID::kDeuteron) || (iS == AliPID::ParticleCode(AliPID::kTriton))) ) {
    3021           0 :       Double_t bethe = fITSResponse.Bethe(t->P(),type,isSA);
    3022           0 :       Double_t sigma = fITSResponse.GetResolution(bethe,nITSpid,isSA,t->P(),type);
    3023           0 :       dedx = gRandom->Gaus(bethe,sigma);
    3024           0 :     }
    3025           0 :   }
    3026             : 
    3027           0 :   const_cast<AliVTrack*>(t)->SetITSsignalTunedOnData(dedx);
    3028             :   return dedx;
    3029           0 : }
    3030             : 
    3031             : //_________________________________________________________________________
    3032             : Float_t AliPIDResponse::GetTPCsignalTunedOnData(const AliVTrack *t) const
    3033             : {
    3034             :   /// Create gaussian signal response based on the dE/dx response observed in data
    3035             : 
    3036           0 :   Float_t dedx = t->GetTPCsignalTunedOnData();
    3037             : 
    3038           0 :   if(dedx > 0) return dedx;
    3039             : 
    3040           0 :   dedx = t->GetTPCsignal();
    3041           0 :   ((AliVTrack*)t)->SetTPCsignalTunedOnData(dedx);
    3042           0 :   if(dedx < 20) return dedx;
    3043             : 
    3044             :   // check if we have MC information
    3045           0 :   if (!fCurrentMCEvent) {
    3046           0 :     AliError("Tune On Data requested, but MC event not set. Call 'SetCurrentMCEvent' before!");
    3047           0 :     return dedx;
    3048             :   }
    3049             : 
    3050             :   // get MC particle
    3051           0 :   AliVParticle *mcPart = fCurrentMCEvent->GetTrack(TMath::Abs(t->GetLabel()));
    3052             : 
    3053           0 :   if (mcPart != NULL) { // protect against label-0 track (initial proton in Pythia events)
    3054             :     AliPID::EParticleType type = AliPID::kPion;
    3055             :     Bool_t kGood = kFALSE;
    3056           0 :     Int_t iS = TMath::Abs(mcPart->PdgCode());
    3057             : 
    3058           0 :     for (Int_t ipart=0; ipart<AliPID::kSPECIESC; ++ipart) {
    3059           0 :       if (iS == AliPID::ParticleCode(ipart)) {
    3060             :         type = static_cast<AliPID::EParticleType>(ipart);
    3061             :         kGood=kTRUE;
    3062           0 :         break;
    3063             :       }
    3064             :     }
    3065             : 
    3066           0 :     if(kGood){
    3067             :       //TODO maybe introduce different dEdxSources?
    3068           0 :       Double_t bethe = fTPCResponse.GetExpectedSignal(t, type, AliTPCPIDResponse::kdEdxDefault, UseTPCEtaCorrection(),
    3069           0 :                                                       UseTPCMultiplicityCorrection());
    3070           0 :       Double_t sigma = fTPCResponse.GetExpectedSigma(t, type, AliTPCPIDResponse::kdEdxDefault, UseTPCEtaCorrection(),
    3071           0 :                                                      UseTPCMultiplicityCorrection());
    3072           0 :       dedx = gRandom->Gaus(bethe,sigma);
    3073             :       //              if(iS == AliPID::ParticleCode(AliPID::kHe3) || iS == AliPID::ParticleCode(AliPID::kAlpha)) dedx *= 5;
    3074           0 :     }
    3075           0 :   }
    3076             : 
    3077           0 :   const_cast<AliVTrack*>(t)->SetTPCsignalTunedOnData(dedx);
    3078             :   return dedx;
    3079           0 : }
    3080             : 
    3081             : //_________________________________________________________________________
    3082             : Float_t AliPIDResponse::GetTOFsignalTunedOnData(const AliVTrack *t) const
    3083             : {
    3084             :   /// Calculate the TOF signal tuned on data by adding a tail
    3085           0 :   Double_t tofSignal = t->GetTOFsignalTunedOnData();
    3086             : 
    3087           0 :   if(tofSignal <  99999) return (Float_t)tofSignal; // it has been already set
    3088             : 
    3089             :   // read additional mismatch fraction
    3090           0 :   Float_t addmism = GetTOFPIDParams()->GetTOFadditionalMismForMC();
    3091           0 :   if(addmism > 1.){
    3092           0 :     Float_t centr = GetCurrentCentrality();
    3093           0 :     if(centr > 50) addmism *= 0.1667;
    3094           0 :     else if(centr > 20) addmism *= 0.33;
    3095           0 :   }
    3096             : 
    3097           0 :   tofSignal = t->GetTOFsignal() + fTOFResponse.GetTailRandomValue(t->Pt(),t->Eta(),t->GetTOFsignal(),addmism);
    3098           0 :   const_cast<AliVTrack*>(t)->SetTOFsignalTunedOnData(tofSignal);
    3099           0 :   return (Float_t)tofSignal;
    3100           0 : }

Generated by: LCOV version 1.11