]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG3/hfe/AliHFEtrdPIDqa.cxx
Try remove macro
[u/mrichter/AliRoot.git] / PWG3 / hfe / AliHFEtrdPIDqa.cxx
CommitLineData
c04c80e6 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// QA class for TRD PID
17// Plot Pion Efficiency at x electron efficiency
18// Calculate the threshold parametrisation and save
19// them in a root file
20//
21// Author:
22// Markus Fasel <M.Fasel@gsi.de>
23//
24#include <TAxis.h>
bf892a6a 25#include <TBrowser.h>
c04c80e6 26#include <TClass.h>
27#include <TCanvas.h>
28#include <TF1.h>
29#include <TFile.h>
30#include <TGraph.h>
31#include <TGraphErrors.h>
32#include <THnSparse.h>
33#include <TH1.h>
34#include <TH2.h>
35#include <TIterator.h>
36#include <TLegend.h>
37#include <TList.h>
38#include <TMath.h>
39#include <TObjArray.h>
40#include <TString.h>
41
42#include "AliAODTrack.h"
43#include "AliAODPid.h"
44#include "AliESDtrack.h"
45#include "AliHFEtrdPIDqa.h"
46#include "AliHFEtools.h"
47#include "AliHFEpidTRD.h"
48#include "AliLog.h"
49
50ClassImp(AliHFEtrdPIDqa)
51
52const Double_t AliHFEtrdPIDqa::fgkElectronEff[kNElectronEffs] = {0.7,0.75, 0.8, 0.85, 0.9, 0.95};
53//_______________________________________________________________
54// Definition of the common binning
55const Int_t AliHFEtrdPIDqa::fgkNBinsCommon[kQuantitiesCommon] = {
56 AliPID::kSPECIES + 1, // species
57 40, // p-bins
58 AliESDtrack::kTRDnPlanes + 1 // tracklets including 0
59};
60const Double_t AliHFEtrdPIDqa::fgkMinBinCommon[kQuantitiesCommon] = {
61 -1, // species
62 0.1, // p-bins
63 0 // tracklets including 0
64};
65
66const Double_t AliHFEtrdPIDqa::fgkMaxBinCommon[kQuantitiesCommon] = {
67 AliPID::kSPECIES, // species
68 10., // p-bins
69 AliESDtrack::kTRDnPlanes + 1 // tracklets including 0
70};
71//_______________________________________________________________
72
73//__________________________________________________________________
74AliHFEtrdPIDqa::AliHFEtrdPIDqa():
75 TNamed("trdPIDqa", ""),
76 fTRDpid(NULL),
bf892a6a 77 fHistos(NULL),
c04c80e6 78 fPionEfficiencies(NULL),
79 fProtonEfficiencies(NULL),
80 fKaonEfficiencies(NULL),
e3ae862b 81 fThresholds(NULL),
e156c3bb 82 fShowMessage(kFALSE),
83 fTotalChargeInSlice0(kFALSE)
c04c80e6 84{
85 //
86 // Default Constructor
87 //
88}
89
90//__________________________________________________________________
91AliHFEtrdPIDqa::AliHFEtrdPIDqa(const Char_t *name):
92 TNamed(name, ""),
93 fTRDpid(NULL),
bf892a6a 94 fHistos(NULL),
c04c80e6 95 fPionEfficiencies(NULL),
96 fProtonEfficiencies(NULL),
97 fKaonEfficiencies(NULL),
e3ae862b 98 fThresholds(NULL),
e156c3bb 99 fShowMessage(kFALSE),
100 fTotalChargeInSlice0(kFALSE)
c04c80e6 101{
102 //
103 // Main Constructor
104 //
105}
106
107//__________________________________________________________________
108AliHFEtrdPIDqa::AliHFEtrdPIDqa(const AliHFEtrdPIDqa &ref):
109 TNamed(ref),
110 fTRDpid(NULL),
bf892a6a 111 fHistos(NULL),
c04c80e6 112 fPionEfficiencies(NULL),
113 fProtonEfficiencies(NULL),
114 fKaonEfficiencies(NULL),
e3ae862b 115 fThresholds(NULL),
e156c3bb 116 fShowMessage(kFALSE),
117 fTotalChargeInSlice0(ref.fTotalChargeInSlice0)
c04c80e6 118{
119 //
120 // Copy constructor
121 //
122 ref.Copy(*this);
123}
124
125//__________________________________________________________________
126AliHFEtrdPIDqa &AliHFEtrdPIDqa::operator=(const AliHFEtrdPIDqa &ref){
127 //
128 // Assignment operator
129 //
130 if(this != &ref)
131 ref.Copy(*this);
132 return *this;
133}
134
135//__________________________________________________________________
136AliHFEtrdPIDqa::~AliHFEtrdPIDqa(){
137 //
138 // Destructor
139 //
140 if(fTRDpid) delete fTRDpid;
bf892a6a 141 if(fHistos) delete fHistos;
c04c80e6 142 if(fPionEfficiencies) delete fPionEfficiencies;
143 if(fProtonEfficiencies) delete fProtonEfficiencies;
144 if(fKaonEfficiencies) delete fKaonEfficiencies;
145}
146
147//__________________________________________________________________
148void AliHFEtrdPIDqa::Copy(TObject &ref) const{
149 //
150 // Copies content of this object into object ref
151 //
152 TNamed::Copy(ref);
153
154 AliHFEtrdPIDqa &target = dynamic_cast<AliHFEtrdPIDqa &>(ref);
155 target.fTRDpid = fTRDpid;
e156c3bb 156 target.fHistos = dynamic_cast<AliHFEcollection *>(fHistos->Clone());
157 target.fTotalChargeInSlice0 = fTotalChargeInSlice0;
c04c80e6 158}
159
160//__________________________________________________________________
161Long64_t AliHFEtrdPIDqa::Merge(TCollection *coll){
162 //
163 // Merge objects
164 //
165 if(!coll) return 0;
166 if(coll->IsEmpty()) return 1;
167
bf892a6a 168 AliHFEtrdPIDqa *refQA = NULL;
169 TIter it(coll);
c04c80e6 170 TObject *o = NULL;
171 Long64_t count = 0;
bf892a6a 172 TList listHistos;
173 while((o = it())){
174 refQA = dynamic_cast<AliHFEtrdPIDqa *>(o);
c04c80e6 175 if(!refQA) continue;
176
bf892a6a 177 listHistos.Add(refQA->fHistos);
178 count++;
c04c80e6 179 }
bf892a6a 180 fHistos->Merge(&listHistos);
c04c80e6 181 return count+1;
182}
183
bf892a6a 184//__________________________________________________________________
185void AliHFEtrdPIDqa::Browse(TBrowser *b){
186 //
187 // Enable Browser functionality
188 //
189 if(b){
190 // Add objects to the browser
191 if(fHistos) b->Add(fHistos, fHistos->GetName());
192 if(fPionEfficiencies) b->Add(fPionEfficiencies, "Pion Efficiencies");
193 if(fProtonEfficiencies) b->Add(fProtonEfficiencies, "Proton Efficiencies");
194 if(fKaonEfficiencies) b->Add(fKaonEfficiencies, "Kaon Efficiencies");
195 if(fThresholds) b->Add(fThresholds, "Thresholds");
196 }
197}
198
c04c80e6 199//__________________________________________________________________
200void AliHFEtrdPIDqa::Init(){
201 //
202 // Initialize Object
203 //
bf892a6a 204
205 fHistos = new AliHFEcollection("TRDqa", "Histos for TRD QA");
c04c80e6 206
207 CreateLikelihoodHistogram();
208 CreateQAHistogram();
209 CreatedEdxHistogram();
210 CreateHistoTruncatedMean();
211
212 fTRDpid = new AliHFEpidTRD("QAtrdPID");
213}
214
215//__________________________________________________________________
216void AliHFEtrdPIDqa::CreateLikelihoodHistogram(){
217 //
218 // Create Histogram for TRD Likelihood Studies
219 //
220 Int_t nbins[kQuantitiesLike]; memcpy(nbins, fgkNBinsCommon, sizeof(Int_t) * kQuantitiesCommon);
221 nbins[kElectronLike] = 100;
222 Double_t binMin[kQuantitiesLike]; memcpy(binMin, fgkMinBinCommon, sizeof(Double_t) * kQuantitiesCommon);
223 Double_t binMax[kQuantitiesLike]; memcpy(binMax, fgkMaxBinCommon, sizeof(Double_t) * kQuantitiesCommon);
224 binMin[kElectronLike] = 0.;
225 binMax[kElectronLike] = 1.;
226
bf892a6a 227 fHistos->CreateTHnSparse("fLikeTRD","TRD Likelihood Studies", kQuantitiesLike, nbins, binMin, binMax);
228 fHistos->BinLogAxis("fLikeTRD", kP);
c04c80e6 229}
230
231//__________________________________________________________________
232void AliHFEtrdPIDqa::CreateQAHistogram(){
233 //
234 // Create Histogram for Basic TRD PID QA
235 //
236 AliDebug(1, "Called");
237 Int_t nbins[kQuantitiesQA]; memcpy(nbins, fgkNBinsCommon, sizeof(Int_t) * kQuantitiesCommon);
238 nbins[kNonZeroTrackletCharge] = AliESDtrack::kTRDnPlanes + 1;
239 nbins[kNClusters] = 200;
240 Double_t binMin[kQuantitiesQA]; memcpy(binMin, fgkMinBinCommon, sizeof(Double_t) * kQuantitiesCommon);
241 binMin[kNonZeroTrackletCharge] = 0.;
242 binMin[kNClusters] = 0.;
243 Double_t binMax[kQuantitiesQA]; memcpy(binMax, fgkMaxBinCommon, sizeof(Double_t) * kQuantitiesCommon);
244 binMax[kNonZeroTrackletCharge] = AliESDtrack::kTRDnPlanes + 1.;
245 binMax[kNClusters] = 200.;
246
bf892a6a 247 fHistos->CreateTHnSparse("fQAtrack","TRD QA Histogram", kQuantitiesQA, nbins, binMin, binMax);
248 fHistos->BinLogAxis("fQAtrack", kP);
c04c80e6 249}
250
251//__________________________________________________________________
252void AliHFEtrdPIDqa::CreatedEdxHistogram(){
253 //
254 // Create QA histogram for dEdx investigations
255 //
256 AliDebug(1, "Called");
257 Int_t nbins[kQuantitiesdEdx]; memcpy(nbins, fgkNBinsCommon, sizeof(Int_t) * kQuantitiesCommon);
258 nbins[kdEdx] = 100;
3a72645a 259 nbins[kNclusters] = 261;
260 nbins[kNonZeroSlices] = 9;
c04c80e6 261 Double_t binMin[kQuantitiesdEdx]; memcpy(binMin, fgkMinBinCommon, sizeof(Double_t) * kQuantitiesCommon);
3a72645a 262 binMin[kdEdx] = 0.;
263 binMin[kNclusters] = 0;
6555e2ad 264 binMin[kNonZeroSlices] = 0.;
c04c80e6 265 Double_t binMax[kQuantitiesdEdx]; memcpy(binMax, fgkMaxBinCommon, sizeof(Double_t) * kQuantitiesCommon);
266 binMax[kdEdx] = 100000.;
3a72645a 267 binMax[kNclusters] = 260.;
268 binMax[kNonZeroSlices] = 8.;
c04c80e6 269
bf892a6a 270 fHistos->CreateTHnSparse("fQAdEdx","TRD summed dEdx", kQuantitiesdEdx, nbins, binMin, binMax);
271 fHistos->BinLogAxis("fQAdEdx", kP);
272 fHistos->Sumw2("fQAdEdx");
c04c80e6 273}
274
275//__________________________________________________________________
276void AliHFEtrdPIDqa::CreateHistoTruncatedMean(){
277 //
278 // Create Histogram for Basic TRD PID QA
279 //
280 AliDebug(1, "Called");
281 Int_t nbins[kQuantitiesTruncMean]; memcpy(nbins, fgkNBinsCommon, sizeof(Int_t) * kQuantitiesCommon);
282 nbins[kTPCdEdx] = 600;
283 nbins[kTRDdEdxMethod1] = 1000;
284 nbins[kTRDdEdxMethod2] = 1000;
285 Double_t binMin[kQuantitiesTruncMean]; memcpy(binMin, fgkMinBinCommon, sizeof(Double_t) * kQuantitiesCommon);
286 binMin[kTPCdEdx] = 0.;
287 binMin[kTRDdEdxMethod1] = 0.;
288 binMin[kTRDdEdxMethod2] = 0.;
289 Double_t binMax[kQuantitiesTruncMean]; memcpy(binMax, fgkMaxBinCommon, sizeof(Double_t) * kQuantitiesCommon);
290 binMax[kTPCdEdx] = 600;
291 binMax[kTRDdEdxMethod1] = 20000.;
292 binMax[kTRDdEdxMethod2] = 20000.;
293
bf892a6a 294 fHistos->CreateTHnSparse("fTRDtruncMean","TRD TruncatedMean studies", kQuantitiesTruncMean, nbins, binMin, binMax);
295 fHistos->BinLogAxis("fTRDtruncMean", kP);
e156c3bb 296 fHistos->CreateTH2F("fTRDslicesPions","TRD dEdx per slice for Pions", 8, 0, 8, 2000, 0, 8000);
297 fHistos->CreateTH2F("fTRDslicesElectrons","TRD dEdx per slice for Electrons", 8, 0, 8, 2000, 0, 8000);
c04c80e6 298}
299
300
301//__________________________________________________________________
c2690925 302void AliHFEtrdPIDqa::ProcessTracks(const TObjArray * const tracks, Int_t species){
c04c80e6 303 //
304 // Process Electron Tracks
305 //
306 if(species < -1 || species >= AliPID::kSPECIES) return;
c2690925 307 TIter it(tracks);
308 const AliVTrack *track = NULL;
309 while((track = dynamic_cast<const AliVTrack *>(it()))){
c04c80e6 310 if(track) ProcessTrack(track, species);
311 }
c04c80e6 312}
313
314//__________________________________________________________________
c2690925 315void AliHFEtrdPIDqa::ProcessTrack(const AliVTrack * const track, Int_t species){
c04c80e6 316 //
317 // Process Single Track
318 //
319 if(TString(track->IsA()->GetName()).CompareTo("AliESDtrack") == 0)
c2690925 320 ProcessTrackESD(dynamic_cast<const AliESDtrack *>(track), species);
c04c80e6 321 else if(TString(track->IsA()->GetName()).CompareTo("AliAODTrack") == 0)
c2690925 322 ProcessTrackAOD(dynamic_cast<const AliAODTrack *>(track), species);
c04c80e6 323}
324
325
326//__________________________________________________________________
c2690925 327void AliHFEtrdPIDqa::ProcessTrackESD(const AliESDtrack *track, Int_t species){
c04c80e6 328 //
329 // Process single ESD track
330 //
bf892a6a 331 if(!track) return;
c04c80e6 332 if((track->GetStatus() & AliESDtrack::kTRDout) == 0) return; // require TRD track
333 FillTRDLikelihoods(track, species);
334 FillTRDQAplots(track, species);
335}
336
337//__________________________________________________________________
c2690925 338void AliHFEtrdPIDqa::ProcessTrackAOD(const AliAODTrack * const track, Int_t /*species*/){
c04c80e6 339 //
340 // Process single AOD track
341 // AOD PID object required
342 //
bf892a6a 343 if(!track) return;
c04c80e6 344 AliAODPid *trackPID = track->GetDetPid();
345 if(!trackPID) return;
346
347}
348
349//__________________________________________________________________
c2690925 350void AliHFEtrdPIDqa::FillTRDLikelihoods(const AliESDtrack * const track, Int_t species){
c04c80e6 351 //
352 // Fill TRD Likelihood Histogram
353 //
354 Double_t trdLike[AliPID::kSPECIES];
355 track->GetTRDpid(trdLike);
c2690925 356 // Renormalize
357 Double_t norm =trdLike[AliPID::kElectron]+trdLike[AliPID::kPion];
358 Double_t likeEle = norm == 0. ? 0. : trdLike[AliPID::kElectron]/norm;
c04c80e6 359 const AliExternalTrackParam *outerPars = track->GetOuterParam();
360
361 Double_t quantities[kQuantitiesLike]; memset(quantities, 0, sizeof(Double_t) * kQuantitiesLike);
362 // we store:
363 // species
364 // p
365 // ntracklets
366 // Electron Likelihood
367 quantities[kSpecies] = species;
368 quantities[kP] = outerPars ? outerPars->P() : track->P();
369 quantities[kNTracklets] = track->GetTRDntrackletsPID();
c2690925 370 quantities[kElectronLike] = likeEle;
c04c80e6 371
bf892a6a 372 fHistos->Fill("fLikeTRD", quantities);
c04c80e6 373}
374
375//__________________________________________________________________
c2690925 376void AliHFEtrdPIDqa::FillTRDQAplots(const AliESDtrack * const track, Int_t species){
c04c80e6 377 //
378 // Fill QA Plots containing further information
379 //
380 const AliExternalTrackParam *outerPars = track->GetOuterParam();
381
382 Double_t quantitiesQA[kQuantitiesQA], quantitiesdEdx[kQuantitiesdEdx], quantitiesTruncMean[kQuantitiesTruncMean];
383 // we store:
384 // 1. QA
385 // species
386 // p
387 // ntracklets
388 // Non-zero tracklet charges
389 // Number of clusters / full track
390 // 2. dEdx
391 // species
392 // p
393 // ntracklets
394 // dEdx
395 // 3. Truncated Mean
396 // ...
397 // TPC dEdx
398 // TRD dEdx Method 1
399 // TRD dEdx Method 2
400 quantitiesQA[kSpecies] = quantitiesdEdx[kSpecies]
401 = quantitiesTruncMean[kSpecies]
402 = species;
bf892a6a 403 quantitiesQA[kP] = quantitiesTruncMean[kP]
c04c80e6 404 = outerPars ? outerPars->P() : track->P();
405 quantitiesQA[kNTracklets] = quantitiesdEdx[kNTracklets]
406 = quantitiesTruncMean[kNTracklets]
407 = track->GetTRDntrackletsPID();
3a72645a 408 quantitiesQA[kNClusters] = quantitiesdEdx[kNclusters] = track->GetTRDncls();
409
c04c80e6 410
3a72645a 411 Double_t dEdxSum = 0., qSlice = 0.;
412 // remove the last slice from the histogram
bf892a6a 413 Int_t ntrackletsNonZero = 0, nSlices = track->GetNumberOfTRDslices(), nSlicesNonZero = 0;
414 TString speciesname = "pions";
415 Bool_t selectedForSlicemon = kFALSE;
416
417 switch(species){
418 case AliPID::kElectron: speciesname = "Electrons"; selectedForSlicemon = kTRUE; break;
419 case AliPID::kPion: speciesname = "Pions"; selectedForSlicemon = kTRUE; break;
420 default: speciesname = "undefined"; selectedForSlicemon = kFALSE; break;
421 };
422 AliDebug(1, Form("species %d, speciesname %s, momentum %f, selected %s", species, speciesname.Data(), track->P(), selectedForSlicemon ? "yes" : "no"));
c04c80e6 423 for(Int_t iplane = 0; iplane < AliESDtrack::kTRDnPlanes; iplane++){
bf892a6a 424 quantitiesdEdx[kP] = track->GetTRDmomentum(iplane);
c04c80e6 425 dEdxSum = 0.;
3a72645a 426 for(Int_t islice = 0; islice < nSlices; islice++){
e156c3bb 427 if(fTotalChargeInSlice0 && islice >= 7) break;
428 qSlice = track->GetTRDslice(iplane, fTotalChargeInSlice0 ? islice + 1 : islice); // hack by mfasel: For data with the new reconstruction, slice 0 is used to store the total charge, the total number of slices is 7 instead of 8
3a72645a 429 if(qSlice > 1e-1){
430 // cut out 0 slices
431 nSlicesNonZero++;
432 dEdxSum += qSlice;
bf892a6a 433 // Reweighting of the slices for the truncated mean: select all pion tracks above
434 // 1.5 GeV and monitor the dEdx as function of slice
435 if(selectedForSlicemon && track->P() > 1.5){
436 AliDebug(2, Form("Filling Histogram fTRDslices%s", speciesname.Data()));
437 fHistos->Fill(Form("fTRDslices%s", speciesname.Data()), static_cast<Double_t>(islice), qSlice);
438 }
3a72645a 439 }
440 }
441 quantitiesdEdx[kNonZeroSlices] = nSlicesNonZero;
e156c3bb 442 quantitiesdEdx[kdEdx] = fTotalChargeInSlice0 ? track->GetTRDslice(iplane, 0) : dEdxSum; // hack by mfasel: In the new reconstruction, the total charge is stored in the first slice, in the old reconstruction it has to be calculated from the slice charges.
c04c80e6 443 if(dEdxSum) ntrackletsNonZero++;
444 // Fill dEdx histogram
bf892a6a 445 if(dEdxSum > 1e-1) fHistos->Fill("fQAdEdx", quantitiesdEdx); // Cut out 0 entries
c04c80e6 446 }
447 quantitiesQA[kNonZeroTrackletCharge] = ntrackletsNonZero;
bf892a6a 448 fHistos->Fill("fQAtrack", quantitiesQA);
c04c80e6 449
450 quantitiesTruncMean[kTPCdEdx] = track->GetTPCsignal();
bf892a6a 451 quantitiesTruncMean[kTRDdEdxMethod1] = fTRDpid->GetTRDSignalV1(track, 0.6);
452 quantitiesTruncMean[kTRDdEdxMethod2] = fTRDpid->GetTRDSignalV2(track, 0.6);
453 fHistos->Fill("fTRDtruncMean", quantitiesTruncMean);
c04c80e6 454}
455
456/////////////////////////////////////////////////////////
457//
458// Code for Post Processing
459//
460// //////////////////////////////////////////////////////
461
462//__________________________________________________________________
463void AliHFEtrdPIDqa::FinishAnalysis(){
464 //
465 // Finish Analysis:
466 // Calculate Electron Efficiency for ntracklets = 4...6
467 // Calculate thresholds for ntracklets = 4...6
468 //
469
470 if(!fPionEfficiencies){
471 fPionEfficiencies = new TList;
472 fPionEfficiencies->SetName("pionEfficiencies");
e156c3bb 473 fPionEfficiencies->SetOwner();
c04c80e6 474 }
475 if(!fProtonEfficiencies){
476 fProtonEfficiencies = new TList;
477 fProtonEfficiencies->SetName("protonEfficiencies");
e156c3bb 478 fProtonEfficiencies->SetOwner();
c04c80e6 479 }
480 if(!fThresholds){
481 fThresholds = new TList;
482 fThresholds->SetName("thresholds");
e156c3bb 483 fThresholds->SetOwner();
c04c80e6 484 }
485
486 for(Int_t itr = 4; itr <= 6; itr++){
e3ae862b 487 if(fShowMessage){
488 printf("========================================\n");
489 printf("Analysing %d trackltes\n", itr);
490 printf("========================================\n");
491 }
c04c80e6 492 AnalyseNTracklets(itr);
493 }
494}
495
496//__________________________________________________________________
497void AliHFEtrdPIDqa::StoreResults(const Char_t *filename){
498 //
499 // Store histos into a root file
500 //
501 TFile *outfile = new TFile(filename, "RECREATE");
502 outfile->cd();
503 fPionEfficiencies->Clone()->Write(fPionEfficiencies->GetName(), kSingleKey);
504 fProtonEfficiencies->Clone()->Write(fProtonEfficiencies->GetName(), kSingleKey);
505 fThresholds->Clone()->Write(fThresholds->GetName(), kSingleKey);
506 outfile->Close();
507 delete outfile;
508}
509
510//__________________________________________________________________
e156c3bb 511void AliHFEtrdPIDqa::SaveThresholdParameters(const Char_t *name, Double_t lowerLimit, Double_t upperLimit){
c04c80e6 512 //
513 // Fit the threshold histograms with the given parametrisation
514 // and store the TF1 in the file
515 //
516
517 if(!fThresholds){
518 AliError("Threshold histograms have to be created first");
519 return;
520 }
521
e3ae862b 522 if(fShowMessage){
523 printf("========================================\n");
524 printf("Calculating threshold parameters\n");
525 printf("========================================\n");
526 }
c04c80e6 527
528 TList *outlist = new TList;
529 outlist->SetName("thresholdTRD");
530
531 TGraph *threshhist = NULL;
532 TF1 *threshparam = NULL;
533 TList *lHistos = NULL, *lFormulas = NULL;
534 for(Int_t itracklet = 4; itracklet <= 6; itracklet++){
535
e3ae862b 536 if(fShowMessage){
537 printf("-------------------------------\n");
538 printf("Processing %d tracklets\n", itracklet);
539 printf("-------------------------------\n");
540 }
c04c80e6 541
542 lHistos = dynamic_cast<TList *>(fThresholds->FindObject(Form("%dTracklets", itracklet)));
543 if(!lHistos){
c1bd5735 544 AliError(Form("Threshold histograms for the case %d tracklets not found", itracklet));
c04c80e6 545 continue;
546 }
547 lFormulas = new TList;
548 lFormulas->SetName(Form("%dTracklets", itracklet));
549 outlist->Add(lFormulas);
550
551 for(Int_t ieff = 0; ieff < kNElectronEffs; ieff++){
552
e3ae862b 553 if(fShowMessage){
554 printf("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
555 printf("Processing Electron Efficiency %f\n", fgkElectronEff[ieff]);
556 printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
557 }
c04c80e6 558
559 threshhist = dynamic_cast<TGraph *>(lHistos->FindObject(Form("eff%d", static_cast<Int_t>(fgkElectronEff[ieff] * 100))));
bf892a6a 560 if(!threshhist) continue;
e156c3bb 561 threshparam = MakeThresholds(threshhist, lowerLimit, upperLimit);
c04c80e6 562 threshparam->SetName(Form("thresh_%d_%d", itracklet, static_cast<Int_t>(fgkElectronEff[ieff] * 100)));
bf892a6a 563 lFormulas->Add(threshparam);
c04c80e6 564 }
565 }
566
567 // store the output
568 TFile *outfile = new TFile(name, "RECREATE");
569 outfile->cd();
570 outlist->Write(outlist->GetName(), kSingleKey);
571 outfile->Close();
572 delete outfile;
573}
574
575//__________________________________________________________________
576void AliHFEtrdPIDqa::AnalyseNTracklets(Int_t nTracklets){
577 //
578 // Calculate Pion Efficiency, Proton Efficiency and Kaon Efficiency at discrete
579 // elPion Efficiency, Proton Efficiency and Kaon Efficiency at discrete
580 // electron efficiencies
581 //
bf892a6a 582 THnSparse *hLikeTRD = dynamic_cast<THnSparseF *>(fHistos->Get("fLikeTRD"));
583 if(!hLikeTRD){
584 AliError("Likelihood Histogram not available");
585 return;
586 }
587 Int_t binTracklets = hLikeTRD->GetAxis(kNTracklets)->FindBin(nTracklets);
588 hLikeTRD->GetAxis(kNTracklets)->SetRange(binTracklets, binTracklets);
c04c80e6 589
bf892a6a 590 Int_t binElectrons = hLikeTRD->GetAxis(kSpecies)->FindBin(AliPID::kElectron);
c04c80e6 591 AliDebug(1, Form("BinElectrons %d", binElectrons));
bf892a6a 592 Int_t binPions = hLikeTRD->GetAxis(kSpecies)->FindBin(AliPID::kPion);
c04c80e6 593 AliDebug(1, Form("BinPions %d", binPions));
bf892a6a 594 Int_t binProtons = hLikeTRD->GetAxis(kSpecies)->FindBin(AliPID::kProton);
c04c80e6 595 AliDebug(1, Form("BinProtons %d", binProtons));
bf892a6a 596 hLikeTRD->GetAxis(kSpecies)->SetRange(binElectrons, binElectrons);
597 TH2 *likeElectron = hLikeTRD->Projection(kElectronLike, kP);
c04c80e6 598 likeElectron->SetName("likeElectron");
bf892a6a 599 hLikeTRD->GetAxis(kSpecies)->SetRange(binPions, binPions);
600 TH2 *likePion = hLikeTRD->Projection(kElectronLike, kP);
c04c80e6 601 likePion->SetName("likePion");
bf892a6a 602 hLikeTRD->GetAxis(kSpecies)->SetRange(binProtons, binProtons);
603 TH2 *likeProton = hLikeTRD->Projection(kElectronLike, kP);
c04c80e6 604 likeProton->SetName("likeProton");
605
606 // Undo ranges
bf892a6a 607 hLikeTRD->GetAxis(kSpecies)->SetRange(0, hLikeTRD->GetAxis(kSpecies)->GetNbins());
608 hLikeTRD->GetAxis(kNTracklets)->SetRange(0, hLikeTRD->GetAxis(kNTracklets)->GetNbins());
c04c80e6 609
610 // Prepare List for output
e156c3bb 611 TList *listPions = new TList; listPions->SetName(Form("%dTracklets", nTracklets)); listPions->SetOwner();
612 TList *listProtons = new TList; listProtons->SetName(Form("%dTracklets", nTracklets)); listProtons->SetOwner();
613 TList *listThresholds = new TList; listThresholds->SetName(Form("%dTracklets", nTracklets)); listThresholds->SetOwner();
c04c80e6 614 fPionEfficiencies->Add(listPions);
615 fProtonEfficiencies->Add(listProtons);
616 fThresholds->Add(listThresholds);
617
618 TH1 *probsEl = NULL, *probsPi = NULL, *probsPr = NULL;
619 TGraphErrors *effPi = NULL, *effPr = NULL; TGraph *thresholds = NULL;
620 Double_t p = 0, dp = 0;
621 Int_t threshbin = 0;
622 Double_t noElEff[2]; // value and error
623 for(Int_t ieff = 0; ieff < kNElectronEffs; ieff++){
e3ae862b 624
625 if(fShowMessage){
626 printf("-----------------------------------------\n");
627 printf("Doing Electron Efficiency %f\n", fgkElectronEff[ieff]);
628 printf("-----------------------------------------\n");
629 }
c04c80e6 630 effPi = new TGraphErrors(likeElectron->GetXaxis()->GetNbins());
631 effPi->SetName(Form("eff%d", static_cast<Int_t >(fgkElectronEff[ieff] * 100)));
632 effPr = new TGraphErrors(likeElectron->GetXaxis()->GetNbins());
633 effPr->SetName(Form("eff%d", static_cast<Int_t >(fgkElectronEff[ieff] * 100)));
634 thresholds = new TGraph(likeElectron->GetXaxis()->GetNbins());
635 thresholds->SetName(Form("eff%d", static_cast<Int_t >(fgkElectronEff[ieff] * 100)));
636
637 // Add to lists
638 listPions->Add(effPi);
639 listProtons->Add(effPr);
640 listThresholds->Add(thresholds);
641
642 for(Int_t imom = 1; imom <= likeElectron->GetXaxis()->GetLast(); imom++){
643 p = likeElectron->GetXaxis()->GetBinCenter(imom);
644 dp = likeElectron->GetXaxis()->GetBinWidth(imom)/2;
645
646 probsEl = likeElectron->ProjectionY("el", imom);
647 if(!probsEl->GetEntries()) continue;
648 probsEl->Scale(1./probsEl->Integral());
649 probsPi = likePion->ProjectionY("pi", imom);
650 if(!probsPi->GetEntries()) continue;
651 probsPi->Scale(1./probsPi->Integral());
652 probsPr = likeProton->ProjectionY("pr", imom);
653 if(!probsPr->GetEntries()) continue;
654 probsPr->Scale(1./probsPr->Integral());
655 AliDebug(1, Form("Calculating Values for p = %f", p));
656
657 // Calculare threshold we need to achive the x% electron Efficiency
658 threshbin = GetThresholdBin(probsEl, fgkElectronEff[ieff]);
659 thresholds->SetPoint(imom - 1, p, probsEl->GetXaxis()->GetBinCenter(threshbin));
660 AliDebug(1, Form("threshold %d|%f", threshbin, probsEl->GetXaxis()->GetBinCenter(threshbin)));
661
662 // Calculate non-electronEfficiency and error
663 CalculateEfficiency(probsPi, threshbin, noElEff);
664 AliDebug(1, Form("Pion Efficiency %f", noElEff[0]));
665 effPi->SetPoint(imom - 1, p, noElEff[0]);
666 effPi->SetPointError(imom - 1, dp, noElEff[1]);
667 CalculateEfficiency(probsPr, threshbin, noElEff);
668 effPr->SetPoint(imom - 1, p, noElEff[0]);
669 effPr->SetPointError(imom - 1, dp, noElEff[1]);
670 AliDebug(1, Form("Proton Efficiency %f", noElEff[0]));
671
672 // cleanup
673 delete probsEl;
674 delete probsPi;
675 delete probsPr;
676 }
677 }
678
679 // remove temporary histograms
680 delete likeElectron;
681 delete likePion;
682 delete likeProton;
683}
684
685//__________________________________________________________________
c2690925 686Int_t AliHFEtrdPIDqa::GetThresholdBin(const TH1 * const input, Double_t eff){
c04c80e6 687 //
688 // Calculate the threshold bin
689 //
690 Double_t integralEff = 0.;
691 Int_t currentBin = 0;
692 for(Int_t ibin = input->GetXaxis()->GetLast(); ibin >= input->GetXaxis()->GetFirst(); ibin--){
693 currentBin = ibin;
694 integralEff += input->GetBinContent(ibin);
695 if(integralEff >= eff){
696 // we found the matching bin, break the loop
697 break;
698 }
699 }
700 return currentBin;
701}
702
703//__________________________________________________________________
c2690925 704Bool_t AliHFEtrdPIDqa::CalculateEfficiency(const TH1 * const input, Int_t threshbin, Double_t * const par){
c04c80e6 705 //
706 // Calculate non-electron efficiency
707 //
708 Double_t integralEff = 0;
709 for(Int_t ibin = threshbin; ibin <= input->GetXaxis()->GetLast(); ibin++)
710 integralEff += input->GetBinContent(ibin);
711 par[0] = integralEff;
712
713 // @TODO: Error calculation
714 par[1] = 0;
715
716 return kTRUE;
717}
718
719//__________________________________________________________________
e3ae862b 720void AliHFEtrdPIDqa::DrawTracklet(Int_t itracklet, Double_t pmin, Double_t pmax, Bool_t doFit){
c04c80e6 721 //
722 // Draw efficiencies and threshold as function of p
723 //
724 if(!(fPionEfficiencies && fProtonEfficiencies && fThresholds)){
725 AliError("No graphs to draw available");
726 return;
727 }
728
729 TList *lpions = dynamic_cast<TList *>(fPionEfficiencies->FindObject(Form("%dTracklets", itracklet)));
730 TList *lprotons = dynamic_cast<TList *>(fProtonEfficiencies->FindObject(Form("%dTracklets", itracklet)));
731
732 TList *lthresholds = dynamic_cast<TList *>(fThresholds->FindObject(Form("%dTracklets", itracklet)));
bf892a6a 733 if(!(lpions && lprotons && lthresholds)){
734 AliDebug(1, "Relevant lists not found. Did you forget to run FinishAnalysis()?");
735 return;
736 }
c04c80e6 737
738 TGraphErrors *pi, *pr;
739 TGraph *tr;
740 TLegend *leg;
c1bd5735 741 TCanvas *c1 = new TCanvas(Form("tracklet%d", itracklet), Form("Tracklet %d", itracklet), 1024, 768);
c04c80e6 742 c1->Divide(3,2);
bf892a6a 743 TF1 *threshfit = NULL;
c04c80e6 744 for(Int_t ieff = 0; ieff < kNElectronEffs; ieff++){
745 c1->cd(ieff + 1);
746 leg = new TLegend(0.6, 0.7, 0.89, 0.89);
747 leg->SetBorderSize(0);
748 leg->SetFillStyle(0);
749 pi = dynamic_cast<TGraphErrors *>(lpions->FindObject(Form("eff%d", static_cast<Int_t>(fgkElectronEff[ieff] * 100))));
750 pr = dynamic_cast<TGraphErrors *>(lprotons->FindObject(Form("eff%d", static_cast<Int_t>(fgkElectronEff[ieff] * 100))));
751 tr = dynamic_cast<TGraph *>(lthresholds->FindObject(Form("eff%d", static_cast<Int_t>(fgkElectronEff[ieff] * 100))));
bf892a6a 752 if(!(pi && pr && tr)) continue;
c04c80e6 753
754 // Define nice plot, draw
755 // Axis Title
756 pi->GetXaxis()->SetTitle("p / GeV/c");
c1bd5735 757 pi->GetYaxis()->SetTitle("Efficiency");
c04c80e6 758 pr->GetXaxis()->SetTitle("p / GeV/c");
c1bd5735 759 pr->GetYaxis()->SetTitle("Efficiency");
c04c80e6 760 tr->GetXaxis()->SetTitle("p / GeV/c");
c1bd5735 761 tr->GetYaxis()->SetTitle("Efficiency");
c04c80e6 762 // Axis Range
e3ae862b 763 pi->GetYaxis()->SetRangeUser(1e-3, 1.);
764 pr->GetYaxis()->SetRangeUser(1e-3, 1.);
765 tr->GetYaxis()->SetRangeUser(1e-3, 1.);
766 if(pmin > 0 && pmax > 0.){
767 pi->GetXaxis()->SetRangeUser(pmin, pmax);
768 pr->GetXaxis()->SetRangeUser(pmin, pmax);
769 tr->GetXaxis()->SetRangeUser(pmin, pmax);
770 }
c04c80e6 771 // Marker
772 pi->SetMarkerColor(kRed);
773 pi->SetMarkerStyle(20);
774 pr->SetMarkerColor(kBlue);
775 pr->SetMarkerStyle(21);
776 tr->SetMarkerColor(kBlack);
777 tr->SetMarkerStyle(22);
778 // Title
779 pi->SetTitle(Form ("%.2f Electron Efficiency", fgkElectronEff[ieff]));
780 pr->SetTitle(Form ("%.2f Electron Efficiency", fgkElectronEff[ieff]));
781 tr->SetTitle(Form ("%.2f Electron Efficiency", fgkElectronEff[ieff]));
782 // Draw
783 pi->Draw("ape"); pr->Draw("pesame"); tr->Draw("psame");
784
bf892a6a 785 // Optionally do Fit
786 if(doFit){
e156c3bb 787 threshfit = MakeThresholds(tr, pmin, pmax);
bf892a6a 788 threshfit->SetLineColor(kBlack);
789 threshfit->Draw("same");
790 }
791
c04c80e6 792 // Add entries to legend
793 leg->AddEntry(pi, "Pion Efficiency", "lp");
794 leg->AddEntry(pr, "Proton Efficiency", "lp");
795 leg->AddEntry(tr, "Thresholds", "lp");
796 leg->Draw();
797 c1->Update();
798 }
799}
800
801//__________________________________________________________________
e156c3bb 802TF1 *AliHFEtrdPIDqa::MakeThresholds(TGraph *threshist, Double_t lowerLimit, Double_t upperLimit){
c04c80e6 803 //
804 // Create TF1 containing the threshold parametrisation
805 //
806
807 TF1 *threshparam = new TF1("thresh", "1-[0]-[1]*x-[2]*TMath::Exp(-[3]*x)", 0.1, 10);
e156c3bb 808 threshist->Fit(threshparam, "NE", "", lowerLimit, upperLimit);
c04c80e6 809 return threshparam;
810}
811
812//__________________________________________________________________
813void AliHFEtrdPIDqa::ClearLists(){
814 //
815 // Clear lists for particle efficiencies and thresholds
816 //
817 if(fPionEfficiencies){
818 fPionEfficiencies->Delete();
819 delete fPionEfficiencies;
820 fPionEfficiencies = NULL;
821 }
822 if(fProtonEfficiencies){
823 fProtonEfficiencies->Delete();
824 delete fProtonEfficiencies;
825 fProtonEfficiencies = NULL;
826 }
827 if(fThresholds){
828 fThresholds->Delete();
829 delete fThresholds;
830 fThresholds = NULL;
831 }
832}
e3ae862b 833
834//__________________________________________________________________
835Double_t AliHFEtrdPIDqa::EvalPionEfficiency(Int_t ntls, Int_t eEff, Double_t p){
c2690925 836 //
837 // calculate pion efficiency
838 // Arguments:
839 // Number of tracklets
840 // Electron Efficiency
841 // Momentum
842 //
e3ae862b 843 TList *graphs = dynamic_cast<TList *>(fPionEfficiencies->FindObject(Form("%dTracklets", ntls)));
844 if(!graphs) return -1.;
845 TGraph *measurement = dynamic_cast<TGraph *>(graphs->FindObject(Form("eff%d", eEff)));
846 if(!measurement) return -1.;
847 return measurement->Eval(p);
848}
849
850//__________________________________________________________________
851Double_t AliHFEtrdPIDqa::EvalProtonEfficiency(Int_t ntls, Int_t eEff, Double_t p){
c2690925 852 //
853 // calculate proton efficiency
854 // Arguments:
855 // Number of tracklets
856 // Electron Efficiency
857 // Momentum
858 //
e3ae862b 859 TList *graphs = dynamic_cast<TList *>(fProtonEfficiencies->FindObject(Form("%dTracklets", ntls)));
860 if(!graphs) return -1.;
861 TGraph *measurement = dynamic_cast<TGraph *>(graphs->FindObject(Form("eff%d", eEff)));
862 if(!measurement) return -1.;
863 return measurement->Eval(p);
864}
865
866//__________________________________________________________________
867Double_t AliHFEtrdPIDqa::EvalThreshold(Int_t ntls, Int_t eEff, Double_t p){
c2690925 868 //
869 // Get the threshold to reach a certain electron efficiency
870 // Arguments:
871 // Number of tracklets
872 // Electron Efficiency
873 // Momentum
874 //
e3ae862b 875 TList *graphs = dynamic_cast<TList *>(fThresholds->FindObject(Form("%dTracklets", ntls)));
876 if(!graphs) return -1.;
877 TGraph *measurement = dynamic_cast<TGraph *>(graphs->FindObject(Form("eff%d", eEff)));
878 if(!measurement) return -1.;
879 return measurement->Eval(p);
880}
881