1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 /* $Id: AliPIDResponse.cxx 46193 2010-12-21 09:00:14Z wiechula $ */
18 //-----------------------------------------------------------------
19 // Base class for handling the pid response //
20 // functions of all detectors //
21 // and give access to the nsigmas //
23 // Origin: Jens Wiechula, Uni Tuebingen, jens.wiechula@cern.ch //
24 //-----------------------------------------------------------------
27 #include <TObjArray.h>
35 #include <AliVEvent.h>
36 #include <AliVTrack.h>
39 #include <AliOADBContainer.h>
40 #include <AliTRDPIDResponseObject.h>
41 #include <AliTOFPIDParams.h>
43 #include "AliPIDResponse.h"
44 #include "AliDetectorPID.h"
46 #include "AliCentrality.h"
48 ClassImp(AliPIDResponse);
50 AliPIDResponse::AliPIDResponse(Bool_t isMC/*=kFALSE*/) :
51 TNamed("PIDResponse","PIDResponse"),
58 fITSPIDmethod(kITSTruncMean),
62 fCustomTPCpidResponse(),
75 fArrPidResponseMaster(NULL),
76 fResolutionCorrection(NULL),
77 fOADBvoltageMaps(NULL),
78 fTRDPIDResponseObject(NULL),
81 fEMCALPIDParams(NULL),
89 AliLog::SetClassDebugLevel("AliPIDResponse",0);
90 AliLog::SetClassDebugLevel("AliESDpid",0);
91 AliLog::SetClassDebugLevel("AliAODpidUtil",0);
95 //______________________________________________________________________________
96 AliPIDResponse::~AliPIDResponse()
101 delete fArrPidResponseMaster;
102 delete fTRDPIDResponseObject;
103 delete fTOFPIDParams;
106 //______________________________________________________________________________
107 AliPIDResponse::AliPIDResponse(const AliPIDResponse &other) :
109 fITSResponse(other.fITSResponse),
110 fTPCResponse(other.fTPCResponse),
111 fTRDResponse(other.fTRDResponse),
112 fTOFResponse(other.fTOFResponse),
113 fEMCALResponse(other.fEMCALResponse),
114 fRange(other.fRange),
115 fITSPIDmethod(other.fITSPIDmethod),
117 fCachePID(other.fCachePID),
118 fOADBPath(other.fOADBPath),
119 fCustomTPCpidResponse(other.fCustomTPCpidResponse),
123 fMCperiodUser(other.fMCperiodUser),
126 fRecoPassUser(other.fRecoPassUser),
132 fArrPidResponseMaster(NULL),
133 fResolutionCorrection(NULL),
134 fOADBvoltageMaps(NULL),
135 fTRDPIDResponseObject(NULL),
138 fEMCALPIDParams(NULL),
140 fCurrCentrality(0.0),
141 fTuneMConData(kFALSE)
148 //______________________________________________________________________________
149 AliPIDResponse& AliPIDResponse::operator=(const AliPIDResponse &other)
155 delete fArrPidResponseMaster;
156 TNamed::operator=(other);
157 fITSResponse=other.fITSResponse;
158 fTPCResponse=other.fTPCResponse;
159 fTRDResponse=other.fTRDResponse;
160 fTOFResponse=other.fTOFResponse;
161 fEMCALResponse=other.fEMCALResponse;
163 fITSPIDmethod=other.fITSPIDmethod;
164 fOADBPath=other.fOADBPath;
165 fCustomTPCpidResponse=other.fCustomTPCpidResponse;
167 fCachePID=other.fCachePID;
171 fMCperiodUser=other.fMCperiodUser;
174 fRecoPassUser=other.fRecoPassUser;
180 fArrPidResponseMaster=NULL;
181 fResolutionCorrection=NULL;
182 fOADBvoltageMaps=NULL;
183 fTRDPIDResponseObject=NULL;
184 fEMCALPIDParams=NULL;
187 fCurrentEvent=other.fCurrentEvent;
193 //______________________________________________________________________________
194 Float_t AliPIDResponse::NumberOfSigmas(EDetCode detCode, const AliVParticle *track, AliPID::EParticleType type) const
197 // NumberOfSigmas for 'detCode'
201 case kDetITS: return NumberOfSigmasITS(track, type); break;
202 case kDetTPC: return NumberOfSigmasTPC(track, type); break;
203 case kDetTOF: return NumberOfSigmasTOF(track, type); break;
204 case kDetEMCAL: return NumberOfSigmasEMCAL(track, type); break;
205 default: return -999.;
210 //______________________________________________________________________________
211 Float_t AliPIDResponse::NumberOfSigmas(EDetector detCode, const AliVParticle *track, AliPID::EParticleType type) const
214 // NumberOfSigmas for 'detCode'
216 return NumberOfSigmas((EDetCode)(1<<detCode), track, type);
219 //______________________________________________________________________________
220 // public buffered versions of the PID calculation
223 //______________________________________________________________________________
224 Float_t AliPIDResponse::NumberOfSigmasITS(const AliVParticle *vtrack, AliPID::EParticleType type) const
227 // Calculate the number of sigmas in the ITS
230 AliVTrack *track=(AliVTrack*)vtrack;
232 // look for cached value first
233 const AliDetectorPID *detPID=track->GetDetectorPID();
234 const EDetector detector=kITS;
236 if ( detPID && detPID->HasNumberOfSigmas(detector)){
237 return detPID->GetNumberOfSigmas(detector, type);
238 } else if (fCachePID) {
239 FillTrackDetectorPID(track, detector);
240 detPID=track->GetDetectorPID();
241 return detPID->GetNumberOfSigmas(detector, type);
244 return GetNumberOfSigmasITS(track, type);
247 //______________________________________________________________________________
248 Float_t AliPIDResponse::NumberOfSigmasTPC(const AliVParticle *vtrack, AliPID::EParticleType type) const
251 // Calculate the number of sigmas in the TPC
254 AliVTrack *track=(AliVTrack*)vtrack;
256 // look for cached value first
257 const AliDetectorPID *detPID=track->GetDetectorPID();
258 const EDetector detector=kTPC;
260 if ( detPID && detPID->HasNumberOfSigmas(detector)){
261 return detPID->GetNumberOfSigmas(detector, type);
262 } else if (fCachePID) {
263 FillTrackDetectorPID(track, detector);
264 detPID=track->GetDetectorPID();
265 return detPID->GetNumberOfSigmas(detector, type);
268 return GetNumberOfSigmasTPC(track, type);
271 //______________________________________________________________________________
272 Float_t AliPIDResponse::NumberOfSigmasTPC( const AliVParticle *vtrack,
273 AliPID::EParticleType type,
274 AliTPCPIDResponse::ETPCdEdxSource dedxSource)
276 //get number of sigmas according the selected TPC gain configuration scenario
277 const AliVTrack *track=static_cast<const AliVTrack*>(vtrack);
279 Float_t nSigma=fTPCResponse.GetNumberOfSigmas(track, type, dedxSource);
284 //______________________________________________________________________________
285 Float_t AliPIDResponse::NumberOfSigmasTOF(const AliVParticle *vtrack, AliPID::EParticleType type) const
288 // Calculate the number of sigmas in the TOF
291 AliVTrack *track=(AliVTrack*)vtrack;
293 // look for cached value first
294 const AliDetectorPID *detPID=track->GetDetectorPID();
295 const EDetector detector=kTOF;
297 if ( detPID && detPID->HasNumberOfSigmas(detector)){
298 return detPID->GetNumberOfSigmas(detector, type);
299 } else if (fCachePID) {
300 FillTrackDetectorPID(track, detector);
301 detPID=track->GetDetectorPID();
302 return detPID->GetNumberOfSigmas(detector, type);
305 return GetNumberOfSigmasTOF(track, type);
308 //______________________________________________________________________________
309 Float_t AliPIDResponse::NumberOfSigmasEMCAL(const AliVParticle *vtrack, AliPID::EParticleType type) const
312 // Calculate the number of sigmas in the EMCAL
315 AliVTrack *track=(AliVTrack*)vtrack;
317 // look for cached value first
318 const AliDetectorPID *detPID=track->GetDetectorPID();
319 const EDetector detector=kEMCAL;
321 if ( detPID && detPID->HasNumberOfSigmas(detector)){
322 return detPID->GetNumberOfSigmas(detector, type);
323 } else if (fCachePID) {
324 FillTrackDetectorPID(track, detector);
325 detPID=track->GetDetectorPID();
326 return detPID->GetNumberOfSigmas(detector, type);
329 return GetNumberOfSigmasEMCAL(track, type);
332 //______________________________________________________________________________
333 Float_t AliPIDResponse::NumberOfSigmasEMCAL(const AliVParticle *vtrack, AliPID::EParticleType type, Double_t &eop, Double_t showershape[4]) const
336 // emcal nsigma with eop and showershape
338 AliVTrack *track=(AliVTrack*)vtrack;
340 AliVCluster *matchedClus = NULL;
345 Double_t fClsE = -1.;
347 // initialize eop and shower shape parameters
349 for(Int_t i = 0; i < 4; i++){
350 showershape[i] = -1.;
353 Int_t nMatchClus = -1;
357 nMatchClus = track->GetEMCALcluster();
362 charge = track->Charge();
364 matchedClus = (AliVCluster*)fCurrentEvent->GetCaloCluster(nMatchClus);
368 // matched cluster is EMCAL
369 if(matchedClus->IsEMCAL()){
371 fClsE = matchedClus->E();
374 // fill used EMCAL variables here
376 showershape[0] = matchedClus->GetNCells(); // number of cells in cluster
377 showershape[1] = matchedClus->GetM02(); // long axis
378 showershape[2] = matchedClus->GetM20(); // short axis
379 showershape[3] = matchedClus->GetDispersion(); // dispersion
381 // look for cached value first
382 const AliDetectorPID *detPID=track->GetDetectorPID();
383 const EDetector detector=kEMCAL;
385 if ( detPID && detPID->HasNumberOfSigmas(detector)){
386 return detPID->GetNumberOfSigmas(detector, type);
387 } else if (fCachePID) {
388 FillTrackDetectorPID(track, detector);
389 detPID=track->GetDetectorPID();
390 return detPID->GetNumberOfSigmas(detector, type);
393 // NSigma value really meaningful only for electrons!
394 return fEMCALResponse.GetNumberOfSigmas(pt,EovP,type,charge);
402 //______________________________________________________________________________
403 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputePIDProbability (EDetCode detCode, const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
406 // Compute PID response of 'detCode'
410 case kDetITS: return ComputeITSProbability(track, nSpecies, p); break;
411 case kDetTPC: return ComputeTPCProbability(track, nSpecies, p); break;
412 case kDetTRD: return ComputeTRDProbability(track, nSpecies, p); break;
413 case kDetTOF: return ComputeTOFProbability(track, nSpecies, p); break;
414 case kDetPHOS: return ComputePHOSProbability(track, nSpecies, p); break;
415 case kDetEMCAL: return ComputeEMCALProbability(track, nSpecies, p); break;
416 case kDetHMPID: return ComputeHMPIDProbability(track, nSpecies, p); break;
417 default: return kDetNoSignal;
421 //______________________________________________________________________________
422 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputePIDProbability (EDetector detCode, const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
425 // Compute PID response of 'detCode'
428 return ComputePIDProbability((EDetCode)(1<<detCode),track,nSpecies,p);
431 //______________________________________________________________________________
432 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeITSProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
435 // Compute PID response for the ITS
438 // look for cached value first
439 const AliDetectorPID *detPID=track->GetDetectorPID();
440 const EDetector detector=kITS;
442 if ( detPID && detPID->HasRawProbabilitiy(detector)){
443 return detPID->GetRawProbability(detector, p, nSpecies);
444 } else if (fCachePID) {
445 FillTrackDetectorPID(track, detector);
446 detPID=track->GetDetectorPID();
447 return detPID->GetRawProbability(detector, p, nSpecies);
450 return GetComputeITSProbability(track, nSpecies, p);
452 //______________________________________________________________________________
453 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeTPCProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
456 // Compute PID response for the TPC
459 // look for cached value first
460 const AliDetectorPID *detPID=track->GetDetectorPID();
461 const EDetector detector=kTPC;
463 if ( detPID && detPID->HasRawProbabilitiy(detector)){
464 return detPID->GetRawProbability(detector, p, nSpecies);
465 } else if (fCachePID) {
466 FillTrackDetectorPID(track, detector);
467 detPID=track->GetDetectorPID();
468 return detPID->GetRawProbability(detector, p, nSpecies);
471 return GetComputeTPCProbability(track, nSpecies, p);
473 //______________________________________________________________________________
474 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeTOFProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
477 // Compute PID response for the
480 const AliDetectorPID *detPID=track->GetDetectorPID();
481 const EDetector detector=kTOF;
483 if ( detPID && detPID->HasRawProbabilitiy(detector)){
484 return detPID->GetRawProbability(detector, p, nSpecies);
485 } else if (fCachePID) {
486 FillTrackDetectorPID(track, detector);
487 detPID=track->GetDetectorPID();
488 return detPID->GetRawProbability(detector, p, nSpecies);
491 return GetComputeTOFProbability(track, nSpecies, p);
493 //______________________________________________________________________________
494 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeTRDProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[],AliTRDPIDResponse::ETRDPIDMethod PIDmethod) const
497 // Compute PID response for the
500 const AliDetectorPID *detPID=track->GetDetectorPID();
501 const EDetector detector=kTRD;
503 // chacke only for the default method (1d at the moment)
504 if (PIDmethod!=AliTRDPIDResponse::kLQ1D) return GetComputeTRDProbability(track, nSpecies, p, PIDmethod);
506 if ( detPID && detPID->HasRawProbabilitiy(detector)){
507 return detPID->GetRawProbability(detector, p, nSpecies);
508 } else if (fCachePID) {
509 FillTrackDetectorPID(track, detector);
510 detPID=track->GetDetectorPID();
511 return detPID->GetRawProbability(detector, p, nSpecies);
514 return GetComputeTRDProbability(track, nSpecies, p);
516 //______________________________________________________________________________
517 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeEMCALProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
520 // Compute PID response for the EMCAL
523 const AliDetectorPID *detPID=track->GetDetectorPID();
524 const EDetector detector=kEMCAL;
526 if ( detPID && detPID->HasRawProbabilitiy(detector)){
527 return detPID->GetRawProbability(detector, p, nSpecies);
528 } else if (fCachePID) {
529 FillTrackDetectorPID(track, detector);
530 detPID=track->GetDetectorPID();
531 return detPID->GetRawProbability(detector, p, nSpecies);
534 return GetComputeEMCALProbability(track, nSpecies, p);
536 //______________________________________________________________________________
537 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputePHOSProbability (const AliVTrack */*track*/, Int_t nSpecies, Double_t p[]) const
540 // Compute PID response for the PHOS
543 // look for cached value first
544 // if (track->GetDetectorPID()){
545 // return track->GetDetectorPID()->GetRawProbability(kPHOS, p, nSpecies);
548 // set flat distribution (no decision)
549 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
552 //______________________________________________________________________________
553 AliPIDResponse::EDetPidStatus AliPIDResponse::ComputeHMPIDProbability(const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
556 // Compute PID response for the HMPID
559 const AliDetectorPID *detPID=track->GetDetectorPID();
560 const EDetector detector=kHMPID;
562 if ( detPID && detPID->HasRawProbabilitiy(detector)){
563 return detPID->GetRawProbability(detector, p, nSpecies);
564 } else if (fCachePID) {
565 FillTrackDetectorPID(track, detector);
566 detPID=track->GetDetectorPID();
567 return detPID->GetRawProbability(detector, p, nSpecies);
570 return GetComputeHMPIDProbability(track, nSpecies, p);
573 //______________________________________________________________________________
574 void AliPIDResponse::InitialiseEvent(AliVEvent *event, Int_t pass, Int_t run)
577 // Apply settings for the current event
586 else fRun=event->GetRunNumber();
593 //TPC resolution parametrisation PbPb
594 if ( fResolutionCorrection ){
595 Double_t corrSigma=fResolutionCorrection->Eval(GetTPCMultiplicityBin(event));
596 fTPCResponse.SetSigma(3.79301e-03*corrSigma, 2.21280e+04);
600 SetTOFResponse(event, (AliPIDResponse::EStartTimeType_t)fTOFPIDParams->GetStartTimeMethod());
603 // Get and set centrality
604 AliCentrality *centrality = event->GetCentrality();
606 fCurrCentrality = centrality->GetCentralityPercentile("V0M");
609 fCurrCentrality = -1;
613 //______________________________________________________________________________
614 void AliPIDResponse::ExecNewRun()
617 // Things to Execute upon a new run
621 SetITSParametrisation();
623 SetTPCPidResponseMaster();
624 SetTPCParametrisation();
626 SetTRDPidResponseMaster();
627 InitializeTRDResponse();
629 SetEMCALPidResponseMaster();
630 InitializeEMCALResponse();
632 SetTOFPidResponseMaster();
633 InitializeTOFResponse();
635 if (fCurrentEvent) fTPCResponse.SetMagField(fCurrentEvent->GetMagneticField());
638 //______________________________________________________________________________
639 Double_t AliPIDResponse::GetTPCMultiplicityBin(const AliVEvent * const event)
642 // Get TPC multiplicity in bins of 150
645 const AliVVertex* vertexTPC = event->GetPrimaryVertex();
646 Double_t tpcMulti=0.;
648 Double_t vertexContribTPC=vertexTPC->GetNContributors();
649 tpcMulti=vertexContribTPC/150.;
650 if (tpcMulti>20.) tpcMulti=20.;
656 //______________________________________________________________________________
657 void AliPIDResponse::SetRecoInfo()
660 // Set reconstruction information
671 TPRegexp reg(".*(LHC1[1-2][a-z]+[0-9]+[a-z_]*)/.*");
672 TPRegexp reg12a17(".*(LHC12a17[a-z]+)/.*");
674 //find the period by run number (UGLY, but not stored in ESD and AOD... )
675 if (fRun>=114737&&fRun<=117223) { fLHCperiod="LHC10B"; fMCperiodTPC="LHC10D1"; }
676 else if (fRun>=118503&&fRun<=121040) { fLHCperiod="LHC10C"; fMCperiodTPC="LHC10D1"; }
677 else if (fRun>=122195&&fRun<=126437) { fLHCperiod="LHC10D"; fMCperiodTPC="LHC10F6A"; }
678 else if (fRun>=127710&&fRun<=130850) { fLHCperiod="LHC10E"; fMCperiodTPC="LHC10F6A"; }
679 else if (fRun>=133004&&fRun<=135029) { fLHCperiod="LHC10F"; fMCperiodTPC="LHC10F6A"; }
680 else if (fRun>=135654&&fRun<=136377) { fLHCperiod="LHC10G"; fMCperiodTPC="LHC10F6A"; }
681 else if (fRun>=136851&&fRun<=139517) {
683 fMCperiodTPC="LHC10H8";
684 if (reg.MatchB(fCurrentFile)) fMCperiodTPC="LHC11A10";
687 else if (fRun>=139699&&fRun<=146860) { fLHCperiod="LHC11A"; fMCperiodTPC="LHC10F6A"; }
688 //TODO: periods 11B, 11C are not yet treated assume 11d for the moment
689 else if (fRun>=148531&&fRun<=155384) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
690 else if (fRun>=156477&&fRun<=159635) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
691 // also for 11e,f use 11d
692 else if (fRun>=160676&&fRun<=162740) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
693 else if (fRun>=162933&&fRun<=165746) { fLHCperiod="LHC11D"; fMCperiodTPC="LHC10F6A"; }
695 else if (fRun>=166529 && fRun<=170718) {
697 fMCperiodTPC="LHC11A10";
699 if (reg12a17.MatchB(fCurrentFile)) fMCperiodTPC="LHC12A17";
701 if (fRun>=170719 && fRun<=177311) { fLHCperiod="LHC12A"; fBeamType="PP"; /*fMCperiodTPC="";*/ }
702 // for the moment use LHC12b parameters up to LHC12e
703 if (fRun>=177312 /*&& fRun<=179356*/) { fLHCperiod="LHC12B"; fBeamType="PP"; /*fMCperiodTPC="";*/ }
704 // if (fRun>=179357 && fRun<=183173) { fLHCperiod="LHC12C"; fBeamType="PP"; /*fMCperiodTPC="";*/ }
705 // if (fRun>=183174 && fRun<=186345) { fLHCperiod="LHC12D"; fBeamType="PP"; /*fMCperiodTPC="";*/ }
706 // if (fRun>=186346 && fRun<=186635) { fLHCperiod="LHC12E"; fBeamType="PP"; /*fMCperiodTPC="";*/ }
708 // if (fRun>=186636 && fRun<=188166) { fLHCperiod="LHC12F"; fBeamType="PP"; /*fMCperiodTPC="";*/ }
709 // if (fRun >= 188167 && fRun <= 188355 ) { fLHCperiod="LHC12G"; fBeamType="PP"; /*fMCperiodTPC="";*/ }
710 // if (fRun >= 188356 && fRun <= 188503 ) { fLHCperiod="LHC12G"; fBeamType="PPB"; /*fMCperiodTPC="";*/ }
711 // for the moment use 12g parametrisation for all full gain runs (LHC12f+)
712 if (fRun >= 186636 ) { fLHCperiod="LHC12G"; fBeamType="PPB"; /*fMCperiodTPC="";*/ }
714 //exception new pp MC productions from 2011
715 if (fBeamType=="PP" && reg.MatchB(fCurrentFile)) fMCperiodTPC="LHC11B2";
716 // exception for 11f1
717 if (fCurrentFile.Contains("LHC11f1/")) fMCperiodTPC="LHC11F1";
720 //______________________________________________________________________________
721 void AliPIDResponse::SetITSParametrisation()
724 // Set the ITS parametrisation
728 //______________________________________________________________________________
729 void AliPIDResponse::SetTPCPidResponseMaster()
732 // Load the TPC pid response functions from the OADB
733 // Load the TPC voltage maps from OADB
735 //don't load twice for the moment
736 if (fArrPidResponseMaster) return;
739 //reset the PID response functions
740 delete fArrPidResponseMaster;
741 fArrPidResponseMaster=NULL;
743 TString fileName(Form("%s/COMMON/PID/data/TPCPIDResponse.root", fOADBPath.Data()));
745 if (!fCustomTPCpidResponse.IsNull()) fileName=fCustomTPCpidResponse;
747 TString fileNamePIDresponse(Form("%s/COMMON/PID/data/TPCPIDResponse.root", fOADBPath.Data()));
748 f=TFile::Open(fileNamePIDresponse.Data());
749 if (f && f->IsOpen() && !f->IsZombie()){
750 fArrPidResponseMaster=dynamic_cast<TObjArray*>(f->Get("TPCPIDResponse"));
754 TString fileNameVoltageMaps(Form("%s/COMMON/PID/data/TPCvoltageSettings.root", fOADBPath.Data()));
755 f=TFile::Open(fileNameVoltageMaps.Data());
756 if (f && f->IsOpen() && !f->IsZombie()){
757 fOADBvoltageMaps=dynamic_cast<AliOADBContainer*>(f->Get("TPCvoltageSettings"));
761 if (!fArrPidResponseMaster){
762 AliFatal(Form("Could not retrieve the TPC pid response from: %s",fileNamePIDresponse.Data()));
765 fArrPidResponseMaster->SetOwner();
767 if (!fOADBvoltageMaps)
769 AliFatal(Form("Could not retrieve the TPC voltage maps from: %s",fileNameVoltageMaps.Data()));
771 fArrPidResponseMaster->SetOwner();
774 //______________________________________________________________________________
775 void AliPIDResponse::SetTPCParametrisation()
778 // Change BB parametrisation for current run
781 if (fLHCperiod.IsNull()) {
782 AliFatal("No period set, not changing parametrisation");
787 // Set default parametrisations for data and MC
791 TString datatype="DATA";
792 //in case of mc fRecoPass is per default 1
794 if(!fTuneMConData) datatype="MC";
801 fTPCResponse.ResetSplines();
804 TString period=fLHCperiod;
805 if (fIsMC && !fTuneMConData) period=fMCperiodTPC;
807 AliInfo(Form("Searching splines for: %s %s PASS%d %s",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));
810 //set the new PID splines
812 if (fArrPidResponseMaster){
813 Int_t recopass = fRecoPass;
814 if(fTuneMConData) recopass = fRecoPassUser;
815 //for MC don't use period information
816 //if (fIsMC) period="[A-Z0-9]*";
817 //for MC use MC period information
818 //pattern for the default entry (valid for all particles)
819 TPRegexp reg(Form("TSPLINE3_%s_([A-Z]*)_%s_PASS%d_%s_MEAN(_*)([A-Z1-9]*)",datatype.Data(),period.Data(),recopass,fBeamType.Data()));
821 //find particle id ang gain scenario
822 for (Int_t igainScenario=0; igainScenario<AliTPCPIDResponse::fgkNumberOfGainScenarios; igainScenario++)
825 TString gainScenario = AliTPCPIDResponse::GainScenarioName(igainScenario);
826 gainScenario.ToUpper();
827 //loop over entries and filter them
828 for (Int_t iresp=0; iresp<fArrPidResponseMaster->GetEntriesFast();++iresp)
830 TObject *responseFunction=fArrPidResponseMaster->At(iresp);
831 if (responseFunction==NULL) continue;
832 TString responseName=responseFunction->GetName();
834 if (!reg.MatchB(responseName)) continue;
836 TObjArray *arr=reg.MatchS(responseName); if (!arr) continue;
838 tmp=arr->At(1); if (!tmp) continue;
839 TString particleName=tmp->GetName();
840 tmp=arr->At(3); if (!tmp) continue;
841 TString gainScenarioName=tmp->GetName();
843 if (particleName.IsNull()) continue;
844 if (!grAll && particleName=="ALL" && gainScenarioName==gainScenario) grAll=responseFunction;
847 for (Int_t ispec=0; ispec<(AliTPCPIDResponse::fgkNumberOfParticleSpecies); ++ispec)
849 TString particle=AliPID::ParticleName(ispec);
851 //std::cout<<responseName<<" "<<particle<<" "<<particleName<<" "<<gainScenario<<" "<<gainScenarioName<<std::endl;
852 if ( particle == particleName && gainScenario == gainScenarioName )
854 fTPCResponse.SetResponseFunction( responseFunction,
855 (AliPID::EParticleType)ispec,
856 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
857 fTPCResponse.SetUseDatabase(kTRUE);
858 AliInfo(Form("Adding graph: %d %d - %s",ispec,igainScenario,responseFunction->GetName()));
860 // overwrite default with proton spline (for light nuclei)
861 if (ispec==AliPID::kProton) grAll=responseFunction;
869 for (Int_t ispec=0; ispec<(AliTPCPIDResponse::fgkNumberOfParticleSpecies); ++ispec)
871 if (!fTPCResponse.GetResponseFunction( (AliPID::EParticleType)ispec,
872 (AliTPCPIDResponse::ETPCgainScenario)igainScenario))
874 fTPCResponse.SetResponseFunction( grAll,
875 (AliPID::EParticleType)ispec,
876 (AliTPCPIDResponse::ETPCgainScenario)igainScenario );
877 fTPCResponse.SetUseDatabase(kTRUE);
878 AliInfo(Form("Adding graph: %d %d - %s",ispec,igainScenario,grAll->GetName()));
885 else AliInfo("no fArrPidResponseMaster");
888 AliError(Form("No splines found for: %s %s PASS%d %s",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));
892 // Setup resolution parametrisation
896 fTPCResponse.SetSigma(3.79301e-03, 2.21280e+04);
899 fTPCResponse.SetSigma(2.30176e-02, 5.60422e+02);
903 // if (fRun>=188356){
904 fTPCResponse.SetSigma(8.62022e-04, 9.08156e+05);
907 if (fArrPidResponseMaster)
908 fResolutionCorrection=(TF1*)fArrPidResponseMaster->FindObject(Form("TF1_%s_ALL_%s_PASS%d_%s_SIGMA",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));
910 if (fResolutionCorrection) AliInfo(Form("Setting multiplicity correction function: %s",fResolutionCorrection->GetName()));
912 //read in the voltage map
913 TVectorF* gsm = dynamic_cast<TVectorF*>(fOADBvoltageMaps->GetObject(fRun));
916 fTPCResponse.SetVoltageMap(*gsm);
918 AliInfo(Form("Reading the voltage map for run %d\n",fRun));
919 vals="IROC A: "; for (Int_t i=0; i<18; i++){vals+=Form("%.2f ",(*gsm)[i]);}
920 AliInfo(vals.Data());
921 vals="IROC C: "; for (Int_t i=18; i<36; i++){vals+=Form("%.2f ",(*gsm)[i]);}
922 AliInfo(vals.Data());
923 vals="OROC A: "; for (Int_t i=36; i<54; i++){vals+=Form("%.2f ",(*gsm)[i]);}
924 AliInfo(vals.Data());
925 vals="OROC C: "; for (Int_t i=54; i<72; i++){vals+=Form("%.2f ",(*gsm)[i]);}
926 AliInfo(vals.Data());
928 else AliInfo("no voltage map, ideal default assumed");
931 //______________________________________________________________________________
932 void AliPIDResponse::SetTRDPidResponseMaster()
935 // Load the TRD pid params and references from the OADB
937 if(fTRDPIDResponseObject) return;
938 AliOADBContainer contParams("contParams");
940 Int_t statusResponse = contParams.InitFromFile(Form("%s/COMMON/PID/data/TRDPIDResponse.root", fOADBPath.Data()), "AliTRDPIDResponseObject");
942 AliError("Failed initializing PID Response Object from OADB");
944 AliInfo(Form("Loading TRD Response from %s/COMMON/PID/data/TRDPIDResponse.root", fOADBPath.Data()));
945 fTRDPIDResponseObject = dynamic_cast<AliTRDPIDResponseObject *>(contParams.GetObject(fRun));
946 if(!fTRDPIDResponseObject){
947 AliError(Form("TRD Response not found in run %d", fRun));
952 //______________________________________________________________________________
953 void AliPIDResponse::InitializeTRDResponse(){
955 // Set PID Params and references to the TRD PID response
957 fTRDResponse.SetPIDResponseObject(fTRDPIDResponseObject);
960 //______________________________________________________________________________
961 void AliPIDResponse::SetTRDSlices(UInt_t TRDslicesForPID[2],AliTRDPIDResponse::ETRDPIDMethod method) const{
963 if(fLHCperiod == "LHC10d" || fLHCperiod == "LHC10e"){
964 // backward compatibility for setting with 8 slices
965 TRDslicesForPID[0] = 0;
966 TRDslicesForPID[1] = 7;
969 if(method==AliTRDPIDResponse::kLQ1D){
970 TRDslicesForPID[0] = 0; // first Slice contains normalized dEdx
971 TRDslicesForPID[1] = 0;
973 if(method==AliTRDPIDResponse::kLQ2D){
974 TRDslicesForPID[0] = 1;
975 TRDslicesForPID[1] = 7;
978 AliDebug(1,Form("Slice Range set to %d - %d",TRDslicesForPID[0],TRDslicesForPID[1]));
981 //______________________________________________________________________________
982 void AliPIDResponse::SetTOFPidResponseMaster()
985 // Load the TOF pid params from the OADB
988 if (fTOFPIDParams) delete fTOFPIDParams;
991 TFile *oadbf = new TFile(Form("%s/COMMON/PID/data/TOFPIDParams.root",fOADBPath.Data()));
992 if (oadbf && oadbf->IsOpen()) {
993 AliInfo(Form("Loading TOF Params from %s/COMMON/PID/data/TOFPIDParams.root", fOADBPath.Data()));
994 AliOADBContainer *oadbc = (AliOADBContainer *)oadbf->Get("TOFoadb");
995 if (oadbc) fTOFPIDParams = dynamic_cast<AliTOFPIDParams *>(oadbc->GetObject(fRun,"TOFparams"));
1001 if (!fTOFPIDParams) AliFatal("TOFPIDParams could not be retrieved");
1004 //______________________________________________________________________________
1005 void AliPIDResponse::InitializeTOFResponse(){
1007 // Set PID Params to the TOF PID response
1010 AliInfo("TOF PID Params loaded from OADB");
1011 AliInfo(Form(" TOF resolution %5.2f [ps]",fTOFPIDParams->GetTOFresolution()));
1012 AliInfo(Form(" StartTime method %d",fTOFPIDParams->GetStartTimeMethod()));
1013 AliInfo(Form(" TOF res. mom. params: %5.2f %5.2f %5.2f %5.2f",
1014 fTOFPIDParams->GetSigParams(0),fTOFPIDParams->GetSigParams(1),fTOFPIDParams->GetSigParams(2),fTOFPIDParams->GetSigParams(3)));
1016 for (Int_t i=0;i<4;i++) {
1017 fTOFResponse.SetTrackParameter(i,fTOFPIDParams->GetSigParams(i));
1019 fTOFResponse.SetTimeResolution(fTOFPIDParams->GetTOFresolution());
1021 AliInfo("TZERO resolution loaded from ESDrun/AODheader");
1022 Float_t t0Spread[4];
1023 for (Int_t i=0;i<4;i++) t0Spread[i]=fCurrentEvent->GetT0spread(i);
1024 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]));
1025 Float_t a = t0Spread[1]*t0Spread[1]-t0Spread[0]*t0Spread[0]+t0Spread[3]*t0Spread[3];
1026 Float_t c = t0Spread[2]*t0Spread[2]-t0Spread[0]*t0Spread[0]+t0Spread[3]*t0Spread[3];
1027 if ( (t0Spread[0] > 50. && t0Spread[0] < 400.) && (a > 0.) && (c>0.)) {
1028 fResT0AC=t0Spread[3];
1029 fResT0A=TMath::Sqrt(a);
1030 fResT0C=TMath::Sqrt(c);
1032 AliInfo(" TZERO spreads not present or inconsistent, loading default");
1037 AliInfo(Form(" TZERO resolution set to: T0A: %f [ps] T0C: %f [ps] T0AC %f [ps]",fResT0A,fResT0C,fResT0AC));
1042 //______________________________________________________________________________
1043 Bool_t AliPIDResponse::IdentifiedAsElectronTRD(const AliVTrack *vtrack, Double_t efficiencyLevel,Double_t centrality,AliTRDPIDResponse::ETRDPIDMethod PIDmethod) const {
1045 // Check whether track is identified as electron under a given electron efficiency hypothesis
1048 Double_t probs[AliPID::kSPECIES];
1049 ComputeTRDProbability(vtrack, AliPID::kSPECIES, probs,PIDmethod);
1051 Int_t ntracklets = vtrack->GetTRDntrackletsPID();
1052 // Take mean of the TRD momenta in the given tracklets
1053 Float_t p = 0, trdmomenta[AliVTrack::kTRDnPlanes];
1055 for(Int_t iPl=0;iPl<AliVTrack::kTRDnPlanes;iPl++){
1056 if(vtrack->GetTRDmomentum(iPl) > 0.){
1057 trdmomenta[nmomenta++] = vtrack->GetTRDmomentum(iPl);
1060 p = TMath::Mean(nmomenta, trdmomenta);
1062 return fTRDResponse.IdentifiedAsElectron(ntracklets, probs, p, efficiencyLevel,centrality,PIDmethod);
1065 //______________________________________________________________________________
1066 void AliPIDResponse::SetEMCALPidResponseMaster()
1069 // Load the EMCAL pid response functions from the OADB
1071 TObjArray* fEMCALPIDParamsRun = NULL;
1072 TObjArray* fEMCALPIDParamsPass = NULL;
1074 if(fEMCALPIDParams) return;
1075 AliOADBContainer contParams("contParams");
1077 Int_t statusPars = contParams.InitFromFile(Form("%s/COMMON/PID/data/EMCALPIDParams.root", fOADBPath.Data()), "AliEMCALPIDParams");
1079 AliError("Failed initializing PID Params from OADB");
1082 AliInfo(Form("Loading EMCAL Params from %s/COMMON/PID/data/EMCALPIDParams.root", fOADBPath.Data()));
1084 fEMCALPIDParamsRun = dynamic_cast<TObjArray *>(contParams.GetObject(fRun));
1085 if(fEMCALPIDParamsRun) fEMCALPIDParamsPass = dynamic_cast<TObjArray *>(fEMCALPIDParamsRun->FindObject(Form("pass%d",fRecoPass)));
1086 if(fEMCALPIDParamsPass) fEMCALPIDParams = dynamic_cast<TObjArray *>(fEMCALPIDParamsPass->FindObject(Form("EMCALPIDParams_Particles")));
1088 if(!fEMCALPIDParams){
1089 AliInfo(Form("EMCAL Params not found in run %d pass %d", fRun, fRecoPass));
1090 AliInfo("Will take the standard LHC11d instead ...");
1092 fEMCALPIDParamsRun = dynamic_cast<TObjArray *>(contParams.GetObject(156477));
1093 if(fEMCALPIDParamsRun) fEMCALPIDParamsPass = dynamic_cast<TObjArray *>(fEMCALPIDParamsRun->FindObject(Form("pass%d",1)));
1094 if(fEMCALPIDParamsPass) fEMCALPIDParams = dynamic_cast<TObjArray *>(fEMCALPIDParamsPass->FindObject(Form("EMCALPIDParams_Particles")));
1096 if(!fEMCALPIDParams){
1097 AliError(Form("DEFAULT EMCAL Params (LHC11d) not found in file %s/COMMON/PID/data/EMCALPIDParams.root", fOADBPath.Data()));
1103 //______________________________________________________________________________
1104 void AliPIDResponse::InitializeEMCALResponse(){
1106 // Set PID Params to the EMCAL PID response
1108 fEMCALResponse.SetPIDParams(fEMCALPIDParams);
1112 //______________________________________________________________________________
1113 void AliPIDResponse::FillTrackDetectorPID(const AliVTrack *track, EDetector detector) const
1116 // create detector PID information and setup the transient pointer in the track
1119 // check if detector number is inside accepted range
1120 if (detector == kNdetectors) return;
1123 AliDetectorPID *detPID=const_cast<AliDetectorPID*>(track->GetDetectorPID());
1125 detPID=new AliDetectorPID;
1126 (const_cast<AliVTrack*>(track))->SetDetectorPID(detPID);
1129 //check if values exist
1130 if (detPID->HasRawProbabilitiy(detector) && detPID->HasNumberOfSigmas(detector)) return;
1132 //TODO: which particles to include? See also the loops below...
1133 Double_t values[AliPID::kSPECIESC]={0};
1136 for (Int_t ipart=0; ipart<AliPID::kSPECIESC; ++ipart)
1137 values[ipart]=GetNumberOfSigmas(detector,track,(AliPID::EParticleType)ipart);
1138 detPID->SetNumberOfSigmas(detector, values, (Int_t)AliPID::kSPECIESC);
1141 EDetPidStatus status=GetComputePIDProbability(detector,track,AliPID::kSPECIESC,values);
1142 detPID->SetRawProbability(detector, values, (Int_t)AliPID::kSPECIESC, status);
1145 //______________________________________________________________________________
1146 void AliPIDResponse::FillTrackDetectorPID()
1149 // create detector PID information and setup the transient pointer in the track
1152 if (!fCurrentEvent) return;
1154 for (Int_t itrack=0; itrack<fCurrentEvent->GetNumberOfTracks(); ++itrack){
1155 AliVTrack *track=dynamic_cast<AliVTrack*>(fCurrentEvent->GetTrack(itrack));
1156 if (!track) continue;
1158 for (Int_t idet=0; idet<kNdetectors; ++idet){
1159 FillTrackDetectorPID(track, (EDetector)idet);
1164 //______________________________________________________________________________
1165 void AliPIDResponse::SetTOFResponse(AliVEvent *vevent,EStartTimeType_t option){
1167 // Set TOF response function
1168 // Input option for event_time used
1171 Float_t t0spread = 0.; //vevent->GetEventTimeSpread();
1172 if(t0spread < 10) t0spread = 80;
1174 // T0 from TOF algorithm
1176 Bool_t flagT0TOF=kFALSE;
1177 Bool_t flagT0T0=kFALSE;
1178 Float_t *startTime = new Float_t[fTOFResponse.GetNmomBins()];
1179 Float_t *startTimeRes = new Float_t[fTOFResponse.GetNmomBins()];
1180 Int_t *startTimeMask = new Int_t[fTOFResponse.GetNmomBins()];
1183 Float_t *estimatedT0event = new Float_t[fTOFResponse.GetNmomBins()];
1184 Float_t *estimatedT0resolution = new Float_t[fTOFResponse.GetNmomBins()];
1185 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1186 estimatedT0event[i]=0.0;
1187 estimatedT0resolution[i]=0.0;
1188 startTimeMask[i] = 0;
1191 Float_t resT0A=fResT0A;
1192 Float_t resT0C=fResT0C;
1193 Float_t resT0AC=fResT0AC;
1194 if(vevent->GetT0TOF()){ // check if T0 detector information is available
1199 AliTOFHeader *tofHeader = (AliTOFHeader*)vevent->GetTOFHeader();
1201 if (tofHeader) { // read global info and T0-TOF
1202 fTOFResponse.SetTimeResolution(tofHeader->GetTOFResolution());
1203 t0spread = tofHeader->GetT0spread(); // read t0 sprad
1204 if(t0spread < 10) t0spread = 80;
1207 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){ // read T0-TOF default value
1208 startTime[i]=tofHeader->GetDefaultEventTimeVal();
1209 startTimeRes[i]=tofHeader->GetDefaultEventTimeRes();
1210 if(startTimeRes[i] < 1.e-5) startTimeRes[i] = t0spread;
1213 TArrayI *ibin=(TArrayI*)tofHeader->GetNvalues();
1214 TArrayF *t0Bin=(TArrayF*)tofHeader->GetEventTimeValues();
1215 TArrayF *t0ResBin=(TArrayF*)tofHeader->GetEventTimeRes();
1216 for(Int_t j=0;j < tofHeader->GetNbins();j++){ // fill T0-TOF in p-bins
1217 Int_t icurrent = (Int_t)ibin->GetAt(j);
1218 startTime[icurrent]=t0Bin->GetAt(j);
1219 startTimeRes[icurrent]=t0ResBin->GetAt(j);
1220 if(startTimeRes[icurrent] < 1.e-5) startTimeRes[icurrent] = t0spread;
1224 // for cut of 3 sigma on t0 spread
1225 Float_t t0cut = 3 * t0spread;
1226 if(t0cut < 500) t0cut = 500;
1228 if(option == kFILL_T0){ // T0-FILL is used
1229 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1230 estimatedT0event[i]=0.0;
1231 estimatedT0resolution[i]=t0spread;
1233 fTOFResponse.SetT0event(estimatedT0event);
1234 fTOFResponse.SetT0resolution(estimatedT0resolution);
1237 if(option == kTOF_T0){ // T0-TOF is used when available (T0-FILL otherwise) from ESD
1239 fTOFResponse.SetT0event(startTime);
1240 fTOFResponse.SetT0resolution(startTimeRes);
1241 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1242 if(startTimeRes[i]<t0spread) startTimeMask[i]=1;
1243 fTOFResponse.SetT0binMask(i,startTimeMask[i]);
1247 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1248 estimatedT0event[i]=0.0;
1249 estimatedT0resolution[i]=t0spread;
1250 fTOFResponse.SetT0binMask(i,startTimeMask[i]);
1252 fTOFResponse.SetT0event(estimatedT0event);
1253 fTOFResponse.SetT0resolution(estimatedT0resolution);
1256 else if(option == kBest_T0){ // T0-T0 or T0-TOF are used when available (T0-FILL otherwise) from ESD
1257 Float_t t0AC=-10000;
1261 t0A= vevent->GetT0TOF()[1];
1262 t0C= vevent->GetT0TOF()[2];
1263 // t0AC= vevent->GetT0TOF()[0];
1264 t0AC= t0A/resT0A/resT0A + t0C/resT0C/resT0C;
1265 resT0AC= TMath::Sqrt(1./resT0A/resT0A + 1./resT0C/resT0C);
1266 t0AC /= resT0AC*resT0AC;
1269 Float_t t0t0Best = 0;
1270 Float_t t0t0BestRes = 9999;
1272 if(TMath::Abs(t0A) < t0cut && TMath::Abs(t0C) < t0cut && TMath::Abs(t0C-t0A) < 500){
1274 t0t0BestRes = resT0AC;
1277 else if(TMath::Abs(t0C) < t0cut){
1279 t0t0BestRes = resT0C;
1282 else if(TMath::Abs(t0A) < t0cut){
1284 t0t0BestRes = resT0A;
1288 if(flagT0TOF){ // if T0-TOF info is available
1289 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1290 if(t0t0BestRes < 999){
1291 if(startTimeRes[i] < t0spread){
1292 Double_t wtot = 1./startTimeRes[i]/startTimeRes[i] + 1./t0t0BestRes/t0t0BestRes;
1293 Double_t t0best = startTime[i]/startTimeRes[i]/startTimeRes[i] + t0t0Best/t0t0BestRes/t0t0BestRes;
1294 estimatedT0event[i]=t0best / wtot;
1295 estimatedT0resolution[i]=1./TMath::Sqrt(wtot);
1296 startTimeMask[i] = t0used+1;
1299 estimatedT0event[i]=t0t0Best;
1300 estimatedT0resolution[i]=t0t0BestRes;
1301 startTimeMask[i] = t0used;
1305 estimatedT0event[i]=startTime[i];
1306 estimatedT0resolution[i]=startTimeRes[i];
1307 if(startTimeRes[i]<t0spread) startTimeMask[i]=1;
1309 fTOFResponse.SetT0binMask(i,startTimeMask[i]);
1311 fTOFResponse.SetT0event(estimatedT0event);
1312 fTOFResponse.SetT0resolution(estimatedT0resolution);
1314 else{ // if no T0-TOF info is available
1315 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1316 fTOFResponse.SetT0binMask(i,t0used);
1317 if(t0t0BestRes < 999){
1318 estimatedT0event[i]=t0t0Best;
1319 estimatedT0resolution[i]=t0t0BestRes;
1322 estimatedT0event[i]=0.0;
1323 estimatedT0resolution[i]=t0spread;
1326 fTOFResponse.SetT0event(estimatedT0event);
1327 fTOFResponse.SetT0resolution(estimatedT0resolution);
1331 else if(option == kT0_T0){ // T0-T0 is used when available (T0-FILL otherwise)
1332 Float_t t0AC=-10000;
1336 t0A= vevent->GetT0TOF()[1];
1337 t0C= vevent->GetT0TOF()[2];
1338 // t0AC= vevent->GetT0TOF()[0];
1339 t0AC= t0A/resT0A/resT0A + t0C/resT0C/resT0C;
1340 resT0AC= TMath::Sqrt(1./resT0A/resT0A + 1./resT0C/resT0C);
1341 t0AC /= resT0AC*resT0AC;
1344 if(TMath::Abs(t0A) < t0cut && TMath::Abs(t0C) < t0cut && TMath::Abs(t0C-t0A) < 500){
1345 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1346 estimatedT0event[i]=t0AC;
1347 estimatedT0resolution[i]=resT0AC;
1348 fTOFResponse.SetT0binMask(i,6);
1351 else if(TMath::Abs(t0C) < t0cut){
1352 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1353 estimatedT0event[i]=t0C;
1354 estimatedT0resolution[i]=resT0C;
1355 fTOFResponse.SetT0binMask(i,4);
1358 else if(TMath::Abs(t0A) < t0cut){
1359 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1360 estimatedT0event[i]=t0A;
1361 estimatedT0resolution[i]=resT0A;
1362 fTOFResponse.SetT0binMask(i,2);
1366 for(Int_t i=0;i<fTOFResponse.GetNmomBins();i++){
1367 estimatedT0event[i]=0.0;
1368 estimatedT0resolution[i]=t0spread;
1369 fTOFResponse.SetT0binMask(i,0);
1372 fTOFResponse.SetT0event(estimatedT0event);
1373 fTOFResponse.SetT0resolution(estimatedT0resolution);
1375 delete [] startTime;
1376 delete [] startTimeRes;
1377 delete [] startTimeMask;
1378 delete [] estimatedT0event;
1379 delete [] estimatedT0resolution;
1382 //______________________________________________________________________________
1383 // private non cached versions of the PID calculation
1387 //______________________________________________________________________________
1388 Float_t AliPIDResponse::GetNumberOfSigmas(EDetector detCode, const AliVParticle *track, AliPID::EParticleType type) const
1391 // NumberOfSigmas for 'detCode'
1395 case kITS: return GetNumberOfSigmasITS(track, type); break;
1396 case kTPC: return GetNumberOfSigmasTPC(track, type); break;
1397 case kTOF: return GetNumberOfSigmasTOF(track, type); break;
1398 case kEMCAL: return GetNumberOfSigmasEMCAL(track, type); break;
1399 default: return -999.;
1406 //______________________________________________________________________________
1407 Float_t AliPIDResponse::GetNumberOfSigmasITS(const AliVParticle *vtrack, AliPID::EParticleType type) const
1410 // Calculate the number of sigmas in the ITS
1413 AliVTrack *track=(AliVTrack*)vtrack;
1415 Float_t dEdx=track->GetITSsignal();
1416 if (dEdx<=0) return -999.;
1418 UChar_t clumap=track->GetITSClusterMap();
1419 Int_t nPointsForPid=0;
1420 for(Int_t i=2; i<6; i++){
1421 if(clumap&(1<<i)) ++nPointsForPid;
1423 Float_t mom=track->P();
1425 //check for ITS standalone tracks
1427 if( track->GetStatus() & AliVTrack::kTPCin ) isSA=kFALSE;
1429 //TODO: in case of the electron, use the SA parametrisation,
1430 // this needs to be changed if ITS provides a parametrisation
1431 // for electrons also for ITS+TPC tracks
1432 return fITSResponse.GetNumberOfSigmas(mom,dEdx,type,nPointsForPid,isSA || (type==AliPID::kElectron));
1435 //______________________________________________________________________________
1436 Float_t AliPIDResponse::GetNumberOfSigmasTPC(const AliVParticle *vtrack, AliPID::EParticleType type) const
1439 // Calculate the number of sigmas in the TPC
1442 AliVTrack *track=(AliVTrack*)vtrack;
1444 Double_t mom = track->GetTPCmomentum();
1445 Double_t sig = track->GetTPCsignal();
1446 if(fTuneMConData) sig = this->GetTPCsignalTunedOnData(track);
1447 UInt_t sigN = track->GetTPCsignalN();
1449 Double_t nSigma = -999.;
1450 if (sigN>0) nSigma=fTPCResponse.GetNumberOfSigmas(mom,sig,sigN,type);
1455 //______________________________________________________________________________
1456 Float_t AliPIDResponse::GetNumberOfSigmasEMCAL(const AliVParticle *vtrack, AliPID::EParticleType type) const
1459 // Calculate the number of sigmas in the EMCAL
1462 AliVTrack *track=(AliVTrack*)vtrack;
1464 AliVCluster *matchedClus = NULL;
1468 Double_t EovP = -1.;
1469 Double_t fClsE = -1.;
1471 Int_t nMatchClus = -1;
1475 nMatchClus = track->GetEMCALcluster();
1476 if(nMatchClus > -1){
1480 charge = track->Charge();
1482 matchedClus = (AliVCluster*)fCurrentEvent->GetCaloCluster(nMatchClus);
1486 // matched cluster is EMCAL
1487 if(matchedClus->IsEMCAL()){
1489 fClsE = matchedClus->E();
1493 // NSigma value really meaningful only for electrons!
1494 return fEMCALResponse.GetNumberOfSigmas(pt,EovP,type,charge);
1504 //______________________________________________________________________________
1505 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputePIDProbability (EDetector detCode, const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
1508 // Compute PID response of 'detCode'
1512 case kITS: return GetComputeITSProbability(track, nSpecies, p); break;
1513 case kTPC: return GetComputeTPCProbability(track, nSpecies, p); break;
1514 case kTRD: return GetComputeTRDProbability(track, nSpecies, p); break;
1515 case kTOF: return GetComputeTOFProbability(track, nSpecies, p); break;
1516 case kPHOS: return GetComputePHOSProbability(track, nSpecies, p); break;
1517 case kEMCAL: return GetComputeEMCALProbability(track, nSpecies, p); break;
1518 case kHMPID: return GetComputeHMPIDProbability(track, nSpecies, p); break;
1519 default: return kDetNoSignal;
1523 //______________________________________________________________________________
1524 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeITSProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
1527 // Compute PID response for the ITS
1530 // look for cached value first
1531 // only the non SA tracks are cached
1532 if (track->GetDetectorPID()){
1533 return track->GetDetectorPID()->GetRawProbability(kITS, p, nSpecies);
1536 // set flat distribution (no decision)
1537 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1539 if ((track->GetStatus()&AliVTrack::kITSin)==0 &&
1540 (track->GetStatus()&AliVTrack::kITSout)==0) return kDetNoSignal;
1542 //check for ITS standalone tracks
1544 if( track->GetStatus() & AliVTrack::kTPCin ) isSA=kFALSE;
1546 Double_t mom=track->P();
1547 Double_t dedx=track->GetITSsignal();
1548 Double_t momITS=mom;
1549 UChar_t clumap=track->GetITSClusterMap();
1550 Int_t nPointsForPid=0;
1551 for(Int_t i=2; i<6; i++){
1552 if(clumap&(1<<i)) ++nPointsForPid;
1555 if(nPointsForPid<3) { // track not to be used for combined PID purposes
1556 // track->ResetStatus(AliVTrack::kITSpid);
1557 return kDetNoSignal;
1560 Bool_t mismatch=kTRUE/*, heavy=kTRUE*/;
1561 for (Int_t j=0; j<AliPID::kSPECIES; j++) {
1562 Double_t mass=AliPID::ParticleMassZ(j);//GeV/c^2
1563 const Double_t chargeFactor = TMath::Power(AliPID::ParticleCharge(j),2.);
1564 Double_t bethe=fITSResponse.Bethe(momITS,mass)*chargeFactor;
1565 //TODO: in case of the electron, use the SA parametrisation,
1566 // this needs to be changed if ITS provides a parametrisation
1567 // for electrons also for ITS+TPC tracks
1568 Double_t sigma=fITSResponse.GetResolution(bethe,nPointsForPid,isSA || (j==(Int_t)AliPID::kElectron));
1569 if (TMath::Abs(dedx-bethe) > fRange*sigma) {
1570 p[j]=TMath::Exp(-0.5*fRange*fRange)/sigma;
1572 p[j]=TMath::Exp(-0.5*(dedx-bethe)*(dedx-bethe)/(sigma*sigma))/sigma;
1576 // Check for particles heavier than (AliPID::kSPECIES - 1)
1577 // if (dedx < (bethe + fRange*sigma)) heavy=kFALSE;
1582 for (Int_t j=0; j<AliPID::kSPECIES; j++) p[j]=1./AliPID::kSPECIES;
1583 return kDetNoSignal;
1589 //______________________________________________________________________________
1590 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeTPCProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
1593 // Compute PID response for the TPC
1596 // set flat distribution (no decision)
1597 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1599 // check quality of the track
1600 if ( (track->GetStatus()&AliVTrack::kTPCin )==0 && (track->GetStatus()&AliVTrack::kTPCout)==0 ) return kDetNoSignal;
1602 Double_t mom = track->GetTPCmomentum();
1604 Double_t dedx=track->GetTPCsignal();
1605 Bool_t mismatch=kTRUE/*, heavy=kTRUE*/;
1607 if(fTuneMConData) dedx = this->GetTPCsignalTunedOnData(track);
1609 for (Int_t j=0; j<AliPID::kSPECIESC; j++) {
1610 AliPID::EParticleType type=AliPID::EParticleType(j);
1611 Double_t bethe=fTPCResponse.GetExpectedSignal(mom,type);
1612 Double_t sigma=fTPCResponse.GetExpectedSigma(mom,track->GetTPCsignalN(),type);
1613 if (TMath::Abs(dedx-bethe) > fRange*sigma) {
1614 p[j]=TMath::Exp(-0.5*fRange*fRange)/sigma;
1616 p[j]=TMath::Exp(-0.5*(dedx-bethe)*(dedx-bethe)/(sigma*sigma))/sigma;
1622 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1623 return kDetNoSignal;
1628 //______________________________________________________________________________
1629 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeTOFProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
1632 // Compute PID response for the
1635 Double_t meanCorrFactor = 0.11/fTOFtail; // Correction factor on the mean because of the tail (should be ~ 0.1 with tail = 1.1)
1637 // set flat distribution (no decision)
1638 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1640 if ((track->GetStatus()&AliVTrack::kTOFout)==0) return kDetNoSignal;
1641 if ((track->GetStatus()&AliVTrack::kTIME)==0) return kDetNoSignal;
1643 Bool_t mismatch = kTRUE/*, heavy = kTRUE*/;
1644 for (Int_t j=0; j<AliPID::kSPECIESC; j++) {
1645 AliPID::EParticleType type=AliPID::EParticleType(j);
1646 Double_t nsigmas=GetNumberOfSigmasTOF(track,type) + meanCorrFactor;
1648 Double_t expTime = fTOFResponse.GetExpectedSignal(track,type);
1649 Double_t sig = fTOFResponse.GetExpectedSigma(track->P(),expTime,AliPID::ParticleMassZ(type));
1650 if (TMath::Abs(nsigmas) > (fRange+2)) {
1651 if(nsigmas < fTOFtail)
1652 p[j] = TMath::Exp(-0.5*(fRange+2)*(fRange+2))/sig;
1654 p[j] = TMath::Exp(-(fRange+2 - fTOFtail*0.5)*fTOFtail)/sig;
1656 if(nsigmas < fTOFtail)
1657 p[j] = TMath::Exp(-0.5*nsigmas*nsigmas)/sig;
1659 p[j] = TMath::Exp(-(nsigmas - fTOFtail*0.5)*fTOFtail)/sig;
1662 if (TMath::Abs(nsigmas)<5.){
1663 Double_t nsigmasTPC=GetNumberOfSigmasTPC(track,type);
1664 if (TMath::Abs(nsigmasTPC)<5.) mismatch=kFALSE;
1669 return kDetMismatch;
1672 // TODO: Light nuclei
1676 //______________________________________________________________________________
1677 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeTRDProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[],AliTRDPIDResponse::ETRDPIDMethod PIDmethod/*=AliTRDPIDResponse::kLQ1D*/) const
1680 // Compute PID response for the
1683 UInt_t TRDslicesForPID[2];
1684 SetTRDSlices(TRDslicesForPID,PIDmethod);
1685 // set flat distribution (no decision)
1686 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1687 if((track->GetStatus()&AliVTrack::kTRDout)==0) return kDetNoSignal;
1689 Float_t mom[6]={0.};
1690 Double_t dedx[48]={0.}; // Allocate space for the maximum number of TRD slices
1691 Int_t nslices = TRDslicesForPID[1] - TRDslicesForPID[0] + 1;
1692 AliDebug(1, Form("First Slice: %d, Last Slice: %d, Number of slices: %d", TRDslicesForPID[0], TRDslicesForPID[1], nslices));
1693 for(UInt_t ilayer = 0; ilayer < 6; ilayer++){
1694 mom[ilayer] = track->GetTRDmomentum(ilayer);
1695 for(UInt_t islice = TRDslicesForPID[0]; islice <= TRDslicesForPID[1]; islice++){
1696 dedx[ilayer*nslices+islice-TRDslicesForPID[0]] = track->GetTRDslice(ilayer, islice);
1699 fTRDResponse.GetResponse(nslices, dedx, mom, p,PIDmethod);
1703 //______________________________________________________________________________
1704 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeEMCALProbability (const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
1707 // Compute PID response for the EMCAL
1710 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1712 AliVCluster *matchedClus = NULL;
1716 Double_t EovP = -1.;
1717 Double_t fClsE = -1.;
1719 Int_t nMatchClus = -1;
1723 nMatchClus = track->GetEMCALcluster();
1725 if(nMatchClus > -1){
1729 charge = track->Charge();
1731 matchedClus = (AliVCluster*)fCurrentEvent->GetCaloCluster(nMatchClus);
1735 // matched cluster is EMCAL
1736 if(matchedClus->IsEMCAL()){
1738 fClsE = matchedClus->E();
1742 // compute the probabilities
1743 if(fEMCALResponse.ComputeEMCALProbability(nSpecies,pt,EovP,charge,p)){
1745 // in case everything is OK
1752 // in all other cases set flat distribution (no decision)
1753 for (Int_t j=0; j<nSpecies; j++) p[j] = 1./nSpecies;
1754 return kDetNoSignal;
1757 //______________________________________________________________________________
1758 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputePHOSProbability (const AliVTrack */*track*/, Int_t nSpecies, Double_t p[]) const
1761 // Compute PID response for the PHOS
1764 // set flat distribution (no decision)
1765 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1766 return kDetNoSignal;
1768 //______________________________________________________________________________
1769 AliPIDResponse::EDetPidStatus AliPIDResponse::GetComputeHMPIDProbability(const AliVTrack *track, Int_t nSpecies, Double_t p[]) const
1772 // Compute PID response for the HMPID
1774 // set flat distribution (no decision)
1775 for (Int_t j=0; j<nSpecies; j++) p[j]=1./nSpecies;
1776 if((track->GetStatus()&AliVTrack::kHMPIDpid)==0) return kDetNoSignal;
1778 track->GetHMPIDpid(p);