8 #include <TObjString.h>
10 #include <TProfile2D.h>
14 #include "AliTRDcluster.h"
15 #include "AliESDHeader.h"
16 #include "AliESDRun.h"
17 #include "AliTRDgeometry.h"
18 #include "AliTRDseedV1.h"
19 #include "AliTRDtrackV1.h"
20 #include "AliTrackReference.h"
21 #include "TTreeStream.h"
23 #include "AliTRDtrackInfo/AliTRDtrackInfo.h"
24 #include "AliTRDtrackInfo/AliTRDeventInfo.h"
25 #include "AliTRDcheckDetector.h"
30 ////////////////////////////////////////////////////////////////////////////
32 // Reconstruction QA //
34 // Task doing basic checks for tracking and detector performance //
37 // Anton Andronic <A.Andronic@gsi.de> //
38 // Markus Fasel <M.Fasel@gsi.de> //
40 ////////////////////////////////////////////////////////////////////////////
42 //_______________________________________________________
43 AliTRDcheckDetector::AliTRDcheckDetector():
44 AliTRDrecoTask("DetChecker", "Basic Detector Checker")
49 // Default constructor
51 DefineInput(1,AliTRDeventInfo::Class());
55 //_______________________________________________________
56 AliTRDcheckDetector::~AliTRDcheckDetector(){
60 if(fEventInfo) delete fEventInfo;
61 if(fTriggerNames) delete fTriggerNames;
64 //_______________________________________________________
65 void AliTRDcheckDetector::ConnectInputData(Option_t *opt){
67 // Connect the Input data with the task
69 AliTRDrecoTask::ConnectInputData(opt);
70 fEventInfo = dynamic_cast<AliTRDeventInfo *>(GetInputData(1));
73 //_______________________________________________________
74 void AliTRDcheckDetector::CreateOutputObjects(){
76 // Create Output Objects
78 OpenFile(0,"RECREATE");
79 fContainer = Histos();
80 if(!fTriggerNames) fTriggerNames = new TMap();
83 //_______________________________________________________
84 void AliTRDcheckDetector::Exec(Option_t *opt){
87 // Filling TRD quality histos
89 if(!HasMCdata() && fEventInfo->GetEventHeader()->GetEventType() != 7) return; // For real data we select only physical events
90 AliTRDrecoTask::Exec(opt);
91 Int_t nTracks = 0; // Count the number of tracks per event
92 Int_t triggermask = fEventInfo->GetEventHeader()->GetTriggerMask();
93 TString triggername = fEventInfo->GetRunInfo()->GetFiredTriggerClasses(triggermask);
94 if(fDebugLevel > 6)printf("Trigger cluster: %d, Trigger class: %s\n", triggermask, triggername.Data());
95 dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNEventsTrigger))->Fill(triggermask);
96 for(Int_t iti = 0; iti < fTracks->GetEntriesFast(); iti++){
97 if(!fTracks->UncheckedAt(iti)) continue;
98 AliTRDtrackInfo *fTrackInfo = dynamic_cast<AliTRDtrackInfo *>(fTracks->UncheckedAt(iti));
99 if(!fTrackInfo->GetTrack()) continue;
103 dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNEventsTriggerTracks))->Fill(triggermask);
104 dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNTracksEventHist))->Fill(nTracks);
106 if(triggermask <= 20 && !fTriggerNames->FindObject(Form("%d", triggermask))){
107 fTriggerNames->Add(new TObjString(Form("%d", triggermask)), new TObjString(triggername));
108 // also set the label for both histograms
109 TH1 *histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNEventsTriggerTracks));
110 histo->GetXaxis()->SetBinLabel(histo->FindBin(triggermask), triggername);
111 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNEventsTrigger));
112 histo->GetXaxis()->SetBinLabel(histo->FindBin(triggermask), triggername);
114 PostData(0, fContainer);
117 //_______________________________________________________
118 void AliTRDcheckDetector::Terminate(Option_t *){
120 // Terminate function
124 //_______________________________________________________
125 Bool_t AliTRDcheckDetector::PostProcess(){
127 // Do Postprocessing (for the moment set the number of Reference histograms)
131 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNTracksEventHist));
132 histo->GetXaxis()->SetTitle("Number of Tracks");
133 histo->GetYaxis()->SetTitle("Events");
134 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNclustersHist));
135 histo->GetXaxis()->SetTitle("Number of Clusters");
136 histo->GetYaxis()->SetTitle("Entries");
137 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNtrackletsHist));
138 histo->GetXaxis()->SetTitle("Number of Tracklets");
139 histo->GetYaxis()->SetTitle("Entries");
140 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNclusterTrackletHist));
141 histo->GetXaxis()->SetTitle("Number of Clusters");
142 histo->GetYaxis()->SetTitle("Entries");
143 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kChi2));
144 histo->GetXaxis()->SetTitle("#chi^2");
145 histo->GetYaxis()->SetTitle("Entries");
146 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNTracksSectorHist));
147 histo->GetXaxis()->SetTitle("Sector");
148 histo->GetYaxis()->SetTitle("Number of Tracks");
149 histo = dynamic_cast<TProfile *>(fContainer->UncheckedAt(kPulseHeight));
150 histo->GetXaxis()->SetTitle("Time / 100ns");
151 histo->GetYaxis()->SetTitle("Average Pulse Height (a. u.)");
152 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kClusterCharge));
153 histo->GetXaxis()->SetTitle("Cluster Charge (a.u.)");
154 histo->GetYaxis()->SetTitle("Entries");
155 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kChargeDeposit));
156 histo->GetXaxis()->SetTitle("Charge Deposit (a.u.)");
157 histo->GetYaxis()->SetTitle("Entries");
159 // Calculate the purity of the trigger clusters
160 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNEventsTrigger));
161 TH1F *histoTracks = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNEventsTriggerTracks));
162 histoTracks->Divide(histo);
163 Float_t purities[20], val = 0;
164 TString triggernames[20];
165 Int_t nTriggerClasses = 0;
166 for(Int_t ibin = 1; ibin <= histo->GetNbinsX(); ibin++){
167 if((val = histoTracks->GetBinContent(ibin))){
168 purities[nTriggerClasses] = val;
169 triggernames[nTriggerClasses] = histoTracks->GetXaxis()->GetBinLabel(ibin);
173 TH1F *hTriggerInf = new TH1F("fTriggerInf", "Trigger Information", TMath::Max(nTriggerClasses, 1), 0, TMath::Max(nTriggerClasses, 1));
174 for(Int_t ibin = 1; ibin <= nTriggerClasses; ibin++){
175 hTriggerInf->SetBinContent(ibin, purities[ibin-1]);
176 hTriggerInf->GetXaxis()->SetBinLabel(ibin, triggernames[ibin-1].Data());
178 hTriggerInf->GetXaxis()->SetTitle("Trigger Cluster");
179 hTriggerInf->GetYaxis()->SetTitle("Ratio");
180 hTriggerInf->GetYaxis()->SetRangeUser(0,1);
181 // hTriggerInf->SetMarkerColor(kBlue);
182 // hTriggerInf->SetMarkerStyle(22);
183 fContainer->Add(hTriggerInf);
188 //_______________________________________________________
189 void AliTRDcheckDetector::GetRefFigure(Int_t ifig){
191 // Setting Reference Figures
196 ((TH1F*)fContainer->At(kNTracksEventHist))->Draw("pl");
199 ((TH1F*)fContainer->At(kNclustersHist))->Draw("pl");
202 h = (TH1F*)fContainer->At(kNtrackletsHist);
203 if(!h->GetEntries()) break;
204 h->Scale(100./h->Integral());
205 h->GetXaxis()->SetRangeUser(.5, 6.5);
206 h->SetFillColor(kGreen);
212 ((TH1F*)fContainer->At(kNclusterTrackletHist))->Draw("pc");
215 ((TH1F*)fContainer->At(kChi2))->Draw("");
218 h = (TH1F*)fContainer->At(kNTracksSectorHist);
219 if(!h->GetEntries()) break;
220 h->Scale(100./h->Integral());
221 h->SetFillColor(kGreen);
227 h = (TH1F*)fContainer->At(kPulseHeight);
228 h->SetMarkerStyle(24);
232 ((TH1F*)fContainer->At(kClusterCharge))->Draw("c");
235 ((TH1F*)fContainer->At(kChargeDeposit))->Draw("c");
238 h=(TH1F*)fContainer->At(kPurity);
241 h->SetFillColor(kGreen);
245 ((TH1F*)fContainer->At(kNTracksEventHist))->Draw("pl");
250 //_______________________________________________________
251 TObjArray *AliTRDcheckDetector::Histos(){
253 // Create QA histograms
255 if(fContainer) return fContainer;
257 fContainer = new TObjArray(25);
258 // Register Histograms
259 fContainer->AddAt(new TH1F("hNtrks", "Number of Tracks per event", 100, 0, 100), kNTracksEventHist);
260 fContainer->AddAt(new TH1F("hEventsTriggerTracks", "Trigger Class (Tracks)", 100, 0, 100), kNEventsTriggerTracks);
261 fContainer->AddAt(new TH1F("hNcls", "Nr. of clusters per track", 181, -0.5, 180.5), kNclustersHist);
262 fContainer->AddAt(new TH1F("hNtls", "Nr. tracklets per track", 7, -0.5, 6.5), kNtrackletsHist);
263 fContainer->AddAt(new TH1F("hNclTls","Mean Number of clusters per tracklet", 31, -0.5, 30.5), kNclusterTrackletHist);
264 fContainer->AddAt(new TH1F("hChi2", "Chi2", 200, 0, 20), kChi2);
265 fContainer->AddAt(new TH1F("hChi2n", "Norm. Chi2 (tracklets)", 50, 0, 5), kChi2Normalized);
266 fContainer->AddAt(new TH1F("hSM", "Track Counts in Supermodule", 18, -0.5, 17.5), kNTracksSectorHist);
267 // Detector signal on Detector-by-Detector basis
268 fContainer->AddAt(new TProfile("hPHdetector", "Average PH", 31, -0.5, 30.5), kPulseHeight);
269 fContainer->AddAt(new TH1F("hQclDetector", "Cluster charge", 200, 0, 1200), kClusterCharge);
270 fContainer->AddAt(new TH1F("hQTdetector", "Total Charge Deposit", 6000, 0, 6000), kChargeDeposit);
271 fContainer->AddAt(new TH1F("hEventsTrigger", "Trigger Class", 100, 0, 100), kNEventsTrigger);
280 //_______________________________________________________
281 TH1 *AliTRDcheckDetector::PlotMeanNClusters(const AliTRDtrackV1 *track){
283 // Plot the mean number of clusters per tracklet
285 if(track) fTrack = track;
287 AliWarning("No Track defined.");
291 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclusterTrackletHist)))){
292 AliWarning("No Histogram defined.");
295 AliTRDseedV1 *tracklet = 0x0;
296 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
297 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
298 h->Fill(tracklet->GetN());
303 //_______________________________________________________
304 TH1 *AliTRDcheckDetector::PlotNClusters(const AliTRDtrackV1 *track){
306 // Plot the number of clusters in one track
308 if(track) fTrack = track;
310 AliWarning("No Track defined.");
314 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclustersHist)))){
315 AliWarning("No Histogram defined.");
320 AliTRDseedV1 *tracklet = 0x0;
321 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
322 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
323 nclusters += tracklet->GetN();
325 Int_t crossing = tracklet->GetNChange();
326 AliTRDcluster *c = 0x0;
327 for(Int_t itime = 0; itime < kNTimeBins; itime++){
328 if(!(c = tracklet->GetClusters(itime))) continue;
331 Int_t detector = c->GetDetector();
332 Float_t sector = static_cast<Int_t>(detector/AliTRDgeometry::kNdets);
333 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
334 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
335 Float_t momentum = 0.;
337 Int_t kinkIndex = fESD ? fESD->GetKinkIndex() : 0;
338 UShort_t TPCncls = fESD ? fESD->GetTPCncls() : 0;
340 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
343 (*fDebugStream) << "NClusters"
344 << "Detector=" << detector
345 << "Sector=" << sector
346 << "crossing=" << crossing
347 << "momentum=" << momentum
351 << "kinkIndex=" << kinkIndex
352 << "TPCncls=" << TPCncls
353 << "nclusters=" << nclusters
361 //_______________________________________________________
362 TH1 *AliTRDcheckDetector::PlotChi2(const AliTRDtrackV1 *track){
364 // Plot the chi2 of the track
366 if(track) fTrack = track;
368 AliWarning("No Track defined.");
372 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChi2)))){
373 AliWarning("No Histogram defined.");
376 h->Fill(fTrack->GetChi2());
380 //_______________________________________________________
381 TH1 *AliTRDcheckDetector::PlotNormalizedChi2(const AliTRDtrackV1 *track){
383 // Plot the chi2 of the track
385 if(track) fTrack = track;
387 AliWarning("No Track defined.");
391 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChi2Normalized)))){
392 AliWarning("No Histogram defined.");
395 Int_t nTracklets = 0;
396 AliTRDseedV1 *tracklet = 0x0;
397 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
398 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
401 h->Fill(fTrack->GetChi2()/nTracklets);
406 //_______________________________________________________
407 TH1 *AliTRDcheckDetector::PlotNTracklets(const AliTRDtrackV1 *track){
409 // Plot the number of tracklets
411 if(track) fTrack = track;
413 AliWarning("No Track defined.");
417 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsHist)))){
418 AliWarning("No Histogram defined.");
421 Int_t nTracklets = 0;
422 AliTRDseedV1 *tracklet = 0x0;
423 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
424 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
431 //_______________________________________________________
432 TH1 *AliTRDcheckDetector::PlotPulseHeight(const AliTRDtrackV1 *track){
434 // Plot the average pulse height
436 if(track) fTrack = track;
438 AliWarning("No Track defined.");
442 if(!(h = dynamic_cast<TProfile *>(fContainer->At(kPulseHeight)))){
443 AliWarning("No Histogram defined.");
446 AliTRDseedV1 *tracklet = 0x0;
447 AliTRDcluster *c = 0x0;
448 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
449 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
450 for(Int_t itime = 0; itime < kNTimeBins; itime++){
451 if(!(c = tracklet->GetClusters(itime))) continue;
452 Int_t localtime = c->GetLocalTimeBin();
453 Double_t absolute_charge = TMath::Abs(c->GetQ());
454 h->Fill(localtime, absolute_charge);
456 Int_t crossing = tracklet->GetNChange();
457 Int_t detector = c->GetDetector();
458 Float_t sector = static_cast<Int_t>(detector/AliTRDgeometry::kNdets);
459 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
460 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
461 Float_t momentum = 0.;
463 Int_t kinkIndex = fESD ? fESD->GetKinkIndex() : 0;
464 UShort_t TPCncls = fESD ? fESD->GetTPCncls() : 0;
466 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
469 (*fDebugStream) << "PulseHeight"
470 << "Detector=" << detector
471 << "Sector=" << sector
472 << "crossing=" << crossing
473 << "Timebin=" << localtime
474 << "Charge=" << absolute_charge
475 << "momentum=" << momentum
479 << "kinkIndex=" << kinkIndex
480 << "TPCncls=" << TPCncls
488 //_______________________________________________________
489 TH1 *AliTRDcheckDetector::PlotClusterCharge(const AliTRDtrackV1 *track){
491 // Plot the cluster charge
493 if(track) fTrack = track;
495 AliWarning("No Track defined.");
499 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kClusterCharge)))){
500 AliWarning("No Histogram defined.");
503 AliTRDseedV1 *tracklet = 0x0;
504 AliTRDcluster *c = 0x0;
505 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
506 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
507 for(Int_t itime = 0; itime < kNTimeBins; itime++){
508 if(!(c = tracklet->GetClusters(itime))) continue;
515 //_______________________________________________________
516 TH1 *AliTRDcheckDetector::PlotChargeDeposit(const AliTRDtrackV1 *track){
518 // Plot the charge deposit per chamber
520 if(track) fTrack = track;
522 AliWarning("No Track defined.");
526 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChargeDeposit)))){
527 AliWarning("No Histogram defined.");
530 AliTRDseedV1 *tracklet = 0x0;
531 AliTRDcluster *c = 0x0, *c1 = 0x0; // c1 for the Debug Stream
533 for(Int_t itl = 0x0; itl < AliTRDgeometry::kNlayer; itl++){
534 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
537 for(Int_t itime = 0; itime < kNTimeBins; itime++){
538 if(!(c = tracklet->GetClusters(itime))) continue;
540 Qtot += TMath::Abs(c->GetQ());
544 Int_t crossing = tracklet->GetNChange();
545 Int_t detector = c1->GetDetector();
546 Float_t sector = static_cast<Int_t>(detector/AliTRDgeometry::kNdets);
547 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
548 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
549 Float_t momentum = 0.;
551 Int_t kinkIndex = fESD ? fESD->GetKinkIndex() : 0;
552 UShort_t TPCncls = fESD ? fESD->GetTPCncls() : 0;
554 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
557 (*fDebugStream) << "ChargeDeposit"
558 << "Detector=" << detector
559 << "Sector=" << sector
560 << "crossing=" << crossing
561 << "momentum=" << momentum
565 << "kinkIndex=" << kinkIndex
566 << "TPCncls=" << TPCncls
574 //_______________________________________________________
575 TH1 *AliTRDcheckDetector::PlotTracksSector(const AliTRDtrackV1 *track){
577 // Plot the number of tracks per Sector
579 if(track) fTrack = track;
581 AliWarning("No Track defined.");
585 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNTracksSectorHist)))){
586 AliWarning("No Histogram defined.");
589 AliTRDseedV1 *tracklet = 0x0;
590 AliTRDcluster *c = 0x0;
592 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
593 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
594 for(Int_t itime = 0; itime < kNTimeBins; itime++){
595 if(!(c = tracklet->GetClusters(itime))) continue;
596 sector = static_cast<Int_t>(c->GetDetector()/AliTRDgeometry::kNdets);