1 //////////////////////////////////////////////////////
3 // PID performance checker of the TRD
5 // Performs checks of ESD information for TRD-PID and recalculate PID based on OCDB information
6 // Also provides performance plots on detector based on the PID information - for the moment only
7 // MC source is used but V0 is also possible. Here is a list of detector performance checks
8 // - Integrated dE/dx per chamber
9 // - <PH> as function of time bin and local radial position
10 // - number of clusters/tracklet
11 // - number of tracklets/track
13 // Author : Alex Wilk <wilka@uni-muenster.de>
14 // Alex Bercuci <A.Bercuci@gsi.de>
15 // Markus Fasel <M.Fasel@gsi.de>
17 ///////////////////////////////////////////////////////
28 #include "TProfile2D.h"
30 #include "TGraphErrors.h"
33 #include <TClonesArray.h>
34 #include <TObjArray.h>
37 #include "AliESDEvent.h"
38 #include "AliESDInputHandler.h"
39 #include "AliTrackReference.h"
41 #include "AliAnalysisTask.h"
43 #include "AliTRDtrackerV1.h"
44 #include "AliTRDtrackV1.h"
45 #include "AliTRDcluster.h"
46 #include "AliTRDReconstructor.h"
47 #include "AliCDBManager.h"
48 #include "AliTRDpidUtil.h"
50 #include "Cal/AliTRDCalPID.h"
51 #include "Cal/AliTRDCalPIDNN.h"
52 #include "AliTRDcheckPID.h"
53 #include "info/AliTRDtrackInfo.h"
54 #include "info/AliTRDpidInfo.h"
55 #include "info/AliTRDv0Info.h"
57 Char_t const * AliTRDcheckPID::fgMethod[3] = {"LQ", "NN", "ESD"};
59 ClassImp(AliTRDcheckPID)
61 //________________________________________________________________________
62 AliTRDcheckPID::AliTRDcheckPID()
70 ,fMinNTracklets(AliTRDgeometry::kNlayer)
71 ,fMaxNTracklets(AliTRDgeometry::kNlayer)
74 // Default constructor
76 SetNameTitle("checkPID", "Check TRD PID");
80 //________________________________________________________________________
81 AliTRDcheckPID::AliTRDcheckPID(char* name )
82 :AliTRDrecoTask(name, "Check TRD PID")
89 ,fMinNTracklets(AliTRDgeometry::kNlayer)
90 ,fMaxNTracklets(AliTRDgeometry::kNlayer)
93 // Default constructor
99 DefineInput(2, TObjArray::Class()); // v0 list
100 DefineOutput(2, TObjArray::Class()); // pid info list
104 //________________________________________________________________________
105 void AliTRDcheckPID::LocalInit()
107 // Initialize working data
108 fReconstructor = new AliTRDReconstructor();
109 fReconstructor->SetRecoParam(AliTRDrecoParam::GetLowFluxParam());
111 // Initialize momentum axis with default values
112 Double_t defaultMomenta[AliTRDCalPID::kNMom+1];
113 for(Int_t imom = 0; imom < AliTRDCalPID::kNMom+1; imom++)
114 defaultMomenta[imom] = AliTRDCalPID::GetMomentumBinning(imom);
115 SetMomentumBinning(AliTRDCalPID::kNMom, defaultMomenta);
117 memset(fEfficiency, 0, AliPID::kSPECIES*sizeof(TObjArray*));
119 fUtil = new AliTRDpidUtil();
122 //________________________________________________________________________
123 AliTRDcheckPID::~AliTRDcheckPID()
125 if(fPID){fPID->Delete(); delete fPID;}
126 if(fGraph){fGraph->Delete(); delete fGraph;}
127 if(fReconstructor) delete fReconstructor;
128 if(fUtil) delete fUtil;
132 //________________________________________________________________________
133 void AliTRDcheckPID::UserCreateOutputObjects()
138 if(!HasFunctorList()) InitFunctorList();
139 fContainer = Histos();
141 fPID = new TObjArray();
142 fPID->SetOwner(kTRUE);
145 //________________________________________________________
146 void AliTRDcheckPID::UserExec(Option_t *opt)
152 fV0s = dynamic_cast<TObjArray *>(GetInputData(2));
155 AliTRDrecoTask::UserExec(opt);
161 //_______________________________________________________
162 TObjArray * AliTRDcheckPID::Histos(){
165 // Create QA histograms
167 if(fContainer) return fContainer;
169 Int_t xBins = AliPID::kSPECIES*fMomentumAxis->GetNbins();
170 fContainer = new TObjArray(); fContainer->Expand(kNPlots);
172 const Float_t epsilon = 1./(2*(AliTRDpidUtil::kBins-1)); // get nice histos with bin center at 0 and 1
175 const Int_t kNmethodsPID=Int_t(sizeof(fgMethod)/sizeof(Char_t*));
176 // histos with posterior probabilities for all particle species
177 for(Int_t is=AliPID::kSPECIES; is--;){
178 fEfficiency[is] = new TObjArray(kNmethodsPID);
179 fEfficiency[is]->SetOwner();
180 fEfficiency[is]->SetName(Form("Eff_%s", AliPID::ParticleShortName(is)));
181 fContainer->AddAt(fEfficiency[is], is?kEfficiencyMu+is-1:kEfficiency);
182 for(Int_t im=kNmethodsPID; im--;){
183 if(!(h = (TH2F*)gROOT->FindObject(Form("PID_%s_%s", fgMethod[im], AliPID::ParticleShortName(is))))) {
184 h = new TH2F(Form("PID_%s_%s", fgMethod[im], AliPID::ParticleShortName(is)), "", xBins, -0.5, xBins - 0.5,
185 AliTRDpidUtil::kBins, 0.-epsilon, 1.+epsilon);
187 fEfficiency[is]->AddAt(h, im);
191 // histos of the dE/dx distribution for all 5 particle species and 11 momenta
192 if(!(h = (TH2F*)gROOT->FindObject("dEdx"))){
193 h = new TH2F("dEdx", "",
194 xBins, -0.5, xBins - 0.5,
198 fContainer->AddAt(h, kdEdx);
200 // histos of the dE/dx slices for all 5 particle species and 11 momenta
201 if(!(h = (TH2F*)gROOT->FindObject("dEdxSlice"))){
202 h = new TH2F("dEdxSlice", "",
203 xBins*AliTRDpidUtil::kLQslices, -0.5, xBins*AliTRDpidUtil::kLQslices - 0.5,
206 fContainer->AddAt(h, kdEdxSlice);
208 // histos of the pulse height distribution for all 5 particle species and 11 momenta
209 TObjArray *fPH = new TObjArray(2);
210 fPH->SetOwner(); fPH->SetName("PH");
211 fContainer->AddAt(fPH, kPH);
212 if(!(h = (TProfile2D*)gROOT->FindObject("PHT"))){
213 h = new TProfile2D("PHT", "",
214 xBins, -0.5, xBins - 0.5,
215 AliTRDtrackerV1::GetNTimeBins(), -0.5, AliTRDtrackerV1::GetNTimeBins() - 0.5);
218 if(!(h = (TProfile2D*)gROOT->FindObject("PHX"))){
219 h = new TProfile2D("PHX", "",
220 xBins, -0.5, xBins - 0.5,
221 AliTRDtrackerV1::GetNTimeBins(), 0., .5*AliTRDgeometry::CamHght()+AliTRDgeometry::CdrHght());
225 // histos of the number of clusters distribution for all 5 particle species and 11 momenta
226 if(!(h = (TH2F*)gROOT->FindObject("NClus"))){
227 h = new TH2F("NClus", "",
228 xBins, -0.5, xBins - 0.5,
231 fContainer->AddAt(h, kNClus);
234 // momentum distributions - absolute and in momentum bins
235 if(!(h = (TH1F*)gROOT->FindObject("hMom"))){
236 h = new TH1F("hMom", "momentum distribution", fMomentumAxis->GetNbins(), fMomentumAxis->GetXmin(), fMomentumAxis->GetXmax());
238 fContainer->AddAt(h, kMomentum);
240 if(!(h = (TH1F*)gROOT->FindObject("hMomBin"))){
241 h = new TH1F("hMomBin", "momentum distribution in momentum bins", fMomentumAxis->GetNbins(), fMomentumAxis->GetXmin(), fMomentumAxis->GetXmax());
243 fContainer->AddAt(h, kMomentumBin);
245 // Number of tracklets per track
246 if(!(h = (TH2F*)gROOT->FindObject("nTracklets"))){
247 h = new TH2F("nTracklets", "",
248 xBins, -0.5, xBins - 0.5,
249 AliTRDgeometry::kNlayer, 0.5, AliTRDgeometry::kNlayer+.5);
251 fContainer->AddAt(h, kNTracklets);
254 if(!(h = (TH1F*)gROOT->FindObject("nV0"))){
255 h = new TH1F("nV0", "V0s/track;v0/track;entries",
258 fContainer->AddAt(h, kV0);
264 //________________________________________________________________________
265 Bool_t AliTRDcheckPID::CheckTrackQuality(const AliTRDtrackV1* track) const
268 // Check if the track is ok for PID
271 Int_t ntracklets = track->GetNumberOfTracklets();
272 if(ntracklets >= fMinNTracklets && ntracklets <= fMaxNTracklets) return 1;
279 //________________________________________________________________________
280 Int_t AliTRDcheckPID::CalcPDG(AliTRDtrackV1* track)
282 // Documentation to come
284 track -> SetReconstructor(fReconstructor);
285 (const_cast<AliTRDrecoParam*>(fReconstructor->GetRecoParam()))->SetPIDNeuralNetwork();
288 if(track -> GetPID(AliPID::kElectron) > track -> GetPID(AliPID::kMuon) + track -> GetPID(AliPID::kPion) + track -> GetPID(AliPID::kKaon) + track -> GetPID(AliPID::kProton)){
291 else if(track -> GetPID(kProton) > track -> GetPID(AliPID::kPion) && track -> GetPID(AliPID::kProton) > track -> GetPID(AliPID::kKaon) && track -> GetPID(AliPID::kProton) > track -> GetPID(AliPID::kMuon)){
294 else if(track -> GetPID(AliPID::kKaon) > track -> GetPID(AliPID::kMuon) && track -> GetPID(AliPID::kKaon) > track -> GetPID(AliPID::kPion)){
297 else if(track -> GetPID(AliPID::kMuon) > track -> GetPID(AliPID::kPion)){
306 //_______________________________________________________
307 TH1 *AliTRDcheckPID::PlotLQ(const AliTRDtrackV1 *track)
310 // Plot the probabilities for electrons using 2-dim LQ
314 AliDebug(2, "No ESD info available.");
318 if(track) fkTrack = track;
320 AliDebug(2, "No Track defined.");
325 status = fkESD -> GetStatus();
326 if(!(status&AliESDtrack::kTRDin)) return NULL;
328 if(!CheckTrackQuality(fkTrack)) return NULL;
330 AliTRDtrackV1 cTrack(*fkTrack);
331 cTrack.SetReconstructor(fReconstructor);
334 Float_t momentum = 0.;
337 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
338 pdg = fkMC->GetPDG();
340 //AliWarning("No MC info available!");
341 momentum = cTrack.GetMomentum(0);
342 pdg = CalcPDG(&cTrack);
344 if(!IsInRange(momentum)) return NULL;
346 (const_cast<AliTRDrecoParam*>(fReconstructor->GetRecoParam()))->SetPIDNeuralNetwork(kFALSE);
348 if(cTrack.GetNumberOfTrackletsPID() < fMinNTracklets) return NULL;
349 Int_t species = AliTRDpidUtil::Pdg2Pid(pdg);
352 TObjArray *eff(NULL);
353 for(Int_t is=AliPID::kSPECIES; is--;){
354 if(!(eff = dynamic_cast<TObjArray *>(fContainer->At(is?kEfficiencyMu+is-1:kEfficiency)))){
355 AliWarning("No Histogram List defined.");
358 if(!(hPIDLQ = dynamic_cast<TH2F *>(eff->At(AliTRDpidUtil::kLQ)))){
359 AliWarning("No Histogram defined.");
363 hPIDLQ -> Fill(FindBin(species, momentum), cTrack.GetPID(is));
371 //_______________________________________________________
372 TH1 *AliTRDcheckPID::PlotNN(const AliTRDtrackV1 *track)
375 // Plot the probabilities for electrons using 2-dim LQ
379 AliDebug(2, "No ESD info available.");
383 if(track) fkTrack = track;
385 AliDebug(2, "No Track defined.");
390 status = fkESD -> GetStatus();
391 if(!(status&AliESDtrack::kTRDin)) return NULL;
393 if(!CheckTrackQuality(fkTrack)) return NULL;
395 AliTRDtrackV1 cTrack(*fkTrack);
396 cTrack.SetReconstructor(fReconstructor);
399 Float_t momentum = 0.;
401 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
402 pdg = fkMC->GetPDG();
404 //AliWarning("No MC info available!");
405 momentum = cTrack.GetMomentum(0);
406 pdg = CalcPDG(&cTrack);
408 if(!IsInRange(momentum)) return NULL;
410 (const_cast<AliTRDrecoParam*>(fReconstructor->GetRecoParam()))->SetPIDNeuralNetwork();
412 if(cTrack.GetNumberOfTrackletsPID() < fMinNTracklets) return NULL;
414 Int_t species = AliTRDpidUtil::Pdg2Pid(pdg);
418 TObjArray *eff(NULL);
419 for(Int_t is=AliPID::kSPECIES; is--;){
420 if(!(eff = dynamic_cast<TObjArray *>(fContainer->At(is?kEfficiencyMu+is-1:kEfficiency)))){
421 AliWarning("No Histogram List defined.");
424 if(!(hPIDNN = dynamic_cast<TH2F *>(eff->At(AliTRDpidUtil::kNN)))){
425 AliWarning("No Histogram defined.");
429 hPIDNN->Fill(FindBin(species, momentum), cTrack.GetPID(is));
436 //_______________________________________________________
437 TH1 *AliTRDcheckPID::PlotESD(const AliTRDtrackV1 *track)
440 // Plot the probabilities for electrons using 2-dim LQ
444 AliDebug(2, "No ESD info available.");
448 if(track) fkTrack = track;
450 AliDebug(2, "No Track defined.");
455 status = fkESD -> GetStatus();
456 if(!(status&AliESDtrack::kTRDin)) return NULL;
458 if(!CheckTrackQuality(fkTrack)) return NULL;
459 if(fkTrack->GetNumberOfTrackletsPID() < fMinNTracklets) return NULL;
462 Float_t momentum = 0.;
464 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
465 pdg = fkMC->GetPDG();
467 //AliWarning("No MC info available!");
468 AliTRDtrackV1 cTrack(*fkTrack);
469 cTrack.SetReconstructor(fReconstructor);
470 momentum = cTrack.GetMomentum(0);
471 pdg = CalcPDG(&cTrack);
473 if(!IsInRange(momentum)) return NULL;
475 const Double32_t *pidESD = fkESD->GetResponseIter();
476 Int_t species = AliTRDpidUtil::Pdg2Pid(pdg);
479 TObjArray *eff(NULL);
480 for(Int_t is=AliPID::kSPECIES; is--;){
481 if(!(eff = dynamic_cast<TObjArray *>(fContainer->At(is?kEfficiencyMu+is-1:kEfficiency)))){
482 AliWarning("No Histogram List defined.");
485 if(!(hPID = dynamic_cast<TH2F *>(eff->At(AliTRDpidUtil::kESD)))){
486 AliWarning("No Histogram defined.");
490 hPID->Fill(FindBin(species, momentum), pidESD[is]);
497 //_______________________________________________________
498 TH1 *AliTRDcheckPID::PlotdEdx(const AliTRDtrackV1 *track)
501 // Plot the probabilities for electrons using 2-dim LQ
504 if(track) fkTrack = track;
506 AliDebug(2, "No Track defined.");
510 if(!CheckTrackQuality(fkTrack)) return NULL;
513 if(!(hdEdx = dynamic_cast<TH2F *>(fContainer->At(kdEdx)))){
514 AliWarning("No Histogram defined.");
518 AliTRDtrackV1 cTrack(*fkTrack);
519 cTrack.SetReconstructor(fReconstructor);
521 Float_t momentum = 0.;
523 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
524 pdg = fkMC->GetPDG();
526 //AliWarning("No MC info available!");
527 momentum = cTrack.GetMomentum(0);
528 pdg = CalcPDG(&cTrack);
530 if(!IsInRange(momentum)) return NULL;
532 // Init exchange container
533 Int_t s(AliTRDpidUtil::Pdg2Pid(pdg));
534 AliTRDpidInfo *pid = new AliTRDpidInfo(s);
536 (const_cast<AliTRDrecoParam*>(fReconstructor->GetRecoParam()))->SetPIDNeuralNetwork(kTRUE);
539 Int_t iBin = FindBin(s, momentum);
540 AliTRDseedV1 *tracklet = NULL;
541 for(Int_t ily = 0; ily < AliTRDgeometry::kNlayer; ily++){
542 tracklet = cTrack.GetTracklet(ily);
543 if(!tracklet) continue;
544 tracklet -> CookdEdx(AliTRDpidUtil::kNNslices);
546 // fill exchange container
547 pid->PushBack(tracklet->GetPlane(),
548 AliTRDpidUtil::GetMomentumBin(tracklet->GetMomentum()), tracklet->GetdEdx());
551 for(Int_t i = AliTRDpidUtil::kNNslices; i--;) sumdEdx += tracklet->GetdEdx()[i];
552 sumdEdx /= AliTRDCalPIDNN::kMLPscale;
553 hdEdx -> Fill(iBin, sumdEdx);
561 //_______________________________________________________
562 TH1 *AliTRDcheckPID::PlotdEdxSlice(const AliTRDtrackV1 *track)
565 // Plot the probabilities for electrons using 2-dim LQ
568 if(track) fkTrack = track;
570 AliDebug(2, "No Track defined.");
574 if(!CheckTrackQuality(fkTrack)) return NULL;
577 if(!(hdEdxSlice = dynamic_cast<TH2F *>(fContainer->At(kdEdxSlice)))){
578 AliWarning("No Histogram defined.");
582 AliTRDtrackV1 cTrack(*fkTrack);
583 cTrack.SetReconstructor(fReconstructor);
585 Float_t momentum = 0.;
587 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
588 pdg = fkMC->GetPDG();
590 //AliWarning("No MC info available!");
591 momentum = cTrack.GetMomentum(0);
592 pdg = CalcPDG(&cTrack);
594 if(!IsInRange(momentum)) return NULL;
596 (const_cast<AliTRDrecoParam*>(fReconstructor->GetRecoParam()))->SetPIDNeuralNetwork(kFALSE);
597 Int_t iMomBin = fMomentumAxis->FindBin(momentum);
598 Int_t species = AliTRDpidUtil::Pdg2Pid(pdg);
600 AliTRDseedV1 *tracklet = NULL;
601 for(Int_t iChamb = 0; iChamb < AliTRDgeometry::kNlayer; iChamb++){
602 tracklet = cTrack.GetTracklet(iChamb);
603 if(!tracklet) continue;
604 tracklet -> CookdEdx(AliTRDpidUtil::kLQslices);
605 fdEdx = const_cast<Float_t *>(tracklet->GetdEdx());
606 for(Int_t iSlice = 0; iSlice < AliTRDpidUtil::kLQslices; iSlice++){
607 hdEdxSlice -> Fill(species * fMomentumAxis->GetNbins() * AliTRDpidUtil::kLQslices + (iMomBin-1) * AliTRDpidUtil::kLQslices + iSlice, fdEdx[iSlice]);
615 //_______________________________________________________
616 TH1 *AliTRDcheckPID::PlotPH(const AliTRDtrackV1 *track)
619 // Plot the probabilities for electrons using 2-dim LQ
622 if(track) fkTrack = track;
624 AliDebug(2, "No Track defined.");
628 if(!CheckTrackQuality(fkTrack)) return NULL;
630 TObjArray *arr = NULL;
631 TProfile2D *hPHX, *hPHT;
632 if(!(arr = dynamic_cast<TObjArray *>(fContainer->At(kPH)))){
633 AliWarning("No Histogram defined.");
636 hPHT = (TProfile2D*)arr->At(0);
637 hPHX = (TProfile2D*)arr->At(1);
640 Float_t momentum = 0.;
642 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
643 pdg = fkMC->GetPDG();
645 //AliWarning("No MC info available!");
646 AliTRDtrackV1 cTrack(*fkTrack);
647 cTrack.SetReconstructor(fReconstructor);
648 momentum = cTrack.GetMomentum(0);
649 pdg = CalcPDG(&cTrack);
651 if(!IsInRange(momentum)) return NULL;;
653 AliTRDseedV1 *tracklet = NULL;
654 AliTRDcluster *cluster = NULL;
655 Int_t species = AliTRDpidUtil::Pdg2Pid(pdg);
656 Int_t iBin = FindBin(species, momentum);
657 for(Int_t iChamb = 0; iChamb < AliTRDgeometry::kNlayer; iChamb++){
658 tracklet = fkTrack->GetTracklet(iChamb);
659 if(!tracklet) continue;
660 Float_t x0 = tracklet->GetX0();
661 for(Int_t ic = 0; ic < AliTRDtrackerV1::GetNTimeBins(); ic++){
662 if(!(cluster = tracklet->GetClusters(ic))) continue;
663 hPHT -> Fill(iBin, cluster->GetLocalTimeBin(), TMath::Abs(cluster->GetQ()));
664 hPHX -> Fill(iBin, x0 - cluster->GetX(), tracklet->GetdQdl(ic));
671 //_______________________________________________________
672 TH1 *AliTRDcheckPID::PlotNClus(const AliTRDtrackV1 *track)
675 // Plot the probabilities for electrons using 2-dim LQ
678 if(track) fkTrack = track;
680 AliDebug(2, "No Track defined.");
684 if(!CheckTrackQuality(fkTrack)) return NULL;
687 if(!(hNClus = dynamic_cast<TH2F *>(fContainer->At(kNClus)))){
688 AliWarning("No Histogram defined.");
694 Float_t momentum = 0.;
696 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
697 pdg = fkMC->GetPDG();
699 //AliWarning("No MC info available!");
700 AliTRDtrackV1 cTrack(*fkTrack);
701 cTrack.SetReconstructor(fReconstructor);
702 momentum = cTrack.GetMomentum(0);
703 pdg = CalcPDG(&cTrack);
705 if(!IsInRange(momentum)) return NULL;
707 Int_t species = AliTRDpidUtil::AliTRDpidUtil::Pdg2Pid(pdg);
708 Int_t iBin = FindBin(species, momentum);
709 AliTRDseedV1 *tracklet = NULL;
710 for(Int_t iChamb = 0; iChamb < AliTRDgeometry::kNlayer; iChamb++){
711 tracklet = fkTrack->GetTracklet(iChamb);
712 if(!tracklet) continue;
713 hNClus -> Fill(iBin, tracklet->GetN());
719 //_______________________________________________________
720 TH1 *AliTRDcheckPID::PlotNTracklets(const AliTRDtrackV1 *track)
723 // Plot the probabilities for electrons using 2-dim LQ
726 if(track) fkTrack = track;
728 AliDebug(2, "No Track defined.");
733 if(!(hTracklets = dynamic_cast<TH2F *>(fContainer->At(kNTracklets)))){
734 AliWarning("No Histogram defined.");
738 AliTRDtrackV1 cTrack(*fkTrack);
739 cTrack.SetReconstructor(fReconstructor);
741 Float_t momentum = 0.;
743 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
744 pdg = fkMC->GetPDG();
746 //AliWarning("No MC info available!");
747 momentum = cTrack.GetMomentum(0);
748 pdg = CalcPDG(&cTrack);
750 Int_t species = AliTRDpidUtil::Pdg2Pid(pdg);
751 if(!IsInRange(momentum)) return NULL;
753 Int_t iBin = FindBin(species, momentum);
754 hTracklets -> Fill(iBin, cTrack.GetNumberOfTracklets());
758 //_______________________________________________________
759 TH1 *AliTRDcheckPID::PlotMom(const AliTRDtrackV1 *track)
762 // Plot the probabilities for electrons using 2-dim LQ
765 if(track) fkTrack = track;
767 AliDebug(2, "No Track defined.");
771 if(!CheckTrackQuality(fkTrack)) return NULL;
774 if(!(hMom = dynamic_cast<TH1F *>(fContainer->At(kMomentum)))){
775 AliWarning("No Histogram defined.");
781 Float_t momentum = 0.;
783 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
784 pdg = fkMC->GetPDG();
786 //AliWarning("No MC info available!");
787 AliTRDtrackV1 cTrack(*fkTrack);
788 cTrack.SetReconstructor(fReconstructor);
789 momentum = cTrack.GetMomentum(0);
790 pdg = CalcPDG(&cTrack);
792 if(IsInRange(momentum)) hMom -> Fill(momentum);
797 //_______________________________________________________
798 TH1 *AliTRDcheckPID::PlotMomBin(const AliTRDtrackV1 *track)
801 // Plot the probabilities for electrons using 2-dim LQ
804 if(track) fkTrack = track;
806 AliDebug(2, "No Track defined.");
810 if(!CheckTrackQuality(fkTrack)) return NULL;
813 if(!(hMomBin = dynamic_cast<TH1F *>(fContainer->At(kMomentumBin)))){
814 AliWarning("No Histogram defined.");
820 Float_t momentum = 0.;
823 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
824 pdg = fkMC->GetPDG();
826 //AliWarning("No MC info available!");
827 AliTRDtrackV1 cTrack(*fkTrack);
828 cTrack.SetReconstructor(fReconstructor);
829 momentum = cTrack.GetMomentum(0);
831 if(IsInRange(momentum)) hMomBin -> Fill(fMomentumAxis->FindBin(momentum));
835 //_______________________________________________________
836 TH1 *AliTRDcheckPID::PlotV0(const AliTRDtrackV1 *track)
839 // Plot the V0 performance against MC
842 if(track) fkTrack = track;
844 AliDebug(2, "No Track defined.");
847 if(!fkESD->HasV0()) return NULL;
849 AliDebug(1, "No MC defined.");
853 AliWarning("No output container defined.");
856 AliDebug(2, Form("TRACK[%d] species[%s][%d]\n", fkESD->GetId(), AliPID::ParticleShortName(fkMC->GetPID()), fkMC->GetPDG()));
858 TH1 *h=dynamic_cast<TH1F*>(fContainer->At(kV0));
859 Int_t sgn(0), n(0); AliTRDv0Info *v0(NULL);
860 for(Int_t iv0(fV0s->GetEntriesFast()); iv0--;){
861 if(!(v0=(AliTRDv0Info*)fV0s->At(iv0))) continue;
862 if(!(sgn = v0->HasTrack(fkESD->GetId()))) continue;
863 //for(Int_t is=AliPID::kSPECIES; is--;) v0->GetPID(is, track);
872 //________________________________________________________
873 Bool_t AliTRDcheckPID::GetRefFigure(Int_t ifig)
875 // Steering function to retrieve performance plots
877 Bool_t kFIRST = kTRUE;
878 TGraphErrors *g = NULL;
880 TObjArray *arr = NULL;
881 TH1 *h1 = NULL, *h=NULL;
883 TList *content = NULL;
886 gPad->Divide(2, 1, 1.e-5, 1.e-5);
887 TList *l=gPad->GetListOfPrimitives();
888 TVirtualPad *pad = ((TVirtualPad*)l->At(0));pad->cd();
889 pad->SetMargin(0.1, 0.01, 0.1, 0.01);
891 TLegend *legEff = new TLegend(.64, .84, .98, .98);
892 legEff->SetBorderSize(1);legEff->SetTextSize(0.03255879);
893 legEff->SetFillColor(0);
894 h=new TH1S("hEff", "", 1, .5, 11.);
895 h->SetLineColor(1);h->SetLineWidth(1);
897 ax->SetTitle("p [GeV/c]");
898 ax->SetRangeUser(.5, 11.);
899 ax->SetMoreLogLabels();
901 ax->SetTitle("#epsilon_{#pi} [%]");
903 ax->SetRangeUser(1.e-2, 10.);
905 content = (TList *)fGraph->FindObject(Form("Eff_%s", AliTRDCalPID::GetPartName(AliPID::kPion)));
906 if(!(g = (TGraphErrors*)content->At(AliTRDpidUtil::kLQ))) break;
907 if(!g->GetN()) break;
908 legEff->SetHeader("PID Method [PION]");
909 g->Draw("pc"); legEff->AddEntry(g, "LQ 2D", "pl");
910 if(! (g = (TGraphErrors*)content->At(AliTRDpidUtil::kNN))) break;
911 g->Draw("pc"); legEff->AddEntry(g, "NN", "pl");
912 if(! (g = (TGraphErrors*)content->At(AliTRDpidUtil::kESD))) break;
913 g->Draw("p"); legEff->AddEntry(g, "ESD", "pl");
921 pad = ((TVirtualPad*)l->At(1));pad->cd();
922 pad->SetMargin(0.1, 0.01, 0.1, 0.01);
923 h=new TH1S("hThr", "", 1, .5, 11.);
924 h->SetLineColor(1);h->SetLineWidth(1);
926 ax->SetTitle("p [GeV/c]");
927 ax->SetMoreLogLabels();
929 ax->SetTitle("Threshold [%]");
930 ax->SetRangeUser(5.e-2, 1.);
932 content = (TList *)fGraph->FindObject("Thres");
933 if(!(g = (TGraphErrors*)content->At(AliTRDpidUtil::kLQ))) break;
934 if(!g->GetN()) break;
936 if(!(g = (TGraphErrors*)content->At(AliTRDpidUtil::kNN))) break;
938 if(!(g = (TGraphErrors*)content->At(AliTRDpidUtil::kESD))) break;
946 gPad->Divide(2, 1, 1.e-5, 1.e-5);
947 TList *l=gPad->GetListOfPrimitives();
948 TVirtualPad *pad = ((TVirtualPad*)l->At(0));pad->cd();
949 pad->SetMargin(0.1, 0.01, 0.1, 0.01);
951 TLegend *legEff = new TLegend(.64, .84, .98, .98);
952 legEff->SetBorderSize(1);legEff->SetTextSize(0.03255879);
953 legEff->SetFillColor(0);
954 h = (TH1S*)gROOT->FindObject("hEff");
955 h=(TH1S*)h->Clone("hEff_K");
956 h->SetYTitle("#epsilon_{K} [%]");
957 h->GetYaxis()->SetRangeUser(1.e-2, 1.e2);
959 content = (TList *)fGraph->FindObject(Form("Eff_%s", AliTRDCalPID::GetPartName(AliPID::kKaon)));
960 if(!(g = (TGraphErrors*)content->At(AliTRDpidUtil::kLQ))) break;
961 if(!g->GetN()) break;
962 legEff->SetHeader("PID Method [KAON]");
963 g->Draw("pc"); legEff->AddEntry(g, "LQ 2D", "pl");
964 if(! (g = (TGraphErrors*)content->At(AliTRDpidUtil::kNN))) break;
965 g->Draw("pc"); legEff->AddEntry(g, "NN", "pl");
966 if(! (g = (TGraphErrors*)content->At(AliTRDpidUtil::kESD))) break;
967 g->Draw("p"); legEff->AddEntry(g, "ESD", "pl");
974 TLegend *legEff2 = new TLegend(.64, .84, .98, .98);
975 legEff2->SetBorderSize(1);legEff2->SetTextSize(0.03255879);
976 legEff2->SetFillColor(0);
977 pad = ((TVirtualPad*)l->At(1));pad->cd();
978 pad->SetMargin(0.1, 0.01, 0.1, 0.01);
979 h=(TH1S*)h->Clone("hEff_p");
980 h->SetYTitle("#epsilon_{p} [%]");
981 h->GetYaxis()->SetRangeUser(1.e-2, 1.e2);
983 content = (TList *)fGraph->FindObject(Form("Eff_%s", AliTRDCalPID::GetPartName(AliPID::kProton)));
984 if(!(g = (TGraphErrors*)content->At(AliTRDpidUtil::kLQ))) break;
985 if(!g->GetN()) break;
986 legEff2->SetHeader("PID Method [PROTON]");
987 g->Draw("pc"); legEff2->AddEntry(g, "LQ 2D", "pl");
988 if(! (g = (TGraphErrors*)content->At(AliTRDpidUtil::kNN))) break;
989 g->Draw("pc"); legEff2->AddEntry(g, "NN", "pl");
990 if(! (g = (TGraphErrors*)content->At(AliTRDpidUtil::kESD))) break;
991 g->Draw("p"); legEff2->AddEntry(g, "ESD", "pl");
1000 // save 2.0 GeV projection as reference
1001 TLegend *legdEdx = new TLegend(.7, .7, .98, .98);
1002 legdEdx->SetBorderSize(1);
1004 if(!(h2 = (TH2F*)(fContainer->At(kdEdx)))) break;
1005 legdEdx->SetHeader("Particle Species");
1006 gPad->SetMargin(0.1, 0.01, 0.1, 0.01);
1007 for(Int_t is = AliPID::kSPECIES-1; is>=0; is--){
1008 Int_t bin = FindBin(is, 2.);
1009 h1 = h2->ProjectionY(Form("px%d", is), bin, bin);
1010 if(!h1->GetEntries()) continue;
1011 h1->Scale(1./h1->Integral());
1012 h1->SetLineColor(AliTRDCalPID::GetPartColor(is));
1014 h1->GetXaxis()->SetTitle("dE/dx (a.u.)");
1015 h1->GetYaxis()->SetTitle("<Entries>");
1017 h = (TH1F*)h1->DrawClone(kFIRST ? "c" : "samec");
1018 legdEdx->AddEntry(h, Form("%s", AliTRDCalPID::GetPartName(is)), "l");
1032 gPad->Divide(2, 1, 1.e-5, 1.e-5);
1033 TList *l=gPad->GetListOfPrimitives();
1035 // save 2.0 GeV projection as reference
1036 TLegend *legPH = new TLegend(.4, .7, .68, .98);
1037 legPH->SetBorderSize(1);legPH->SetFillColor(0);
1038 legPH->SetHeader("Particle Species");
1039 if(!(arr = (TObjArray*)(fContainer->At(kPH)))) break;
1040 if(!(h2 = (TProfile2D*)(arr->At(0)))) break;
1042 TVirtualPad *pad = ((TVirtualPad*)l->At(0));pad->cd();
1043 pad->SetMargin(0.1, 0.01, 0.1, 0.01);
1045 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1046 Int_t bin = FindBin(is, 2.);
1047 h1 = h2->ProjectionY(Form("pyt%d", is), bin, bin);
1048 if(!h1->GetEntries()) continue;
1049 h1->SetMarkerStyle(24);
1050 h1->SetMarkerColor(AliTRDCalPID::GetPartColor(is));
1051 h1->SetLineColor(AliTRDCalPID::GetPartColor(is));
1053 h1->GetXaxis()->SetTitle("t_{drift} [100*ns]");
1054 h1->GetYaxis()->SetTitle("<dQ/dt> [a.u.]");
1056 h = (TH1F*)h1->DrawClone(kFIRST ? "c" : "samec");
1057 legPH->AddEntry(h, Form("%s", AliTRDCalPID::GetPartName(is)), "pl");
1061 pad = ((TVirtualPad*)l->At(1));pad->cd();
1062 pad->SetMargin(0.1, 0.01, 0.1, 0.01);
1063 if(!(h2 = (TProfile2D*)(arr->At(1)))) break;
1065 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1066 Int_t bin = FindBin(is, 2.);
1067 h1 = h2->ProjectionY(Form("pyx%d", is), bin, bin);
1068 if(!h1->GetEntries()) continue;
1069 h1->SetMarkerStyle(24);
1070 h1->SetMarkerColor(AliTRDCalPID::GetPartColor(is));
1071 h1->SetLineColor(AliTRDCalPID::GetPartColor(is));
1073 h1->GetXaxis()->SetTitle("x_{drift} [cm]");
1074 h1->GetYaxis()->SetTitle("<dQ/dl> [a.u./cm]");
1076 h = (TH1F*)h1->DrawClone(kFIRST ? "c" : "samec");
1089 // save 2.0 GeV projection as reference
1090 TLegend *legNClus = new TLegend(.13, .7, .4, .98);
1091 legNClus->SetBorderSize(1);
1092 legNClus->SetFillColor(0);
1095 if(!(h2 = (TH2F*)(fContainer->At(kNClus)))) break;
1096 legNClus->SetHeader("Particle Species");
1097 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1098 Int_t bin = FindBin(is, 2.);
1099 h1 = h2->ProjectionY(Form("pyNClus%d", is), bin, bin);
1100 if(!h1->GetEntries()) continue;
1101 h1->Scale(100./h1->Integral());
1102 //h1->SetMarkerStyle(24);
1103 //h1->SetMarkerColor(AliTRDCalPID::GetPartColor(is));
1104 h1->SetLineColor(AliTRDCalPID::GetPartColor(is));
1106 h1->GetXaxis()->SetTitle("N^{cl}/tracklet");
1107 h1->GetYaxis()->SetTitle("Prob. [%]");
1108 h = (TH1F*)h1->DrawClone("c");
1110 h->GetXaxis()->SetRangeUser(0., 35.);
1112 } else h = (TH1F*)h1->DrawClone("samec");
1114 legNClus->AddEntry(h, Form("%s", AliTRDCalPID::GetPartName(is)), "l");
1128 TLegend *legNClus = new TLegend(.4, .7, .68, .98);
1129 legNClus->SetBorderSize(1);
1131 if(!(h2 = (TH2F*)(fContainer->At(kNTracklets)))) break;
1132 legNClus->SetHeader("Particle Species");
1133 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1134 Int_t bin = FindBin(is, 2.);
1135 h1 = h2->ProjectionY(Form("pyNTracklets%d", is), bin, bin);
1136 if(!h1->GetEntries()) continue;
1137 h1->Scale(100./h1->Integral());
1138 //h1->SetMarkerStyle(24);
1139 //h1->SetMarkerColor(AliTRDCalPID::GetPartColor(is));
1140 h1->SetLineColor(AliTRDCalPID::GetPartColor(is));
1142 h1->GetXaxis()->SetTitle("N^{trklt}/track");
1143 h1->GetXaxis()->SetRangeUser(1.,6.);
1144 h1->GetYaxis()->SetTitle("Prob. [%]");
1146 h = (TH1F*)h1->DrawClone(kFIRST ? "c" : "samec");
1147 legNClus->AddEntry(h, Form("%s", AliTRDCalPID::GetPartName(is)), "l");
1159 AliInfo(Form("Reference plot [%d] missing result", ifig));
1163 //________________________________________________________________________
1164 Bool_t AliTRDcheckPID::PostProcess()
1166 // Draw result to the screen
1167 // Called once at the end of the query
1170 Printf("ERROR: list not available");
1174 TObjArray *eff(NULL);
1176 fGraph = new TObjArray(2*AliPID::kSPECIES);
1179 if(!(eff = dynamic_cast<TObjArray *>(fContainer->At(kEfficiency)))){
1180 AliError("Efficiency container for Electrons missing.");
1183 EvaluateEfficiency(eff, fGraph, AliPID::kPion, 0.9);
1184 EvaluateEfficiency(eff, fGraph, AliPID::kKaon, 0.9);
1185 EvaluateEfficiency(eff, fGraph, AliPID::kProton, 0.9);
1191 //________________________________________________________________________
1192 void AliTRDcheckPID::EvaluateEfficiency(TObjArray * const histoContainer, TObjArray *results, Int_t species, Float_t electronEfficiency){
1193 // Process PID information for pion efficiency
1195 fUtil->SetElectronEfficiency(electronEfficiency);
1198 const Int_t kNmethodsPID=Int_t(sizeof(fgMethod)/sizeof(Char_t*));
1199 Color_t colors[kNmethodsPID] = {kBlue, kGreen+2, kRed};
1200 Int_t markerStyle[kNmethodsPID] = {7, 7, 24};
1201 // efficiency graphs
1202 TGraphErrors *g(NULL);
1203 TObjArray *eff = new TObjArray(kNmethodsPID); eff->SetOwner(); eff->SetName(Form("Eff_%s", AliTRDCalPID::GetPartName(species)));
1204 results->AddAt(eff, species);
1205 for(Int_t iMethod = 0; iMethod < kNmethodsPID; iMethod++){
1206 eff->AddAt(g = new TGraphErrors(), iMethod);
1207 g->SetName(Form("%s", fgMethod[iMethod]));
1208 g->SetLineColor(colors[iMethod]);
1209 g->SetMarkerColor(colors[iMethod]);
1210 g->SetMarkerStyle(markerStyle[iMethod]);
1213 // Threshold graphs if not already
1214 TObjArray *thres(NULL);
1215 if(!(results->At(AliPID::kSPECIES))){
1216 thres = new TObjArray(kNmethodsPID); thres->SetOwner();
1217 thres->SetName("Thres");
1218 results->AddAt(thres, AliPID::kSPECIES);
1219 for(Int_t iMethod = 0; iMethod < kNmethodsPID; iMethod++){
1220 thres->AddAt(g = new TGraphErrors(), iMethod);
1221 g->SetName(Form("%s", fgMethod[iMethod]));
1222 g->SetLineColor(colors[iMethod]);
1223 g->SetMarkerColor(colors[iMethod]);
1224 g->SetMarkerStyle(markerStyle[iMethod]);
1228 TH2F *hPtr[kNmethodsPID]={
1229 (TH2F*)histoContainer->At(AliTRDpidUtil::kLQ),
1230 (TH2F*)histoContainer->At(AliTRDpidUtil::kNN),
1231 (TH2F*)histoContainer->At(AliTRDpidUtil::kESD)
1233 for(Int_t iMom = 0; iMom < fMomentumAxis->GetNbins(); iMom++){
1234 Float_t mom(fMomentumAxis->GetBinCenter(iMom+1));
1236 Int_t binEl(fMomentumAxis->GetNbins() * AliPID::kElectron + iMom + 1),
1237 binXX(fMomentumAxis->GetNbins() * species + iMom + 1);
1239 for(Int_t iMethod = 0; iMethod < kNmethodsPID; iMethod++){
1240 // Calculate the Species Efficiency at electronEfficiency% electron efficiency for each Method
1242 TH1D *histo1 = hPtr[iMethod] -> ProjectionY(Form("%s_el", fgMethod[iMethod]), binEl, binEl);
1243 TH1D *histo2 = hPtr[iMethod] -> ProjectionY(Form("%s_%s", fgMethod[iMethod], AliTRDCalPID::GetPartName(species)), binXX, binXX);
1245 if(!fUtil->CalculatePionEffi(histo1, histo2)) continue;
1247 g=(TGraphErrors*)eff->At(iMethod);
1248 g->SetPoint(iMom, mom, 1.e2*fUtil->GetPionEfficiency());
1249 g->SetPointError(iMom, 0., 1.e2*fUtil->GetError());
1250 AliDebug(2, Form("%s Efficiency for %s is : %f +/- %f", AliTRDCalPID::GetPartName(species), fgMethod[iMethod], fUtil->GetPionEfficiency(), fUtil->GetError()));
1252 if(!thres) continue;
1253 g=(TGraphErrors*)thres->At(iMethod);
1254 g->SetPoint(iMom, mom, fUtil->GetThreshold());
1255 g->SetPointError(iMom, 0., 0.);