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 // Class further contains TRD specific cuts and QA histograms
20 // Jens Wiechula <Jens.Wiechula@cern.ch>
21 // Markus Fasel <M.Fasel@gsi.de>
26 #include <AliVParticle.h>
27 #include <AliESDtrack.h>
31 #include "AliDielectronTRDpidCut.h"
33 ClassImp(AliDielectronTRDpidCut)
35 const Double_t AliDielectronTRDpidCut::fgkVerySmall = 1e-12;
37 //___________________________________________________________________
38 AliDielectronTRDpidCut::AliDielectronTRDpidCut() :
41 , fElectronEfficiency(0.91)
46 // default constructor
48 memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
49 SetUseDefaultParameters();
52 //___________________________________________________________________
53 AliDielectronTRDpidCut::AliDielectronTRDpidCut(const char* name) :
54 AliAnalysisCuts(name,name)
56 , fElectronEfficiency(0.91)
61 // default constructor
63 memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
64 SetUseDefaultParameters();
67 //___________________________________________________________________
68 AliDielectronTRDpidCut::AliDielectronTRDpidCut(const AliDielectronTRDpidCut &ref):
69 AliAnalysisCuts(ref.GetName(),ref.GetTitle())
71 , fElectronEfficiency(ref.fElectronEfficiency)
72 , fPIDMethod(ref.fPIDMethod)
73 , fRequirePIDbit(ref.fRequirePIDbit)
78 memset(fThreshParams, 0, sizeof(Double_t) * kThreshParams);
82 //___________________________________________________________________
83 AliDielectronTRDpidCut &AliDielectronTRDpidCut::operator=(const AliDielectronTRDpidCut &ref){
85 // Assignment operator
93 //___________________________________________________________________
94 void AliDielectronTRDpidCut::Copy(TObject &ref) const {
96 // Performs the copying of the object
98 AliDielectronTRDpidCut &target = dynamic_cast<AliDielectronTRDpidCut &>(ref);
100 Bool_t defaultParameters = UseDefaultParameters();
101 target.SetUseDefaultParameters(defaultParameters);
102 target.fMinP = fMinP;
103 target.fPIDMethod = fPIDMethod;
104 target.fRequirePIDbit = fRequirePIDbit;
105 target.fElectronEfficiency = fElectronEfficiency;
106 memcpy(target.fThreshParams, fThreshParams, sizeof(Double_t) * kThreshParams);
107 AliAnalysisCuts::Copy(ref);
110 //___________________________________________________________________
111 AliDielectronTRDpidCut::~AliDielectronTRDpidCut(){
117 //______________________________________________________
118 Bool_t AliDielectronTRDpidCut::InitializePID(){
120 // InitializePID: Load TRD thresholds and create the electron efficiency axis
123 if(UseDefaultParameters()){
124 if(fPIDMethod == kLQ)
125 InitParameters1DLQ();
132 //______________________________________________________
133 Bool_t AliDielectronTRDpidCut::IsSelected(TObject *track) {
135 // Does PID for TRD alone:
136 // PID thresholds based on 90% Electron Efficiency level approximated by a linear
139 const AliESDtrack *part = dynamic_cast<const AliESDtrack *>(track);
140 if (!part) return kFALSE;
142 if (fRequirePIDbit==AliDielectronTRDpidCut::kRequire&&!(part->GetStatus()&AliESDtrack::kTRDpid)) return kFALSE;
143 if (fRequirePIDbit==AliDielectronTRDpidCut::kIfAvailable&&!(part->GetStatus()&AliESDtrack::kTRDpid)) return kTRUE;
145 Double_t p = GetP((AliVParticle*)track);
147 AliDebug(1, Form("Track momentum below %f", fMinP));
148 if(fRequirePIDbit==AliDielectronTRDpidCut::kRequire) return kFALSE;
149 if(fRequirePIDbit==AliDielectronTRDpidCut::kIfAvailable) return kTRUE;
152 Double_t electronLike = GetElectronLikelihood((AliVParticle*)track);
153 Double_t threshold = GetTRDthresholds(fElectronEfficiency, p);
154 AliDebug(1, Form("Threshold: %f\n", threshold));
155 if(electronLike > threshold){
162 //___________________________________________________________________
163 Double_t AliDielectronTRDpidCut::GetTRDthresholds(Double_t electronEff, Double_t p) const {
165 // Return momentum dependent and electron efficiency dependent TRD thresholds
168 GetParameters(electronEff, params);
169 Double_t threshold = 1. - params[0] - params[1] * p - params[2] * TMath::Exp(-params[3] * p);
170 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
173 //___________________________________________________________________
174 void AliDielectronTRDpidCut::SetThresholdParameters(Double_t electronEff, Double_t *params){
176 // Set threshold parameters for the given bin
178 if(electronEff >= 1. || electronEff < 0.7) return;
179 Int_t effbin = static_cast<Int_t>((electronEff - 0.7)/0.05);
180 memcpy(&fThreshParams[effbin * 4], params, sizeof(Double_t) * 4);
181 SetUseDefaultParameters(kFALSE);
184 //___________________________________________________________________
185 void AliDielectronTRDpidCut::InitParameters(){
187 // Fill the Parameters into an array
190 AliDebug(2, "Loading threshold Parameter");
191 // Parameters for 6 Layers
192 fThreshParams[0] = -0.001839; // 0.7 electron eff
193 fThreshParams[1] = 0.000276;
194 fThreshParams[2] = 0.044902;
195 fThreshParams[3] = 1.726751;
196 fThreshParams[4] = -0.002405; // 0.75 electron eff
197 fThreshParams[5] = 0.000372;
198 fThreshParams[6] = 0.061775;
199 fThreshParams[7] = 1.739371;
200 fThreshParams[8] = -0.003178; // 0.8 electron eff
201 fThreshParams[9] = 0.000521;
202 fThreshParams[10] = 0.087585;
203 fThreshParams[11] = 1.749154;
204 fThreshParams[12] = -0.004058; // 0.85 electron eff
205 fThreshParams[13] = 0.000748;
206 fThreshParams[14] = 0.129583;
207 fThreshParams[15] = 1.782323;
208 fThreshParams[16] = -0.004967; // 0.9 electron eff
209 fThreshParams[17] = 0.001216;
210 fThreshParams[18] = 0.210128;
211 fThreshParams[19] = 1.807665;
212 fThreshParams[20] = -0.000996; // 0.95 electron eff
213 fThreshParams[21] = 0.002627;
214 fThreshParams[22] = 0.409099;
215 fThreshParams[23] = 1.787076;
218 //___________________________________________________________________
219 void AliDielectronTRDpidCut::InitParameters1DLQ(){
221 // Init Parameters for 1DLQ PID (M. Fasel, Sept. 6th, 2010)
224 // Parameters for 6 Layers
225 AliDebug(2, Form("Loading threshold parameter for Method 1DLQ"));
226 fThreshParams[0] = -0.02241; // 0.7 electron eff
227 fThreshParams[1] = 0.05043;
228 fThreshParams[2] = 0.7925;
229 fThreshParams[3] = 2.625;
230 fThreshParams[4] = 0.07438; // 0.75 electron eff
231 fThreshParams[5] = 0.05158;
232 fThreshParams[6] = 2.864;
233 fThreshParams[7] = 4.356;
234 fThreshParams[8] = 0.1977; // 0.8 electron eff
235 fThreshParams[9] = 0.05956;
236 fThreshParams[10] = 2.853;
237 fThreshParams[11] = 3.713;
238 fThreshParams[12] = 0.5206; // 0.85 electron eff
239 fThreshParams[13] = 0.03077;
240 fThreshParams[14] = 2.966;
241 fThreshParams[15] = 4.07;
242 fThreshParams[16] = 0.8808; // 0.9 electron eff
243 fThreshParams[17] = 0.002092;
244 fThreshParams[18] = 1.17;
245 fThreshParams[19] = 4.506;
246 fThreshParams[20] = 1.; // 0.95 electron eff
247 fThreshParams[21] = 0.;
248 fThreshParams[22] = 0.;
249 fThreshParams[23] = 0.;
253 //___________________________________________________________________
254 void AliDielectronTRDpidCut::RenormalizeElPi(const Double_t *likein, Double_t *likeout) const {
256 // Renormalize likelihoods for electrons and pions neglecting the
257 // likelihoods for protons, kaons and muons
259 memset(likeout, 0, sizeof(Double_t) * AliPID::kSPECIES);
260 Double_t norm = likein[AliPID::kElectron] + likein[AliPID::kPion];
261 if(norm == 0.) norm = 1.; // Safety
262 likeout[AliPID::kElectron] = likein[AliPID::kElectron] / norm;
263 likeout[AliPID::kPion] = likein[AliPID::kPion] / norm;
266 //___________________________________________________________________
267 void AliDielectronTRDpidCut::GetParameters(Double_t electronEff, Double_t *parameters) const {
269 // return parameter set for the given efficiency bin
271 Int_t effbin = static_cast<Int_t>((electronEff - 0.7)/0.05);
272 memcpy(parameters, fThreshParams + effbin * 4, sizeof(Double_t) * 4);
275 //___________________________________________________________________
276 Double_t AliDielectronTRDpidCut::GetElectronLikelihood(const AliVParticle *track) const {
278 // Get TRD likelihoods for ESD respectively AOD tracks
280 Double_t pidProbs[AliPID::kSPECIES]; memset(pidProbs, 0, sizeof(Double_t) * AliPID::kSPECIES);
281 const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
282 if(esdtrack) esdtrack->GetTRDpid(pidProbs);
283 if(!IsRenormalizeElPi()) return pidProbs[AliPID::kElectron];
284 Double_t probsNew[AliPID::kSPECIES];
285 RenormalizeElPi(pidProbs, probsNew);
286 return probsNew[AliPID::kElectron];
289 //___________________________________________________________________
290 Double_t AliDielectronTRDpidCut::GetP(const AliVParticle *track) const {
292 // Get the Momentum in the TRD
295 const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
296 if(esdtrack) p = esdtrack->GetOuterParam() ? esdtrack->GetOuterParam()->P() : esdtrack->P();
300 //___________________________________________________________________
301 Double_t AliDielectronTRDpidCut::GetChargeLayer(const AliVParticle *track, UInt_t layer) const {
303 // Get the Charge in a single TRD layer
305 if(layer >= 6) return 0.;
306 Double_t charge = 0.;
307 const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
309 for(Int_t islice = 0; islice < esdtrack->GetNumberOfTRDslices(); islice++)
310 charge += esdtrack->GetTRDslice(static_cast<UInt_t>(layer), islice);
314 //___________________________________________________________________
315 void AliDielectronTRDpidCut::GetTRDmomenta(const AliVParticle *track, Double_t *mom) const {
317 // Fill Array with momentum information at the TRD tracklet
319 const AliESDtrack *esdtrack = dynamic_cast<const AliESDtrack *>(track);
321 for(Int_t itl = 0; itl < 6; itl++)
322 mom[itl] = esdtrack->GetTRDmomentum(itl);
325 //___________________________________________________________________
326 Double_t AliDielectronTRDpidCut::GetTRDSignalV1(const AliESDtrack *track, Float_t truncation) const {
328 // Calculation of the TRD Signal via truncated mean
329 // Method 1: Take all Slices available
331 // Order them in increasing order
332 // Cut out the upper third
333 // Calculate mean over the last 2/3 slices
335 const Int_t kNSlices = 48;
336 const Int_t kSlicePerLayer = 7;
337 // Weight the slice to equalize the MPV of the dQ/dl-distribution per slice to the one in the first slice
338 // Pions are used as reference for the equalization
339 const Double_t kWeightSlice[8] = {1., 2.122, 1.8, 1.635, 1.595, 1.614, 1.16, 7.0};
340 AliDebug(3, Form("Number of Tracklets: %d\n", track->GetTRDntrackletsPID()));
341 Double_t trdSlices[kNSlices], tmp[kNSlices];
344 for(Int_t idet = 0; idet < 6; idet++)
345 for(Int_t islice = 0; islice < kSlicePerLayer; islice++){
346 AliDebug(2, Form("Chamber[%d], Slice[%d]: TRDSlice = %f", idet, islice, track->GetTRDslice(idet, islice)));
347 if(TMath::Abs(track->GetTRDslice(idet, islice)) < fgkVerySmall) continue;;
348 trdSlices[icnt++] = track->GetTRDslice(idet, islice) * kWeightSlice[islice];
350 AliDebug(1, Form("Number of Slices: %d\n", icnt));
351 if(icnt < 6) return 0.; // We need at least 6 Slices for the truncated mean
352 TMath::Sort(icnt, trdSlices, indices, kFALSE);
353 memcpy(tmp, trdSlices, sizeof(Double_t) * icnt);
354 for(Int_t ien = 0; ien < icnt; ien++)
355 trdSlices[ien] = tmp[indices[ien]];
356 Double_t trdSignal = TMath::Mean(static_cast<Int_t>(static_cast<Float_t>(icnt) * truncation), trdSlices);
357 Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
358 AliDebug(3, Form("PID Meth. 1: p[%f], TRDSignal[%f]", mom, trdSignal));
362 //___________________________________________________________________
363 Double_t AliDielectronTRDpidCut::GetTRDSignalV2(const AliESDtrack *track, Float_t truncation) const {
365 // Calculation of the TRD Signal via truncated mean
366 // Method 2: Take only first 5 slices per chamber
367 // Order them in increasing order
368 // Cut out upper half
369 // Now do mean with the reamining 3 slices per chamber
371 const Double_t kWeightSlice[8] = {1., 2.122, 1.8, 1.635, 1.595, 1.614, 1.16, 7.0};
372 const Int_t kLayers = 6;
373 const Int_t kSlicesLow = 6;
374 const Int_t kSlicesHigh = 1;
375 Double_t trdSlicesLowTime[kLayers*kSlicesLow], trdSlicesRemaining[kLayers*(kSlicesHigh + kSlicesLow)];
376 Int_t indices[kLayers*kSlicesLow];
377 Int_t cntLowTime=0, cntRemaining = 0;
378 for(Int_t idet = 0; idet < 6; idet++)
379 for(Int_t islice = 0; islice < kSlicesLow+kSlicesHigh; islice++){
380 if(TMath::Abs(track->GetTRDslice(idet, islice)) < fgkVerySmall) continue;;
381 if(islice < kSlicesLow){
382 AliDebug(3, Form("Part 1, Det[%d], Slice[%d], TRDSlice: %f", idet, islice, track->GetTRDslice(idet, islice)));
383 trdSlicesLowTime[cntLowTime++] = track->GetTRDslice(idet, islice) * kWeightSlice[islice];
385 AliDebug(3, Form("Part 1, Det[%d], Slice[%d], TRDSlice: %f", idet, islice, track->GetTRDslice(idet, islice)));
386 trdSlicesRemaining[cntRemaining++] = track->GetTRDslice(idet, islice) * kWeightSlice[islice];
389 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
390 TMath::Sort(cntLowTime, trdSlicesLowTime, indices, kFALSE);
391 // Fill the second array with the lower half of the first time bins
392 for(Int_t ien = 0; ien < static_cast<Int_t>(static_cast<Float_t>(cntLowTime) * truncation); ien++)
393 trdSlicesRemaining[cntRemaining++] = trdSlicesLowTime[indices[ien]];
394 Double_t trdSignal = TMath::Mean(cntRemaining, trdSlicesRemaining);
395 Double_t mom = track->GetOuterParam() ? track->GetOuterParam()->P() : -1;
396 AliDebug(3, Form("PID Meth. 2: p[%f], TRDSignal[%f]", mom, trdSignal));