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
287 AliWarning("No Track defined.");
293 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclusterTrackletHist)))){
294 AliWarning("No Histogram defined.");
297 AliTRDseedV1 *tracklet = 0x0;
298 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
299 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
300 h->Fill(tracklet->GetN());
305 //_______________________________________________________
306 TH1 *AliTRDcheckDetector::PlotNClusters(const AliTRDtrackV1 *track){
308 // Plot the number of clusters in one track
312 AliWarning("No Track defined.");
318 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclustersHist)))){
319 AliWarning("No Histogram defined.");
324 AliTRDseedV1 *tracklet = 0x0;
325 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
326 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
327 nclusters += tracklet->GetN();
329 Int_t crossing = tracklet->GetNChange();
330 AliTRDcluster *c = 0x0;
331 for(Int_t itime = 0; itime < kNTimeBins; itime++){
332 if(!(c = tracklet->GetClusters(itime))) continue;
335 Int_t detector = c->GetDetector();
336 Float_t sector = static_cast<Int_t>(detector/AliTRDgeometry::kNdets);
337 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
338 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
339 Float_t momentum = 0.;
342 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
345 (*fDebugStream) << "NClusters"
346 << "Detector=" << detector
347 << "Sector=" << sector
348 << "crossing=" << crossing
349 << "momentum=" << momentum
353 << "nclusters=" << nclusters
361 //_______________________________________________________
362 TH1 *AliTRDcheckDetector::PlotChi2(const AliTRDtrackV1 *track){
364 // Plot the chi2 of the track
368 AliWarning("No Track defined.");
374 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChi2)))){
375 AliWarning("No Histogram defined.");
378 h->Fill(fTrack->GetChi2());
382 //_______________________________________________________
383 TH1 *AliTRDcheckDetector::PlotNormalizedChi2(const AliTRDtrackV1 *track){
385 // Plot the chi2 of the track
389 AliWarning("No Track defined.");
395 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChi2Normalized)))){
396 AliWarning("No Histogram defined.");
399 Int_t nTracklets = 0;
400 AliTRDseedV1 *tracklet = 0x0;
401 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
402 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
405 h->Fill(fTrack->GetChi2()/nTracklets);
410 //_______________________________________________________
411 TH1 *AliTRDcheckDetector::PlotNTracklets(const AliTRDtrackV1 *track){
413 // Plot the number of tracklets
417 AliWarning("No Track defined.");
423 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsHist)))){
424 AliWarning("No Histogram defined.");
427 Int_t nTracklets = 0;
428 AliTRDseedV1 *tracklet = 0x0;
429 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
430 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
437 //_______________________________________________________
438 TH1 *AliTRDcheckDetector::PlotPulseHeight(const AliTRDtrackV1 *track){
440 // Plot the average pulse height
444 AliWarning("No Track defined.");
450 if(!(h = dynamic_cast<TProfile *>(fContainer->At(kPulseHeight)))){
451 AliWarning("No Histogram defined.");
454 AliTRDseedV1 *tracklet = 0x0;
455 AliTRDcluster *c = 0x0;
456 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
457 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
458 for(Int_t itime = 0; itime < kNTimeBins; itime++){
459 if(!(c = tracklet->GetClusters(itime))) continue;
460 Int_t localtime = c->GetLocalTimeBin();
461 Double_t absolute_charge = TMath::Abs(c->GetQ());
462 h->Fill(localtime, absolute_charge);
464 Int_t crossing = tracklet->GetNChange();
465 Int_t detector = c->GetDetector();
466 Float_t sector = static_cast<Int_t>(detector/AliTRDgeometry::kNdets);
467 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
468 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
469 Float_t momentum = 0.;
472 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
475 (*fDebugStream) << "PulseHeight"
476 << "Detector=" << detector
477 << "Sector=" << sector
478 << "crossing=" << crossing
479 << "Timebin=" << localtime
480 << "Charge=" << absolute_charge
481 << "momentum=" << momentum
492 //_______________________________________________________
493 TH1 *AliTRDcheckDetector::PlotClusterCharge(const AliTRDtrackV1 *track){
495 // Plot the cluster charge
499 AliWarning("No Track defined.");
505 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kClusterCharge)))){
506 AliWarning("No Histogram defined.");
509 AliTRDseedV1 *tracklet = 0x0;
510 AliTRDcluster *c = 0x0;
511 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
512 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
513 for(Int_t itime = 0; itime < kNTimeBins; itime++){
514 if(!(c = tracklet->GetClusters(itime))) continue;
521 //_______________________________________________________
522 TH1 *AliTRDcheckDetector::PlotChargeDeposit(const AliTRDtrackV1 *track){
524 // Plot the charge deposit per chamber
528 AliWarning("No Track defined.");
534 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChargeDeposit)))){
535 AliWarning("No Histogram defined.");
538 AliTRDseedV1 *tracklet = 0x0;
539 AliTRDcluster *c = 0x0, *c1 = 0x0; // c1 for the Debug Stream
541 for(Int_t itl = 0x0; itl < AliTRDgeometry::kNlayer; itl++){
542 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
545 for(Int_t itime = 0; itime < kNTimeBins; itime++){
546 if(!(c = tracklet->GetClusters(itime))) continue;
548 Qtot += TMath::Abs(c->GetQ());
552 Int_t crossing = tracklet->GetNChange();
553 Int_t detector = c1->GetDetector();
554 Float_t sector = static_cast<Int_t>(detector/AliTRDgeometry::kNdets);
555 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
556 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
557 Float_t momentum = 0.;
560 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
563 (*fDebugStream) << "ChargeDeposit"
564 << "Detector=" << detector
565 << "Sector=" << sector
566 << "crossing=" << crossing
567 << "momentum=" << momentum
578 //_______________________________________________________
579 TH1 *AliTRDcheckDetector::PlotTracksSector(const AliTRDtrackV1 *track){
581 // Plot the number of tracks per Sector
585 AliWarning("No Track defined.");
591 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNTracksSectorHist)))){
592 AliWarning("No Histogram defined.");
595 AliTRDseedV1 *tracklet = 0x0;
596 AliTRDcluster *c = 0x0;
598 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
599 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
600 for(Int_t itime = 0; itime < kNTimeBins; itime++){
601 if(!(c = tracklet->GetClusters(itime))) continue;
602 sector = static_cast<Int_t>(c->GetDetector()/AliTRDgeometry::kNdets);