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 **************************************************************************/
17 // Implements the abstract base class AliHFEpidbase
18 // Make PID does the PID decision
19 // Class further contains TRD specific cuts and QA histograms
22 // Markus Fasel <M.Fasel@gsi.de>
26 #include <THnSparse.h>
30 #include "AliAODpidUtil.h"
31 #include "AliAODPid.h"
32 #include "AliAODTrack.h"
33 #include "AliAODMCParticle.h"
34 #include "AliESDtrack.h"
35 #include "AliESDpid.h"
37 #include "AliMCParticle.h"
40 #include "AliHFEpidQAmanager.h"
41 #include "AliHFEpidTRD.h"
43 ClassImp(AliHFEpidTRD)
45 const Double_t AliHFEpidTRD::fgkVerySmall = 1e-12;
47 //___________________________________________________________________
48 AliHFEpidTRD::AliHFEpidTRD() :
51 , fElectronEfficiency(0.91)
55 // default constructor
59 //___________________________________________________________________
60 AliHFEpidTRD::AliHFEpidTRD(const char* name) :
63 , fElectronEfficiency(0.91)
67 // default constructor
69 memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
72 //___________________________________________________________________
73 AliHFEpidTRD::AliHFEpidTRD(const AliHFEpidTRD &ref):
76 , fElectronEfficiency(ref.fElectronEfficiency)
77 , fPIDMethod(ref.fPIDMethod)
82 memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
86 //___________________________________________________________________
87 AliHFEpidTRD &AliHFEpidTRD::operator=(const AliHFEpidTRD &ref){
89 // Assignment operator
97 //___________________________________________________________________
98 void AliHFEpidTRD::Copy(TObject &ref) const {
100 // Performs the copying of the object
102 AliHFEpidTRD &target = dynamic_cast<AliHFEpidTRD &>(ref);
104 target.fMinP = fMinP;
105 target.fPIDMethod = fPIDMethod;
106 target.fElectronEfficiency = fElectronEfficiency;
107 memcpy(target.fThreshParams, fThreshParams, sizeof(Double_t) * kThreshParams);
108 AliHFEpidBase::Copy(ref);
111 //___________________________________________________________________
112 AliHFEpidTRD::~AliHFEpidTRD(){
118 //______________________________________________________
119 Bool_t AliHFEpidTRD::InitializePID(){
121 // InitializePID: Load TRD thresholds and create the electron efficiency axis
124 if(fPIDMethod == kLQ)
125 InitParameters1DLQ();
131 //______________________________________________________
132 Int_t AliHFEpidTRD::IsSelected(const AliHFEpidObject *track, AliHFEpidQAmanager *pidqa) const {
134 // Does PID for TRD alone:
135 // PID thresholds based on 90% Electron Efficiency level approximated by a linear
138 AliDebug(1, "Applying TRD PID");
139 if((!fESDpid && track->IsESDanalysis()) || (!fAODpid && track->IsAODanalysis())){
140 AliDebug(1, "Cannot process track");
144 AliHFEpidObject::AnalysisType_t anatype = track->IsESDanalysis() ? AliHFEpidObject::kESDanalysis: AliHFEpidObject::kAODanalysis;
145 Double_t p = GetP(track->GetRecTrack(), anatype);
147 AliDebug(1, Form("Track momentum below %f", fMinP));
151 if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kBeforePID);
152 Double_t electronLike = GetElectronLikelihood(track->GetRecTrack(), anatype);
153 Double_t threshold = GetTRDthresholds(fElectronEfficiency, p);
154 AliDebug(1, Form("Threshold: %f\n", threshold));
155 if(electronLike > threshold){
156 if(pidqa) pidqa->ProcessTrack(track, AliHFEpid::kTRDpid, AliHFEdetPIDqa::kAfterPID);
163 //___________________________________________________________________
164 Double_t AliHFEpidTRD::GetTRDthresholds(Double_t electronEff, Double_t p) const {
166 // Return momentum dependent and electron efficiency dependent TRD thresholds
169 GetParameters(electronEff, params);
170 Double_t threshold = 1. - params[0] - params[1] * p - params[2] * TMath::Exp(-params[3] * p);
171 return TMath::Max(TMath::Min(threshold, 0.99), 0.2); // truncate the threshold upperwards to 0.999 and lowerwards to 0.2 and exclude unphysical values
174 //___________________________________________________________________
175 void AliHFEpidTRD::InitParameters(){
177 // Fill the Parameters into an array
180 AliDebug(2, "Loading threshold Parameter");
181 // Parameters for 6 Layers
182 fThreshParams[0] = -0.001839; // 0.7 electron eff
183 fThreshParams[1] = 0.000276;
184 fThreshParams[2] = 0.044902;
185 fThreshParams[3] = 1.726751;
186 fThreshParams[4] = -0.002405; // 0.75 electron eff
187 fThreshParams[5] = 0.000372;
188 fThreshParams[6] = 0.061775;
189 fThreshParams[7] = 1.739371;
190 fThreshParams[8] = -0.003178; // 0.8 electron eff
191 fThreshParams[9] = 0.000521;
192 fThreshParams[10] = 0.087585;
193 fThreshParams[11] = 1.749154;
194 fThreshParams[12] = -0.004058; // 0.85 electron eff
195 fThreshParams[13] = 0.000748;
196 fThreshParams[14] = 0.129583;
197 fThreshParams[15] = 1.782323;
198 fThreshParams[16] = -0.004967; // 0.9 electron eff
199 fThreshParams[17] = 0.001216;
200 fThreshParams[18] = 0.210128;
201 fThreshParams[19] = 1.807665;
202 fThreshParams[20] = -0.000996; // 0.95 electron eff
203 fThreshParams[21] = 0.002627;
204 fThreshParams[22] = 0.409099;
205 fThreshParams[23] = 1.787076;
208 //___________________________________________________________________
209 void AliHFEpidTRD::InitParameters1DLQ(){
211 // Init Parameters for 1DLQ PID (M. Fasel, Sept. 6th, 2010)
214 // Parameters for 6 Layers
215 AliDebug(2, Form("Loading threshold parameter for Method 1DLQ"));
216 fThreshParams[0] = -0.02241; // 0.7 electron eff
217 fThreshParams[1] = 0.05043;
218 fThreshParams[2] = 0.7925;
219 fThreshParams[3] = 2.625;
220 fThreshParams[4] = 0.07438; // 0.75 electron eff
221 fThreshParams[5] = 0.05158;
222 fThreshParams[6] = 2.864;
223 fThreshParams[7] = 4.356;
224 fThreshParams[8] = 0.1977; // 0.8 electron eff
225 fThreshParams[9] = 0.05956;
226 fThreshParams[10] = 2.853;
227 fThreshParams[11] = 3.713;
228 fThreshParams[12] = 0.5206; // 0.85 electron eff
229 fThreshParams[13] = 0.03077;
230 fThreshParams[14] = 2.966;
231 fThreshParams[15] = 4.07;
232 fThreshParams[16] = 0.8808; // 0.9 electron eff
233 fThreshParams[17] = 0.002092;
234 fThreshParams[18] = 1.17;
235 fThreshParams[19] = 4.506;
236 fThreshParams[20] = 1.; // 0.95 electron eff
237 fThreshParams[21] = 0.;
238 fThreshParams[22] = 0.;
239 fThreshParams[23] = 0.;
243 //___________________________________________________________________
244 void AliHFEpidTRD::GetParameters(Double_t electronEff, Double_t *parameters) const {
246 // return parameter set for the given efficiency bin
248 Int_t effbin = static_cast<Int_t>((electronEff - 0.7)/0.05);
249 memcpy(parameters, fThreshParams + effbin * 4, sizeof(Double_t) * 4);
252 //___________________________________________________________________
253 Double_t AliHFEpidTRD::GetElectronLikelihood(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType) const {
255 // Get TRD likelihoods for ESD respectively AOD tracks
257 Double_t pidProbs[AliPID::kSPECIES]; memset(pidProbs, 0, sizeof(Double_t) * AliPID::kSPECIES);
258 if(anaType == AliHFEpidObject::kESDanalysis){
259 const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
260 esdtrack->GetTRDpid(pidProbs);
262 const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
263 fAODpid->MakeTRDPID(const_cast<AliAODTrack *>(aodtrack), pidProbs);
265 return pidProbs[AliPID::kElectron];
268 //___________________________________________________________________
269 Double_t AliHFEpidTRD::GetP(const AliVParticle *track, AliHFEpidObject::AnalysisType_t anaType) const {
271 // Get the Momentum in the TRD
274 if(anaType == AliHFEpidObject::kESDanalysis){
275 const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
276 p = esdtrack->GetOuterParam() ? esdtrack->GetOuterParam()->P() : esdtrack->P();
278 const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
284 //___________________________________________________________________
285 Double_t AliHFEpidTRD::GetChargeLayer(const AliVParticle *track, UInt_t layer, AliHFEpidObject::AnalysisType_t anaType) const {
287 // Get the Charge in a single TRD layer
289 if(layer >= 6) return 0.;
290 Double_t charge = 0.;
291 if(anaType == AliHFEpidObject::kESDanalysis){
292 const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
293 for(Int_t islice = 0; islice < esdtrack->GetNumberOfTRDslices(); islice++) charge += esdtrack->GetTRDslice(static_cast<UInt_t>(layer), islice);
295 const AliAODTrack *aodtrack = dynamic_cast<const AliAODTrack *>(track);
296 AliAODPid *aoddetpid = aodtrack->GetDetPid();
297 for(Int_t islice = 0; islice < aoddetpid->GetTRDnSlices(); islice++) charge += aoddetpid->GetTRDsignal()[layer * aoddetpid->GetTRDnSlices() + islice];
302 //___________________________________________________________________
303 Double_t AliHFEpidTRD::GetTRDSignalV1(const AliESDtrack *track) const {
305 // Calculation of the TRD Signal via truncated mean
306 // Method 1: Take all Slices available
308 // Order them in increasing order
309 // Cut out the upper third
310 // Calculate mean over the last 2/3 slices
312 const Int_t kNSlices = 48;
313 AliDebug(3, Form("Number of Tracklets: %d\n", track->GetTRDpidQuality()));
314 Double_t trdSlices[kNSlices], tmp[kNSlices];
317 for(Int_t idet = 0; idet < 6; idet++)
318 for(Int_t islice = 0; islice < 8; islice++){
319 AliDebug(2, Form("Chamber[%d], Slice[%d]: TRDSlice = %f", idet, islice, track->GetTRDslice(idet, islice)));
320 if(TMath::Abs(track->GetTRDslice(idet, islice)) < fgkVerySmall) continue;;
321 trdSlices[icnt++] = track->GetTRDslice(idet, islice);
323 AliDebug(1, Form("Number of Slices: %d\n", icnt));
324 if(icnt < 6) return 0.; // We need at least 6 Slices for the truncated mean
325 TMath::Sort(icnt, trdSlices, indices, kFALSE);
326 memcpy(tmp, trdSlices, sizeof(Double_t) * icnt);
327 for(Int_t ien = 0; ien < icnt; ien++)
328 trdSlices[ien] = tmp[indices[ien]];
329 Double_t trdSignal = TMath::Mean(static_cast<Int_t>(static_cast<Double_t>(icnt) * 2./3.), trdSlices);
330 Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
331 AliDebug(3, Form("PID Meth. 1: p[%f], TRDSignal[%f]", mom, trdSignal));
335 //___________________________________________________________________
336 Double_t AliHFEpidTRD::GetTRDSignalV2(const AliESDtrack *track) const {
338 // Calculation of the TRD Signal via truncated mean
339 // Method 2: Take only first 5 slices per chamber
340 // Order them in increasing order
341 // Cut out upper half
342 // Now do mean with the reamining 3 slices per chamber
344 Double_t trdSlicesLowTime[30], trdSlicesRemaining[32];
346 Int_t cntLowTime=0, cntRemaining = 0;
347 for(Int_t idet = 0; idet < 6; idet++)
348 for(Int_t islice = 0; islice < 8; islice++){
349 if(TMath::Abs(track->GetTRDslice(idet, islice)) < fgkVerySmall) continue;;
351 AliDebug(3, Form("Part 1, Det[%d], Slice[%d], TRDSlice: %f", idet, islice, track->GetTRDslice(idet, islice)));
352 trdSlicesLowTime[cntLowTime++] = track->GetTRDslice(idet, islice);
354 AliDebug(3, Form("Part 1, Det[%d], Slice[%d], TRDSlice: %f", idet, islice, track->GetTRDslice(idet, islice)));
355 trdSlicesRemaining[cntRemaining++] = track->GetTRDslice(idet, islice);
358 if(cntLowTime < 4 || cntRemaining < 2) return 0.; // Min. Number of Slices at high time is 2 (matches with 1 layer), for the truncated mean we need at least 4 Slices
359 TMath::Sort(cntLowTime, trdSlicesLowTime, indices, kFALSE);
360 // Fill the second array with the lower half of the first time bins
361 for(Int_t ien = 0; ien < static_cast<Int_t>(static_cast<Double_t>(cntLowTime) * 0.5); ien++)
362 trdSlicesRemaining[cntRemaining++] = trdSlicesLowTime[indices[ien]];
363 Double_t trdSignal = TMath::Mean(cntRemaining, trdSlicesRemaining);
364 Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
365 AliDebug(3, Form("PID Meth. 2: p[%f], TRDSignal[%f]", mom, trdSignal));