6 #include "TGraphErrors.h"
8 #include <TClonesArray.h>
13 #include "AliESDEvent.h"
14 #include "AliESDInputHandler.h"
15 #include "AliTrackReference.h"
17 #include "AliAnalysisTask.h"
18 #include "AliAnalysisManager.h"
20 #include "AliTRDtrackV1.h"
21 #include "AliTRDReconstructor.h"
22 #include "AliCDBManager.h"
23 #include "../Cal/AliTRDCalPID.h"
26 #include "AliTRDpidChecker.h"
27 #include "AliTRDtrackInfo/AliTRDtrackInfo.h"
29 // calculate pion efficiency at 90% electron efficiency for 11 momentum bins
30 // this task should be used with simulated data only
32 ClassImp(AliTRDpidChecker)
34 //________________________________________________________________________
35 AliTRDpidChecker::AliTRDpidChecker(const char *name)
36 :AliAnalysisTask(name, "")
37 ,fObjectContainer(0x0)
44 // Default constructor
47 fReconstructor = new AliTRDReconstructor();
48 fReconstructor->SetRecoParam(AliTRDrecoParam::GetLowFluxParam());
50 DefineInput(0, TObjArray::Class());
51 DefineOutput(0, TObjArray::Class());
55 //________________________________________________________________________
56 AliTRDpidChecker::~AliTRDpidChecker()
59 //fObjectContainer->Delete();
60 //delete fObjectContainer;
66 //________________________________________________________________________
67 void AliTRDpidChecker::ConnectInputData(Option_t *)
73 fTracks = dynamic_cast<TObjArray*>(GetInputData(0));
77 //________________________________________________________________________
78 void AliTRDpidChecker::CreateOutputObjects()
83 OpenFile(0, "RECREATE");
84 fObjectContainer = new TObjArray();
85 fObjectContainer->Add(new TH1F("hMom", "momentum distribution", AliTRDCalPID::kNMom, 0.5, 11.5));
88 // histos of the electron probability of all 5 particle species and 11 momenta for the 2-dim LQ method
89 const Int_t kBins = 12000; // binning of the histos and eficiency calculation
90 for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
91 for(Int_t iMom = 0; iMom < AliTRDCalPID::kNMom; iMom++){
92 fObjectContainer->Add(new TH1F(Form("PID%d_%d_LQ",iPart,iMom), Form("PID distribution for %d_%d", iPart, iMom), kBins, -0.1, 1.1));
96 // histos of the electron probability of all 5 particle species and 11 momenta for the neural network method
97 for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
98 for(Int_t iMom = 0; iMom < AliTRDCalPID::kNMom; iMom++){
99 fObjectContainer->Add(new TH1F(Form("PID%d_%d_NN",iPart,iMom), Form("PID distribution for %d_%d", iPart, iMom), kBins, -0.1, 1.1));
103 // frame and TGraph of the pion efficiencies
104 fObjectContainer -> Add(new TH2F("hFrame", "", 10, 0.4, 12., 10, 0.0005, 0.1));
105 fObjectContainer -> Add(new TGraph(AliTRDCalPID::kNMom));
106 fObjectContainer -> Add(new TGraphErrors(AliTRDCalPID::kNMom));
107 fObjectContainer -> Add(new TGraph(AliTRDCalPID::kNMom));
108 fObjectContainer -> Add(new TGraphErrors(AliTRDCalPID::kNMom));
111 //________________________________________________________________________
112 void AliTRDpidChecker::Exec(Option_t *)
115 // Called for each event
118 // if(!AliTracker::GetFieldMap()){
119 // AliMagFMaps* field = new AliMagFMaps("Maps","Maps", 2, 1., 10., AliMagFMaps::k5kG);
120 // AliTracker::SetFieldMap(field, kTRUE);
123 TH1F *hMom = (TH1F*)fObjectContainer->UncheckedAt(0);
124 TH1F *hPIDLQ[AliPID::kSPECIES][AliTRDCalPID::kNMom];
125 TH1F *hPIDNN[AliPID::kSPECIES][AliTRDCalPID::kNMom];
127 for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
128 for(Int_t iMom = 0; iMom < AliTRDCalPID::kNMom; iMom++){
129 hPIDLQ[iPart][iMom] = (TH1F*)fObjectContainer->At(iPart*AliTRDCalPID::kNMom+iMom+1);
130 hPIDNN[iPart][iMom] = (TH1F*)fObjectContainer->At(iPart*AliTRDCalPID::kNMom+iMom+1+AliPID::kSPECIES*AliTRDCalPID::kNMom);
134 Int_t labelsacc[10000];
135 memset(labelsacc, 0, sizeof(Int_t) * 10000);
142 AliTRDtrackInfo *track = 0x0;
143 AliTRDtrackV1 *TRDtrack = 0x0;
144 AliTrackReference *ref = 0x0;
145 AliExternalTrackParam *esd = 0x0;
146 for(Int_t itrk=0; itrk<fTracks->GetEntriesFast(); itrk++){
147 track = (AliTRDtrackInfo*)fTracks->UncheckedAt(itrk);
148 if(!track->HasESDtrack()) continue;
149 status = track->GetStatus();
150 if(!(status&AliESDtrack::kTPCout)) continue;
152 if(!(TRDtrack = track->GetTRDtrack())) continue;
153 //&&(track->GetNumberOfClustersRefit()
154 // use only tracks taht hit 6 chambers
155 if(!(TRDtrack->GetNumberOfTracklets() == AliTRDCalPID::kNPlane)) continue;
157 ref = track->GetTrackRef(0);
158 esd = track->GetOuterParam();
159 mom = ref ? ref->P(): esd->P();
161 labelsacc[nTRD] = track->GetLabel();
164 // fill momentum histo to have the momentum distribution
168 // set the 11 momentum bins
170 if(mom < .7) iMomBin = 0;
171 else if(mom < .9) iMomBin = 1;
172 else if(mom < 1.25) iMomBin = 2;
173 else if(mom < 1.75) iMomBin = 3;
174 else if(mom < 2.5) iMomBin = 4;
175 else if(mom < 3.5) iMomBin = 5;
176 else if(mom < 4.5) iMomBin = 6;
177 else if(mom < 5.5) iMomBin = 7;
178 else if(mom < 7.0) iMomBin = 8;
179 else if(mom < 9.0) iMomBin = 9;
182 // set the reconstructor
183 TRDtrack -> SetReconstructor(fReconstructor);
186 // calculate the probabilities and fill histograms for electrons using 2-dim LQ
187 fReconstructor -> SetOption("!nn");
188 TRDtrack -> CookPID();
190 switch(track->GetPDG()){
193 hPIDLQ[AliPID::kElectron][iMomBin] -> Fill(TRDtrack -> GetPID(0));
197 hPIDLQ[AliPID::kMuon][iMomBin] -> Fill(TRDtrack -> GetPID(0));
201 hPIDLQ[AliPID::kPion][iMomBin] -> Fill(TRDtrack -> GetPID(0));
205 hPIDLQ[AliPID::kKaon][iMomBin] -> Fill(TRDtrack -> GetPID(0));
209 hPIDLQ[AliPID::kMuon][iMomBin] -> Fill(TRDtrack -> GetPID(0));
214 // calculate the probabilities and fill histograms for electrons using NN
215 fReconstructor -> SetOption("nn");
217 switch(track->GetPDG()){
220 hPIDNN[AliPID::kElectron][iMomBin] -> Fill(TRDtrack -> GetPID(0));
224 hPIDNN[AliPID::kMuon][iMomBin] -> Fill(TRDtrack -> GetPID(0));
228 hPIDNN[AliPID::kPion][iMomBin] -> Fill(TRDtrack -> GetPID(0));
232 hPIDNN[AliPID::kKaon][iMomBin] -> Fill(TRDtrack -> GetPID(0));
236 hPIDNN[AliPID::kMuon][iMomBin] -> Fill(TRDtrack -> GetPID(0));
241 PostData(0, fObjectContainer);
244 //________________________________________________________________________
245 void AliTRDpidChecker::Terminate(Option_t *)
247 // Draw result to the screen
248 // Called once at the end of the query
250 fObjectContainer = dynamic_cast<TObjArray*>(GetOutputData(0));
251 if (!fObjectContainer) {
252 Printf("ERROR: list not available");
257 // container for the pion efficiencies and the errors
258 Double_t PionEffiLQ[AliTRDCalPID::kNMom],
259 PionEffiNN[AliTRDCalPID::kNMom],
260 PionEffiErrorLQ[AliTRDCalPID::kNMom],
261 PionEffiErrorNN[AliTRDCalPID::kNMom];
264 // calculate the pion efficiencies and the errors for 90% electron efficiency (2-dim LQ)
265 for(Int_t iMom = 0; iMom < AliTRDCalPID::kNMom; iMom++){
266 PionEffiLQ[iMom] = GetPionEfficiency(iMom+1,iMom+23);
267 PionEffiErrorLQ[iMom] = GetError(iMom+1,iMom+23);
268 Printf("Pion Efficiency for 2-dim LQ is : %f +/- %f\n\n", PionEffiLQ[iMom], PionEffiErrorLQ[iMom]);
271 // calculate the pion efficiencies and the errors for 90% electron efficiency (NN)
272 for(Int_t iMom = 0; iMom < AliTRDCalPID::kNMom; iMom++){
273 PionEffiNN[iMom] = GetPionEfficiency(iMom+56,iMom+78);
274 PionEffiErrorNN[iMom] = GetError(iMom+56,iMom+78);
275 Printf("Pion Efficiency for NN is : %f +/- %f\n\n", PionEffiNN[iMom], PionEffiErrorNN[iMom]);
279 // create TGraph to plot the pion efficiencies
280 TGraph *gEffisLQ=0x0, *gEffisNN=0x0;
281 TGraphErrors *gEffisErrLQ=0x0, *gEffisErrNN=0x0;
283 gEffisLQ = (TGraph*)fObjectContainer->At(112);
284 gEffisErrLQ = (TGraphErrors*)fObjectContainer->At(113);
285 gEffisNN = (TGraph*)fObjectContainer->At(114);
286 gEffisErrNN = (TGraphErrors*)fObjectContainer->At(115);
288 for(Int_t iBin = 0; iBin < AliTRDCalPID::kNMom; iBin++){
289 Float_t momentum = AliTRDCalPID::GetMomentum(iBin);
290 gEffisLQ->SetPoint(iBin, momentum, PionEffiLQ[iBin]);
291 gEffisErrLQ->SetPoint(iBin, momentum, PionEffiLQ[iBin]);
292 gEffisErrLQ->SetPointError(iBin, 0., PionEffiErrorLQ[iBin]);
294 gEffisNN->SetPoint(iBin, momentum, PionEffiNN[iBin]);
295 gEffisErrNN->SetPoint(iBin, momentum, PionEffiNN[iBin]);
296 gEffisErrNN->SetPointError(iBin, 0., PionEffiErrorNN[iBin]);
299 gEffisLQ -> SetNameTitle("gEffisLQ", "Efficiencies of the 2-dim LQ method");
300 gEffisErrLQ -> SetNameTitle("gEffisLQErr", "Efficiencies and Errors of the 2-dim LQ method");
301 gEffisNN -> SetNameTitle("gEffisNN", "Efficiencies of the NN method");
302 gEffisErrNN -> SetNameTitle("gEffisNNErr", "Efficiencies and Errors of the NN method");
306 //________________________________________________________________________
307 Double_t AliTRDpidChecker::GetPionEfficiency(Int_t Index1, Int_t Index2){
309 Float_t Multi = 0.9; // electron efficiency
311 Double_t SumElecs, SumPions; // integrated sum of elecs and pions in the histos
312 Double_t aBinSum, bBinSum; // content of a single bin in the histos
314 TH1F *Histo1 = (TH1F*)fObjectContainer->At(Index1); // electron histo
315 TH1F *Histo2 = (TH1F*)fObjectContainer->At(Index2); // pion histo
319 if(!(Histo1 -> GetEntries() > 0 && Histo2 -> GetEntries() > 0)){
320 Printf("Warning: Histo momentum intervall %d has no Entries!", Index1-1);
323 Histo1 -> Scale(1./Histo1->GetEntries());
324 Histo2 -> Scale(1./Histo2->GetEntries());
327 // calculate threshold for pion efficiency
328 for (abin = (Histo1 -> GetNbinsX()); abin >= 0; abin--){
330 aBinSum = Histo1 -> GetBinContent(abin);
332 SumElecs = SumElecs + aBinSum;
334 if (SumElecs >= Multi){
340 // calculate pion efficiency
342 for (bbin = (Histo2 -> GetNbinsX()); bbin >= abin; bbin--){
344 bBinSum = Histo2 -> GetBinContent(bbin);
346 SumPions = SumPions + bBinSum;
351 // print the electron efficiency and its cuts
352 Printf("Cut for momentum intervall %d and electron efficiency of %f for: 0.%d", Index1-1, SumElecs, abin-1000);
353 Printf("(%.0f electrons and %.0f pions)",Histo1 -> GetEntries(), Histo2 -> GetEntries());
356 // return the pion efficiency
362 //________________________________________________________________________
363 Double_t AliTRDpidChecker::GetError(Int_t Index1, Int_t Index2){
366 const Int_t kBins = 12000; // binning of the histos and eficiency calculation
367 const Float_t Multi = 0.9; // electron efficiency
368 Int_t abinE, bbinE, cbinE;
369 Double_t SumElecsE[kBins], SumPionsE[kBins]; // array of the integrated sum in each bin
370 Double_t aBinSumE, bBinSumE; // content of a single bin
371 Double_t EleEffi, PioEffi; // electron and pion efficiency
372 Bool_t bFirst = 1; // checks if threshold is crossed for the first time
373 Double_t fError = 0.; // error of the pion efficiency
376 TH1F *Histo1 = (TH1F*)fObjectContainer->At(Index1); // electron histo
377 TH1F *Histo2 = (TH1F*)fObjectContainer->At(Index2); // pion histo
379 if(!(Histo1 -> GetEntries() > 0 && Histo2 -> GetEntries() > 0)){
380 Printf("Warning: Histo momentum intervall %d has no Entries!", Index1-1);
384 for(Int_t iBin = 0; iBin < kBins; iBin++){
385 SumElecsE[iBin] = 0.;
386 SumPionsE[iBin] = 0.;
394 // calculate electron efficiency of each bin
395 for (abinE = (Histo1 -> GetNbinsX())-2; abinE >= 0; abinE--){
397 aBinSumE = Histo1 -> GetBinContent(abinE);
399 SumElecsE[abinE] = SumElecsE[abinE+1] + aBinSumE;
400 if((SumElecsE[abinE] >= Multi) && (bFirst == 1)){
403 EleEffi = (SumElecsE[cbinE]);
408 // calculate pion efficiency of each bin
409 for (bbinE = (Histo2 -> GetNbinsX())-2; bbinE >= abinE; bbinE--){
411 bBinSumE = Histo2 -> GetBinContent(bbinE);
413 SumPionsE[bbinE] = SumPionsE[bbinE+1] + bBinSumE;
415 PioEffi = (SumPionsE[cbinE]);
420 // pion efficiency vs electron efficiency
421 TGraph *gEffis = new TGraph(kBins, SumElecsE, SumPionsE);
423 // use fit function to get derivate of the TGraph for error calculation
424 TF1 *f1 = new TF1("f1","[0]*x*x+[1]*x+[2]", Multi-.05, Multi+.05);
425 gEffis -> Fit("f1","Q","",Multi-.05, Multi+.05);
426 Printf("Derivative at %4.2f : %f", Multi, f1 -> Derivative(Multi));
428 // return the error of the pion efficiency
429 fError = sqrt(((1/Histo2 -> GetEntries())*PioEffi*(1-PioEffi))+((f1 -> Derivative(Multi))*(f1 -> Derivative(Multi))*(1/Histo1 -> GetEntries())*EleEffi*(1-EleEffi)));