1 ////////////////////////////////////////////////////////////////////////////
4 // Basic checks for tracking and detector performance //
6 // For the moment (15.10.2009) the following checks are implemented //
7 // - Number of clusters/track
8 // - Number of clusters/tracklet
9 // - Number of tracklets/track from different sources (Barrel, StandAlone)
10 // - Number of findable tracklets
11 // - Number of tracks per event and TRD sector
13 // - Chi2 distribution for tracks
14 // - Charge distribution per cluster and tracklet
15 // - Number of events and tracks per trigger source
17 // - Track and Tracklet propagation status
20 // Anton Andronic <A.Andronic@gsi.de> //
21 // Alexandru Bercuci <A.Bercuci@gsi.de> //
22 // Markus Fasel <M.Fasel@gsi.de> //
24 ////////////////////////////////////////////////////////////////////////////
35 #include <TGraphErrors.h>
37 #include <TLinearFitter.h>
40 #include <TProfile2D.h>
41 #include <TObjArray.h>
43 #include <TObjString.h>
47 #include <TProfile2D.h>
52 #include "AliTRDcluster.h"
53 #include "AliESDHeader.h"
54 #include "AliESDRun.h"
55 #include "AliESDtrack.h"
56 #include "AliExternalTrackParam.h"
57 #include "AliTRDgeometry.h"
58 #include "AliTRDpadPlane.h"
59 #include "AliTRDSimParam.h"
60 #include "AliTRDseedV1.h"
61 #include "AliTRDtrackV1.h"
62 #include "AliTRDtrackerV1.h"
63 #include "AliTRDReconstructor.h"
64 #include "AliTrackReference.h"
65 #include "AliTrackPointArray.h"
66 #include "AliTracker.h"
67 #include "TTreeStream.h"
69 #include "info/AliTRDtrackInfo.h"
70 #include "info/AliTRDeventInfo.h"
71 #include "AliTRDinfoGen.h"
72 #include "AliTRDcheckDET.h"
77 ClassImp(AliTRDcheckDET)
79 //_______________________________________________________
80 AliTRDcheckDET::AliTRDcheckDET():
87 // Default constructor
89 SetNameTitle("TRDcheckDET", "Basic TRD data checker");
92 //_______________________________________________________
93 AliTRDcheckDET::AliTRDcheckDET(char* name):
94 AliTRDrecoTask(name, "Basic TRD data checker")
100 // Default constructor
106 //_______________________________________________________
107 AliTRDcheckDET::~AliTRDcheckDET(){
111 if(fTriggerNames) delete fTriggerNames;
114 //_______________________________________________________
115 void AliTRDcheckDET::UserCreateOutputObjects(){
117 // Create Output Objects
119 AliTRDrecoTask::UserCreateOutputObjects();
120 if(!fTriggerNames) fTriggerNames = new TMap();
123 //_______________________________________________________
124 void AliTRDcheckDET::UserExec(Option_t *opt){
126 // Execution function
127 // Filling TRD quality histos
129 //AliDebug(2, Form("EventInfo[%p] Header[%p]", (void*)fEventInfo, (void*)(fEvent?fEvent->GetEventHeader():NULL)));
131 AliTRDrecoTask::UserExec(opt);
133 TH1F *histo(NULL); AliTRDtrackInfo *fTrackInfo(NULL); Int_t nTracks(0); // Count the number of tracks per event
134 for(Int_t iti = 0; iti < fTracks->GetEntriesFast(); iti++){
135 if(!fTracks->UncheckedAt(iti)) continue;
136 if(!(fTrackInfo = dynamic_cast<AliTRDtrackInfo *>(fTracks->UncheckedAt(iti)))) continue;
137 if(!fTrackInfo->GetTrack()) continue;
141 if((histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNtracksEvent)))) histo->Fill(nTracks);
143 if(!fEvent->GetEventHeader()) return; // For trigger statistics event header is essential
144 Int_t triggermask = fEventInfo->GetEventHeader()->GetTriggerMask();
145 TString triggername = fEventInfo->GetRunInfo()->GetFiredTriggerClasses(triggermask);
146 AliDebug(6, Form("Trigger cluster: %d, Trigger class: %s\n", triggermask, triggername.Data()));
147 if((histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTrigger)))) histo->Fill(triggermask);
150 if((histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTriggerTracks)))) histo->Fill(triggermask);
152 if(triggermask <= 20 && !fTriggerNames->FindObject(Form("%d", triggermask))){
153 fTriggerNames->Add(new TObjString(Form("%d", triggermask)), new TObjString(triggername));
154 // also set the label for both histograms
155 if((histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTriggerTracks))))
156 histo->GetXaxis()->SetBinLabel(histo->FindBin(triggermask), triggername);
157 if((histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTrigger))))
158 histo->GetXaxis()->SetBinLabel(histo->FindBin(triggermask), triggername);
163 //_______________________________________________________
164 Bool_t AliTRDcheckDET::PostProcess(){
166 // Do Postprocessing (for the moment set the number of Reference histograms)
169 TH1F *h(NULL), *h1(NULL);
171 // Calculate of the trigger clusters purity
172 if((h = dynamic_cast<TH1F *>(fContainer->FindObject("hEventsTrigger"))) &&
173 (h1 = dynamic_cast<TH1F *>(fContainer->FindObject("hEventsTriggerTracks")))) {
175 Float_t purities[20], val = 0; memset(purities, 0, 20*sizeof(Float_t));
176 TString triggernames[20];
177 Int_t nTriggerClasses = 0;
178 for(Int_t ibin = 1; ibin <= h->GetNbinsX(); ibin++){
179 if((val = h1->GetBinContent(ibin))){
180 purities[nTriggerClasses] = val;
181 triggernames[nTriggerClasses] = h1->GetXaxis()->GetBinLabel(ibin);
186 if((h = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kTriggerPurity)))){
187 TAxis *ax = h->GetXaxis();
188 for(Int_t itrg = 0; itrg < nTriggerClasses; itrg++){
189 h->Fill(itrg, purities[itrg]);
190 ax->SetBinLabel(itrg+1, triggernames[itrg].Data());
192 ax->SetRangeUser(-0.5, nTriggerClasses+.5);
193 h->GetYaxis()->SetRangeUser(0,1);
198 if((h=dynamic_cast<TH1F*>(fContainer->At(kTrackStatus)))){
199 Float_t ok = h->GetBinContent(1);
200 Int_t nerr = h->GetNbinsX();
201 for(Int_t ierr=nerr; ierr--;){
202 h->SetBinContent(ierr+1, ok>0.?1.e2*h->GetBinContent(ierr+1)/ok:0.);
204 h->SetBinContent(1, 0.);
208 TObjArray *arr(NULL);
209 if(( arr = dynamic_cast<TObjArray*>(fContainer->UncheckedAt(kTrackletStatus)))){
210 for(Int_t ily = AliTRDgeometry::kNlayer; ily--;){
211 if(!(h=dynamic_cast<TH1F*>(arr->At(ily)))) continue;
212 Float_t okB = h->GetBinContent(1);
213 Int_t nerrB = h->GetNbinsX();
214 for(Int_t ierr=nerrB; ierr--;){
215 h->SetBinContent(ierr+1, okB>0.?1.e2*h->GetBinContent(ierr+1)/okB:0.);
217 h->SetBinContent(1, 0.);
225 //_______________________________________________________
226 void AliTRDcheckDET::MakeSummary(){
228 // Create summary plots for TRD check DET
229 // This function creates 2 summary plots:
230 // - General Quantities
232 // The function will reuse GetRefFigure
235 TCanvas *cOut = new TCanvas(Form("summary%s1", GetName()), Form("Summary 1 for task %s", GetName()), 1024, 768);
238 // Create figures using GetRefFigure
239 cOut->cd(1); GetRefFigure(kFigNtracksEvent);
240 cOut->cd(2); GetRefFigure(kFigNtracksSector);
241 cOut->cd(3); GetRefFigure(kFigNclustersTrack);
242 cOut->cd(4); GetRefFigure(kFigNclustersTracklet);
243 cOut->cd(5); GetRefFigure(kFigNtrackletsTrack);
244 cOut->cd(6); GetRefFigure(kFigNTrackletsP);
245 cOut->cd(7); GetRefFigure(kFigChargeCluster);
246 cOut->cd(8); GetRefFigure(kFigChargeTracklet);
247 cOut->SaveAs("TRD_TrackQuality.gif");
251 cOut = new TCanvas(Form("summary%s2", GetName()), Form("Summary 2 for task %s", GetName()), 1024, 512);
252 cOut->cd(); GetRefFigure(kFigPH);
253 cOut->SaveAs("TRD_PH.gif");
256 // Third Plot: Mean Number of clusters as function of eta, phi and layer
257 cOut = new TCanvas(Form("summary%s3", GetName()), Form("Summary 3 for task %s", GetName()), 1024, 768);
258 cOut->cd(); MakePlotMeanClustersLayer();
259 cOut->SaveAs("TRD_MeanNclusters.gif");
264 //_______________________________________________________
265 Bool_t AliTRDcheckDET::GetRefFigure(Int_t ifig){
267 // Setting Reference Figures
271 TH1 *h = NULL; TObjArray *arr=NULL;
275 case kFigNclustersTrack:
276 (h=(TH1F*)fContainer->FindObject("hNcls"))->Draw("pl");
277 PutTrendValue("NClustersTrack", h->GetMean());
278 PutTrendValue("NClustersTrackRMS", h->GetRMS());
280 case kFigNclustersTracklet:
281 (h =(TH1F*)fContainer->FindObject("hNclTls"))->Draw("pc");
282 PutTrendValue("NClustersTracklet", h->GetMean());
283 PutTrendValue("NClustersTrackletRMS", h->GetRMS());
285 case kFigNtrackletsTrack:
286 h=MakePlotNTracklets();
288 PutTrendValue("NTrackletsTrack", h->GetMean());
289 PutTrendValue("NTrackletsTrackRMS", h->GetRMS());
292 case kFigNTrackletsP:
293 MakePlotnTrackletsVsP();
295 case kFigNtrackletsCross:
296 h = (TH1F*)fContainer->FindObject("hNtlsCross");
297 if(!MakeBarPlot(h, kRed)) break;
298 PutTrendValue("NTrackletsCross", h->GetMean());
299 PutTrendValue("NTrackletsCrossRMS", h->GetRMS());
301 case kFigNtrackletsFindable:
302 h = (TH1F*)fContainer->FindObject("hNtlsFindable");
303 if(!MakeBarPlot(h, kGreen)) break;
304 PutTrendValue("NTrackletsFindable", h->GetMean());
305 PutTrendValue("NTrackletsFindableRMS", h->GetRMS());
307 case kFigNtracksEvent:
308 (h = (TH1F*)fContainer->FindObject("hNtrks"))->Draw("pl");
309 PutTrendValue("NTracksEvent", h->GetMean());
310 PutTrendValue("NTracksEventRMS", h->GetRMS());
312 case kFigNtracksSector:
313 h = (TH1F*)fContainer->FindObject("hNtrksSector");
314 if(!MakeBarPlot(h, kGreen)) break;
315 PutTrendValue("NTracksSector", h->Integral()/h->GetNbinsX());
317 case kFigTrackStatus:
318 if(!(h=(TH1F *)fContainer->FindObject("hTrackStatus"))) break;
319 h->GetXaxis()->SetRangeUser(0.5, -1);
320 h->GetYaxis()->CenterTitle();
322 PutTrendValue("TrackStatus", h->Integral());
325 case kFigTrackletStatus:
326 if(!(arr = dynamic_cast<TObjArray*>(fContainer->At(kTrackletStatus)))) break;
327 leg = new TLegend(.68, .7, .97, .97);
328 leg->SetBorderSize(0);leg->SetFillStyle(0);
329 leg->SetHeader("TRD layer");
330 for(Int_t ily=AliTRDgeometry::kNlayer; ily--;){
331 if(!(h=dynamic_cast<TH1F*>(arr->At(ily)))) continue;
334 h->GetXaxis()->SetRangeUser(0.5, -1);
335 h->GetYaxis()->CenterTitle();
337 } else h->Draw("samepl");
338 leg->AddEntry(h, Form("ly = %d", ily), "l");
339 PutTrendValue(Form("TrackletStatus%d", ily), h->Integral());
348 gPad->SetMargin(0.125, 0.015, 0.1, 0.1);
349 MakePlotPulseHeight();
352 case kFigChargeCluster:
353 (h = (TH1F*)fContainer->FindObject("hQcl"))->Draw("c");
355 PutTrendValue("ChargeCluster", h->GetMaximumBin());
356 PutTrendValue("ChargeClusterRMS", h->GetRMS());
358 case kFigChargeTracklet:
359 (h=(TH1F*)fContainer->FindObject("hQtrklt"))->Draw("c");
360 PutTrendValue("ChargeTracklet", h->GetMaximumBin());
361 PutTrendValue("ChargeTrackletRMS", h->GetRMS());
363 case kFigNeventsTrigger:
364 ((TH1F*)fContainer->FindObject("hEventsTrigger"))->Draw("");
366 case kFigNeventsTriggerTracks:
367 ((TH1F*)fContainer->FindObject("hEventsTriggerTracks"))->Draw("");
369 case kFigTriggerPurity:
370 if(!MakeBarPlot((TH1F*)fContainer->FindObject("hTriggerPurity"), kGreen)) break;
375 AliInfo(Form("Reference plot [%d] missing result", ifig));
379 //_______________________________________________________
380 TObjArray *AliTRDcheckDET::Histos(){
382 // Create QA histograms
385 if(fContainer) return fContainer;
387 fContainer = new TObjArray(20);
388 //fContainer->SetOwner(kTRUE);
390 // Register Histograms
393 if(!(h = (TH2F *)gROOT->FindObject("hNcls"))){
394 h = new TH2F("hNcls", "N_{clusters} / track", 181, -0.5, 180.5, AliTRDeventInfo::kCentralityClasses + 1, -1.5, AliTRDeventInfo::kCentralityClasses - 0.5);
395 /*h = new TH2F("hNcls", "N_{clusters} / track", 181, -0.5, 180.5);
396 h->GetXaxis()->SetTitle("N_{clusters}");
397 h->GetYaxis()->SetTitle("Centrality");
398 h->GetZaxis()->SetTitle("Entries");*/
400 fContainer->AddAt(h, kNclustersTrack);
402 TObjArray *arr = new TObjArray(AliTRDgeometry::kNlayer);
403 arr->SetOwner(kTRUE); arr->SetName("clusters");
404 fContainer->AddAt(arr, kNclustersLayer);
405 for(Int_t ily=AliTRDgeometry::kNlayer; ily--;){
406 if(!(h = (TProfile2D *)gROOT->FindObject(Form("hNcl%d", ily)))){
407 h = new TProfile2D(Form("hNcl%d", ily), Form("Mean Number of clusters in Layer %d", ily), 100, -1.0, 1.0, 50, -1.1*TMath::Pi(), 1.1*TMath::Pi());
408 h->GetXaxis()->SetTitle("#eta");
409 h->GetYaxis()->SetTitle("#phi");
414 if(!(h = (TH1F *)gROOT->FindObject("hNclTls"))){
415 h = new TH1F("hNclTls","N_{clusters} / tracklet", 51, -0.5, 50.5);
416 h->GetXaxis()->SetTitle("N_{clusters}");
417 h->GetYaxis()->SetTitle("Entries");
419 fContainer->AddAt(h, kNclustersTracklet);
421 if(!(h = (TH1F *)gROOT->FindObject("hNtls"))){
422 h = new TH1F("hNtls", "N_{tracklets} / track", AliTRDgeometry::kNlayer, 0.5, 6.5);
423 h->GetXaxis()->SetTitle("N^{tracklet}");
424 h->GetYaxis()->SetTitle("freq. [%]");
426 fContainer->AddAt(h, kNtrackletsTrack);
428 if(!(h = (TH1F *)gROOT->FindObject("htlsSTA"))){
429 h = new TH1F("hNtlsSTA", "N_{tracklets} / track (Stand Alone)", AliTRDgeometry::kNlayer, 0.5, 6.5);
430 h->GetXaxis()->SetTitle("N^{tracklet}");
431 h->GetYaxis()->SetTitle("freq. [%]");
433 fContainer->AddAt(h, kNtrackletsSTA);
435 // Binning for momentum dependent tracklet Plots
438 Float_t binsP[kNp+1], binsTrklt[AliTRDgeometry::kNlayer+1];
439 for(Int_t i=0;i<kNp+1; i++,p+=(TMath::Exp(i*i*.001)-1.)) binsP[i]=p;
440 for(Int_t il = 0; il <= AliTRDgeometry::kNlayer; il++) binsTrklt[il] = 0.5 + il;
441 if(!(h = (TH1F *)gROOT->FindObject("htlsBAR"))){
442 // Make tracklets for barrel tracks momentum dependent (if we do not exceed min and max values)
443 h = new TH2F("hNtlsBAR",
444 "N_{tracklets} / track;p [GeV/c];N^{tracklet};freq. [%]",
445 kNp, binsP, AliTRDgeometry::kNlayer, binsTrklt);
447 fContainer->AddAt(h, kNtrackletsBAR);
450 if(!(h = (TH1F *)gROOT->FindObject("hNtlsCross"))){
451 h = new TH1F("hNtlsCross", "N_{tracklets}^{cross} / track", 7, -0.5, 6.5);
452 h->GetXaxis()->SetTitle("n_{row cross}");
453 h->GetYaxis()->SetTitle("freq. [%]");
455 fContainer->AddAt(h, kNtrackletsCross);
457 if(!(h = (TH1F *)gROOT->FindObject("hNtlsFindable"))){
458 h = new TH1F("hNtlsFindable", "Found/Findable Tracklets" , 101, -0.005, 1.005);
459 h->GetXaxis()->SetTitle("r [a.u]");
460 h->GetYaxis()->SetTitle("Entries");
462 fContainer->AddAt(h, kNtrackletsFindable);
464 if(!(h = (TH1F *)gROOT->FindObject("hNtrks"))){
465 h = new TH1F("hNtrks", "N_{tracks} / event", 100, 0, 100);
466 h->GetXaxis()->SetTitle("N_{tracks}");
467 h->GetYaxis()->SetTitle("Entries");
469 fContainer->AddAt(h, kNtracksEvent);
471 if(!(h = (TH1F *)gROOT->FindObject("hNtrksSector"))){
472 h = new TH1F("hNtrksSector", "N_{tracks} / sector", AliTRDgeometry::kNsector, -0.5, 17.5);
473 h->GetXaxis()->SetTitle("sector");
474 h->GetYaxis()->SetTitle("freq. [%]");
476 fContainer->AddAt(h, kNtracksSector);
478 if(!(h = (TH1F*)gROOT->FindObject("hTrackStatus"))){
479 const Int_t nerr = 7;
480 h = new TH1F("hTrackStatus", "Track Status", nerr, -0.5, nerr-0.5);
481 const Char_t *label[nerr] = {"OK", "PROL", "PROP", "AJST", "SNP", "TINI", "UPDT"};
483 for(Int_t ierr=nerr; ierr--;) ax->SetBinLabel(ierr+1, label[ierr]);
484 h->SetYTitle("Relative Error to Good [%]");
486 fContainer->AddAt(h, kTrackStatus);
488 arr = new TObjArray(AliTRDgeometry::kNlayer);
489 arr->SetOwner(kTRUE); arr->SetName("TrackletStatus");
490 fContainer->AddAt(arr, kTrackletStatus);
491 for(Int_t ily=AliTRDgeometry::kNlayer; ily--;){
492 if(!(h = (TH1F *)gROOT->FindObject(Form("hTrackletStatus%d", ily)))){
493 const Int_t nerr = 8;
494 h = new TH1F(Form("hTrackletStatus%d", ily), "Tracklet status", nerr, -0.5, nerr-0.5);
495 h->SetLineColor(ily+1);
496 const Char_t *label[nerr] = {"OK", "Geom", "Bound", "NoCl", "NoAttach", "NoClTr", "NoFit", "Chi2"};
498 for(Int_t ierr=nerr; ierr--;) ax->SetBinLabel(ierr+1, label[ierr]);
499 h->SetYTitle("Relative Error to Good [%]");
505 arr = new TObjArray(3);
506 arr->SetOwner(kTRUE); arr->SetName("<PH>");
507 fContainer->AddAt(arr, kPH);
508 if(!(h = (TH1F *)gROOT->FindObject("hPHt"))){
509 h = new TProfile("hPHt", "<PH>", 31, -0.5, 30.5);
510 h->GetXaxis()->SetTitle("Time / 100ns");
511 h->GetYaxis()->SetTitle("<PH> [a.u]");
514 if(!(h = (TH1F *)gROOT->FindObject("hPHx")))
515 h = new TProfile("hPHx", "<PH>", 31, -0.08, 4.88);
518 if(!(h = (TH2F *)gROOT->FindObject("hPH2D"))){
519 h = new TH2F("hPH2D", "Charge Distribution / time", 31, -0.5, 30.5, 100, 0, 1024);
520 h->GetXaxis()->SetTitle("Time / 100ns");
521 h->GetYaxis()->SetTitle("Charge / a.u.");
526 if(!(h = (TH2S*)gROOT->FindObject("hChi2"))){
527 h = new TH2S("hChi2", "#chi^{2} per track", AliTRDgeometry::kNlayer, .5, AliTRDgeometry::kNlayer+.5, 100, 0, 50);
529 h->SetYTitle("#chi^{2}/ndf");
530 h->SetZTitle("entries");
532 fContainer->AddAt(h, kChi2);
534 if(!(h = (TH1F *)gROOT->FindObject("hQcl"))){
535 h = new TH1F("hQcl", "Q_{cluster}", 200, 0, 1200);
536 h->GetXaxis()->SetTitle("Q_{cluster} [a.u.]");
537 h->GetYaxis()->SetTitle("Entries");
539 fContainer->AddAt(h, kChargeCluster);
541 if(!(h = (TH1F *)gROOT->FindObject("hQtrklt"))){
542 h = new TH1F("hQtrklt", "Q_{tracklet}", 6000, 0, 6000);
543 h->GetXaxis()->SetTitle("Q_{tracklet} [a.u.]");
544 h->GetYaxis()->SetTitle("Entries");
546 fContainer->AddAt(h, kChargeTracklet);
549 if(!(h = (TH1F *)gROOT->FindObject("hEventsTrigger")))
550 h = new TH1F("hEventsTrigger", "Trigger Class", 100, 0, 100);
553 fContainer->AddAt(h, kNeventsTrigger);
555 if(!(h = (TH1F *)gROOT->FindObject("hEventsTriggerTracks")))
556 h = new TH1F("hEventsTriggerTracks", "Trigger Class (Tracks)", 100, 0, 100);
558 fContainer->AddAt(h, kNeventsTriggerTracks);
560 if(!(h = (TH1F *)gROOT->FindObject("hTriggerPurity"))){
561 h = new TH1F("hTriggerPurity", "Trigger Purity", 10, -0.5, 9.5);
562 h->GetXaxis()->SetTitle("Trigger Cluster");
563 h->GetYaxis()->SetTitle("freq.");
565 fContainer->AddAt(h, kTriggerPurity);
574 //_______________________________________________________
575 TH1 *AliTRDcheckDET::PlotTrackStatus(const AliTRDtrackV1 *track)
578 // Plot the track propagation status. The following errors are defined (see AliTRDtrackV1::ETRDtrackError)
579 // PROL - track prolongation failure
580 // PROP - track propagation failure
581 // AJST - crossing sectors failure
582 // SNP - too large bending
583 // TINI - tracklet initialization failure
584 // UPDT - track position/covariance update failure
586 // Performance plot looks as below:
588 //<img src="TRD/trackStatus.gif">
591 if(track) fkTrack = track;
593 AliDebug(4, "No Track defined.");
597 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kTrackStatus)))){
598 AliWarning("No Histogram defined.");
601 h->Fill(fkTrack->GetStatusTRD());
605 //_______________________________________________________
606 TH1 *AliTRDcheckDET::PlotTrackletStatus(const AliTRDtrackV1 *track)
609 // Plot the tracklet propagation status. The following errors are defined for tracklet (see AliTRDtrackV1::ETRDlayerError)
611 // Bound - tracklet too close to chamber walls
612 // NoCl - no clusters in the track roads
613 // NoAttach - fail to attach clusters
614 // NoClTr - fail to use clusters for fit
615 // NoFit - tracklet fit failled
616 // Chi2 - chi2 tracklet-track over threshold
618 // Performance plot looks as below:
620 //<img src="TRD/trackletStatus.gif">
623 if(track) fkTrack = track;
625 AliDebug(4, "No Track defined.");
628 TObjArray *arr =NULL;
629 if(!(arr = dynamic_cast<TObjArray*>(fContainer->At(kTrackletStatus)))){
630 AliWarning("Histograms not defined.");
635 for(Int_t ily=AliTRDgeometry::kNlayer; ily--;){
636 if(!(h = dynamic_cast<TH1F*>(arr->At(ily)))){
637 AliWarning(Form("Missing histo for layer %d.", ily));
640 h->Fill(fkTrack->GetStatusTRD(ily));
645 //_______________________________________________________
646 TH1 *AliTRDcheckDET::PlotNClustersTracklet(const AliTRDtrackV1 *track){
648 // Plot the mean number of clusters per tracklet
650 if(track) fkTrack = track;
652 AliDebug(4, "No Track defined.");
655 AliExternalTrackParam *par = fkTrack->GetTrackIn() ? fkTrack->GetTrackIn() : fkTrack->GetTrackOut();
657 TProfile2D *hlayer = NULL;
658 Double_t eta = 0., phi = 0.;
659 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclustersTracklet)))){
660 AliWarning("No Histogram defined.");
663 AliTRDseedV1 *tracklet = NULL;
664 TObjArray *histosLayer = dynamic_cast<TObjArray *>(fContainer->At(kNclustersLayer));
666 AliWarning("No Histograms for single layer defined");
668 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
669 if(!(tracklet = fkTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
670 h->Fill(tracklet->GetN2());
671 if(histosLayer && par){
672 if((hlayer = dynamic_cast<TProfile2D *>(histosLayer->At(itl)))){
673 GetEtaPhiAt(par, tracklet->GetX0(), eta, phi);
674 hlayer->Fill(eta, phi, tracklet->GetN2());
681 //_______________________________________________________
682 TH1 *AliTRDcheckDET::PlotNClustersTrack(const AliTRDtrackV1 *track){
684 // Plot the number of clusters in one track
686 if(track) fkTrack = track;
688 AliDebug(4, "No Track defined.");
692 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclustersTrack)))){
693 AliWarning("No Histogram defined.");
698 AliTRDseedV1 *tracklet = NULL;
699 AliExternalTrackParam *par = fkTrack->GetTrackOut() ? fkTrack->GetTrackOut() : fkTrack->GetTrackIn();
700 if(!par) return NULL;
701 Double_t momentumRec = par->P();
702 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
703 if(!(tracklet = fkTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
704 Int_t n(tracklet->GetN());
706 if(DebugLevel() > 2){
707 Int_t crossing = Int_t(tracklet->IsRowCross());
708 Int_t detector = tracklet->GetDetector();
709 Float_t theta = TMath::ATan(tracklet->GetZref(1));
710 Float_t phi = TMath::ATan(tracklet->GetYref(1));
711 Float_t momentumMC = 0.;
713 Int_t kinkIndex = fkESD ? fkESD->GetKinkIndex() : 0;
714 UShort_t nclsTPC = fkESD ? fkESD->GetTPCncls() : 0;
716 if(fkMC->GetTrackRef()) momentumMC = fkMC->GetTrackRef()->P();
717 pdg = fkMC->GetPDG();
719 (*DebugStream()) << "NClustersTrack"
720 << "Detector=" << detector
721 << "crossing=" << crossing
722 << "momentumMC="<< momentumMC
723 << "momentumRec=" << momentumRec
727 << "kinkIndex=" << kinkIndex
728 << "TPCncls=" << nclsTPC
738 //_______________________________________________________
739 TH1 *AliTRDcheckDET::PlotNTrackletsTrack(const AliTRDtrackV1 *track){
741 // Plot the number of tracklets
743 if(track) fkTrack = track;
745 AliDebug(4, "No Track defined.");
748 TH1 *h = NULL, *hSta = NULL; TH2 *hBarrel = NULL;
749 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsTrack)))){
750 AliWarning("No Histogram defined.");
753 Int_t nTracklets = fkTrack->GetNumberOfTracklets();
756 Int_t status = fkESD->GetStatus();
758 /* printf("in/out/refit/pid: TRD[%d|%d|%d|%d]\n", status &AliESDtrack::kTRDin ? 1 : 0, status &AliESDtrack::kTRDout ? 1 : 0, status &AliESDtrack::kTRDrefit ? 1 : 0, status &AliESDtrack::kTRDpid ? 1 : 0);*/
760 Int_t method = -1; // to distinguish between stand alone and full barrel tracks in the debugging
761 if((status & AliESDtrack::kTRDin) != 0){
763 // Full Barrel Track: Save momentum dependence
764 if(!(hBarrel = dynamic_cast<TH2F *>(fContainer->At(kNtrackletsBAR)))){
765 AliWarning("Method: Barrel. Histogram not processed!");
768 AliExternalTrackParam *par(fkTrack->GetTrackIn());
770 AliError("Input track params missing");
773 p = par->P(); // p needed later in the debug streaming
774 hBarrel->Fill(p, nTracklets);
776 // Stand alone Track: momentum dependence not usefull
778 if(!(hSta = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsSTA)))) {
779 AliWarning("Method: StandAlone. Histogram not processed!");
782 hSta->Fill(nTracklets);
785 if(DebugLevel() > 2){
786 AliTRDseedV1 *tracklet = NULL;
787 AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
788 Int_t sector = -1, stack = -1, detector;
789 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
790 if(!(tracklet = fkTrack->GetTracklet(itl)) || !(tracklet->IsOK())) continue;
791 detector = tracklet->GetDetector();
792 sector = geo->GetSector(detector);
793 stack = geo->GetStack(detector);
796 (*DebugStream()) << "NTrackletsTrack"
797 << "Sector=" << sector
799 << "NTracklets=" << nTracklets
800 << "Method=" << method
804 if(DebugLevel() > 3){
805 AliTRDseedV1 *tracklet = NULL;
806 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
807 if((tracklet = fkTrack->GetTracklet(il)) && tracklet->IsOK()){
808 (*DebugStream()) << "NTrackletsLayer"
819 //_______________________________________________________
820 TH1 *AliTRDcheckDET::PlotNTrackletsRowCross(const AliTRDtrackV1 *track){
822 // Plot the number of tracklets
824 if(track) fkTrack = track;
826 AliDebug(4, "No Track defined.");
830 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsCross)))){
831 AliWarning("No Histogram defined.");
836 AliTRDseedV1 *tracklet = NULL;
837 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
838 if(!(tracklet = fkTrack->GetTracklet(il)) || !tracklet->IsOK()) continue;
840 if(tracklet->IsRowCross()) ncross++;
846 //_______________________________________________________
847 TH1 *AliTRDcheckDET::PlotFindableTracklets(const AliTRDtrackV1 *track){
849 // Plots the ratio of number of tracklets vs.
850 // number of findable tracklets
852 // Findable tracklets are defined as track prolongation
853 // to layer i does not hit the dead area +- epsilon
855 // In order to check whether tracklet hist active area in Layer i,
856 // the track is refitted and the fitted position + an uncertainty
857 // range is compared to the chamber border (also with a different
860 // For the track fit two cases are distinguished:
861 // If the track is a stand alone track (defined by the status bit
862 // encoding, then the track is fitted with the tilted Rieman model
863 // Otherwise the track is fitted with the Kalman fitter in two steps:
864 // Since the track parameters are give at the outer point, we first
865 // fit in direction inwards. Afterwards we fit again in direction outwards
866 // to extrapolate the track to layers which are not reached by the track
867 // For the Kalman model, the radial track points have to be shifted by
868 // a distance epsilon in the direction that we want to fit
870 const Float_t epsilon = 0.01; // dead area tolerance
871 const Float_t epsilonR = 1; // shift in radial direction of the anode wire position (Kalman filter only)
872 const Float_t deltaY = 0.7; // Tolerance in the track position in y-direction
873 const Float_t deltaZ = 7.0; // Tolerance in the track position in z-direction (Padlength)
874 Double_t xAnode[AliTRDgeometry::kNlayer] = {300.2, 312.8, 325.4, 338.0, 350.6, 363.2}; // Take the default X0
876 if(track) fkTrack = track;
878 AliDebug(4, "No Track defined.");
882 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsFindable)))){
883 AliWarning("No Histogram defined.");
886 Int_t nFound = 0, nFindable = 0;
888 Double_t ymin = 0., ymax = 0., zmin = 0., zmax = 0.;
889 Double_t y = 0., z = 0.;
890 AliTRDseedV1 *tracklet = NULL;
892 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
893 if((tracklet = fkTrack->GetTracklet(il)) && tracklet->IsOK()){
894 tracklet->SetReconstructor(AliTRDinfoGen::Reconstructor());
898 // 2 Different cases:
899 // 1st stand alone: here we cannot propagate, but be can do a Tilted Rieman Fit
900 // 2nd barrel track: here we propagate the track to the layers
901 AliTrackPoint points[6];
903 memset(xyz, 0, sizeof(Float_t) * 3);
904 if(((fkESD->GetStatus() & AliESDtrack::kTRDout) > 0) && !((fkESD->GetStatus() & AliESDtrack::kTRDin) > 0)){
906 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
908 points[il].SetXYZ(xyz);
910 AliTRDtrackerV1::FitRiemanTilt(const_cast<AliTRDtrackV1 *>(fkTrack), NULL, kTRUE, 6, points);
916 // -> Kalman outwards
917 AliTRDtrackV1 copyTrack(*fkTrack); // Do Kalman on a (non-constant) copy of the track
918 AliTrackPoint pointsInward[6], pointsOutward[6];
919 for(Int_t il = AliTRDgeometry::kNlayer; il--;){
920 // In order to avoid complications in the Kalman filter if the track points have the same radial
921 // position like the tracklets, we have to shift the radial postion of the anode wire by epsilon
922 // in the direction we want to go
923 // The track points have to be in reverse order for the Kalman Filter inwards
924 xyz[0] = xAnode[AliTRDgeometry::kNlayer - il - 1] - epsilonR;
925 pointsInward[il].SetXYZ(xyz);
926 xyz[0] = xAnode[il] + epsilonR;
927 pointsOutward[il].SetXYZ(xyz);
929 /*for(Int_t ipt = 0; ipt < AliTRDgeometry::kNlayer; ipt++)
930 printf("%d. X = %f\n", ipt, points[ipt].GetX());*/
932 AliTRDtrackerV1::FitKalman(©Track, NULL, kFALSE, 6, pointsInward);
933 memcpy(points, pointsInward, sizeof(AliTrackPoint) * 6); // Preliminary store the inward results in the Array points
935 AliTRDtrackerV1::FitKalman(©Track, NULL, kTRUE, 6, pointsInward);
936 memcpy(points, pointsOutward, sizeof(AliTrackPoint) * AliTRDgeometry::kNlayer);
938 AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
939 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
940 y = points[il].GetY();
941 z = points[il].GetZ();
942 if((stack = geo->GetStack(z, il)) < 0) continue; // Not findable
943 pp = geo->GetPadPlane(il, stack);
944 ymin = pp->GetCol0() + epsilon;
945 ymax = pp->GetColEnd() - epsilon;
946 zmin = pp->GetRowEnd() + epsilon;
947 zmax = pp->GetRow0() - epsilon;
948 // ignore y-crossing (material)
949 if((z + deltaZ > zmin && z - deltaZ < zmax) && (y + deltaY > ymin && y - deltaY < ymax)) nFindable++;
950 if(DebugLevel() > 3){
951 Double_t posTracklet[2] = {tracklet ? tracklet->GetYfit(0) : 0, tracklet ? tracklet->GetZfit(0) : 0};
952 Int_t hasTracklet = tracklet ? 1 : 0;
953 (*DebugStream()) << "FindableTracklets"
955 << "ytracklet=" << posTracklet[0]
957 << "ztracklet=" << posTracklet[1]
959 << "tracklet=" << hasTracklet
964 h->Fill(nFindable > 0 ? TMath::Min(nFound/static_cast<Double_t>(nFindable), 1.) : 1);
965 AliDebug(2, Form("Findable[Found]: %d[%d|%f]", nFindable, nFound, nFound/static_cast<Float_t>(nFindable > 0 ? nFindable : 1)));
970 //_______________________________________________________
971 TH1 *AliTRDcheckDET::PlotChi2(const AliTRDtrackV1 *track){
973 // Plot the chi2 of the track
975 if(track) fkTrack = track;
977 AliDebug(4, "No Track defined.");
981 if(!(h = dynamic_cast<TH2S*>(fContainer->At(kChi2)))) {
982 AliWarning("No Histogram defined.");
985 Int_t n = fkTrack->GetNumberOfTracklets();
988 h->Fill(n, fkTrack->GetChi2()/n);
993 //_______________________________________________________
994 TH1 *AliTRDcheckDET::PlotPHt(const AliTRDtrackV1 *track){
996 // Plot the average pulse height
998 if(track) fkTrack = track;
1000 AliDebug(4, "No Track defined.");
1003 TProfile *h = NULL; TH2F *phs2D = NULL;
1004 if(!(h = dynamic_cast<TProfile *>(((TObjArray*)(fContainer->At(kPH)))->At(0)))){
1005 AliWarning("No Histogram defined.");
1008 if(!(phs2D = dynamic_cast<TH2F *>(((TObjArray*)(fContainer->At(kPH)))->At(2)))){
1009 AliWarning("2D Pulse Height histogram not defined. Histogramm cannot be filled");
1011 AliTRDseedV1 *tracklet = NULL;
1012 AliTRDcluster *c = NULL;
1013 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
1014 if(!(tracklet = fkTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
1015 Int_t crossing = Int_t(tracklet->IsRowCross());
1016 Int_t detector = tracklet->GetDetector();
1017 tracklet->ResetClusterIter();
1018 while((c = tracklet->NextCluster())){
1019 if(!IsUsingClustersOutsideChamber() && !c->IsInChamber()) continue;
1020 Int_t localtime = c->GetLocalTimeBin();
1021 Double_t absoluteCharge = TMath::Abs(c->GetQ());
1022 h->Fill(localtime, absoluteCharge);
1023 phs2D->Fill(localtime, absoluteCharge);
1024 if(DebugLevel() > 3){
1025 Int_t inChamber = c->IsInChamber() ? 1 : 0;
1026 Double_t distance[2];
1027 GetDistanceToTracklet(distance, tracklet, c);
1028 Float_t theta = TMath::ATan(tracklet->GetZref(1));
1029 Float_t phi = TMath::ATan(tracklet->GetYref(1));
1030 AliExternalTrackParam *trdPar = fkTrack->GetTrackIn();
1031 Float_t momentumMC = 0, momentumRec = trdPar ? trdPar->P() : fkTrack->P(); // prefer Track Low
1033 Int_t kinkIndex = fkESD ? fkESD->GetKinkIndex() : 0;
1034 UShort_t tpcNCLS = fkESD ? fkESD->GetTPCncls() : 0;
1036 if(fkMC->GetTrackRef()) momentumMC = fkMC->GetTrackRef()->P();
1037 pdg = fkMC->GetPDG();
1039 (*DebugStream()) << "PHt"
1040 << "Detector=" << detector
1041 << "crossing=" << crossing
1042 << "inChamber=" << inChamber
1043 << "Timebin=" << localtime
1044 << "Charge=" << absoluteCharge
1045 << "momentumMC=" << momentumMC
1046 << "momentumRec=" << momentumRec
1048 << "theta=" << theta
1050 << "kinkIndex=" << kinkIndex
1051 << "TPCncls=" << tpcNCLS
1052 << "dy=" << distance[0]
1053 << "dz=" << distance[1]
1062 //_______________________________________________________
1063 TH1 *AliTRDcheckDET::PlotPHx(const AliTRDtrackV1 *track){
1065 // Plots the average pulse height vs the distance from the anode wire
1066 // (plus const anode wire offset)
1068 if(track) fkTrack = track;
1070 AliDebug(4, "No Track defined.");
1074 if(!(h = dynamic_cast<TProfile *>(((TObjArray*)(fContainer->At(kPH)))->At(1)))){
1075 AliWarning("No Histogram defined.");
1078 AliTRDseedV1 *tracklet(NULL);
1079 AliTRDcluster *c(NULL);
1080 Double_t xd(0.), dqdl(0.);
1081 TVectorD vq(AliTRDseedV1::kNtb), vxd(AliTRDseedV1::kNtb), vdqdl(AliTRDseedV1::kNtb);
1082 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
1083 if(!(tracklet = fkTrack->GetTracklet(itl)) || !(tracklet->IsOK())) continue;
1084 Int_t det(tracklet->GetDetector());
1085 Bool_t rc(tracklet->IsRowCross());
1086 for(Int_t ic(0); ic<AliTRDseedV1::kNtb; ic++){
1087 Bool_t kFIRST(kFALSE);
1088 if(!(c = tracklet->GetClusters(ic))){
1089 if(!(c = tracklet->GetClusters(AliTRDseedV1::kNtb+ic))) continue;
1090 } else kFIRST=kTRUE;
1091 if(!IsUsingClustersOutsideChamber() && !c->IsInChamber()) continue;
1092 xd = tracklet->GetX0() - c->GetX(); vxd[ic] = xd;
1093 dqdl=tracklet->GetdQdl(ic); vdqdl[ic] = dqdl;
1095 if(kFIRST && (c = tracklet->GetClusters(AliTRDseedV1::kNtb+ic))) vq[ic]+=c->GetQ();
1098 if(DebugLevel() > 3){
1099 (*DebugStream()) << "PHx"
1104 << "dqdl=" << &vdqdl
1111 //_______________________________________________________
1112 TH1 *AliTRDcheckDET::PlotChargeCluster(const AliTRDtrackV1 *track){
1114 // Plot the cluster charge
1116 if(track) fkTrack = track;
1118 AliDebug(4, "No Track defined.");
1122 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChargeCluster)))){
1123 AliWarning("No Histogram defined.");
1126 AliTRDseedV1 *tracklet = NULL;
1127 AliTRDcluster *c = NULL;
1128 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
1129 if(!(tracklet = fkTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
1130 for(Int_t ic(0); ic < AliTRDseedV1::kNtb; ic++){
1131 Bool_t kFIRST(kFALSE);
1132 if(!(c = tracklet->GetClusters(ic))) {
1133 if(!(c = tracklet->GetClusters(AliTRDseedV1::kNtb+ic))) continue;
1134 } else kFIRST = kTRUE;
1135 Float_t q(c->GetQ());
1136 if(kFIRST && (c = tracklet->GetClusters(AliTRDseedV1::kNtb+ic))) q+=c->GetQ();
1143 //_______________________________________________________
1144 TH1 *AliTRDcheckDET::PlotChargeTracklet(const AliTRDtrackV1 *track){
1146 // Plot the charge deposit per chamber
1148 if(track) fkTrack = track;
1150 AliDebug(4, "No Track defined.");
1154 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChargeTracklet)))){
1155 AliWarning("No Histogram defined.");
1158 AliTRDseedV1 *tracklet = NULL;
1159 AliTRDcluster *c = NULL;
1161 Int_t nTracklets =fkTrack->GetNumberOfTracklets();
1162 for(Int_t itl(0); itl < AliTRDgeometry::kNlayer; itl++){
1163 if(!(tracklet = fkTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
1165 for(Int_t ic = AliTRDseedV1::kNclusters; ic--;){
1166 if(!(c = tracklet->GetClusters(ic))) continue;
1167 qTot += TMath::Abs(c->GetQ());
1170 if(DebugLevel() > 3){
1171 Int_t crossing = (Int_t)tracklet->IsRowCross();
1172 Int_t detector = tracklet->GetDetector();
1173 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
1174 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
1175 Float_t momentum = 0.;
1177 Int_t kinkIndex = fkESD ? fkESD->GetKinkIndex() : 0;
1178 UShort_t nclsTPC = fkESD ? fkESD->GetTPCncls() : 0;
1180 if(fkMC->GetTrackRef()) momentum = fkMC->GetTrackRef()->P();
1181 pdg = fkMC->GetPDG();
1183 (*DebugStream()) << "ChargeTracklet"
1184 << "Detector=" << detector
1185 << "crossing=" << crossing
1186 << "momentum=" << momentum
1187 << "nTracklets="<< nTracklets
1189 << "theta=" << theta
1191 << "kinkIndex=" << kinkIndex
1192 << "TPCncls=" << nclsTPC
1200 //_______________________________________________________
1201 TH1 *AliTRDcheckDET::PlotNTracksSector(const AliTRDtrackV1 *track){
1203 // Plot the number of tracks per Sector
1205 if(track) fkTrack = track;
1207 AliDebug(4, "No Track defined.");
1211 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtracksSector)))){
1212 AliWarning("No Histogram defined.");
1216 // TODO we should compare with
1217 // sector = Int_t(track->GetAlpha() / AliTRDgeometry::GetAlpha());
1219 AliTRDseedV1 *tracklet = NULL;
1221 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
1222 if(!(tracklet = fkTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
1223 sector = static_cast<Int_t>(tracklet->GetDetector()/AliTRDgeometry::kNdets);
1231 //________________________________________________________
1232 void AliTRDcheckDET::GetDistanceToTracklet(Double_t *dist, AliTRDseedV1 * const tracklet, AliTRDcluster * const c)
1234 Float_t x = c->GetX();
1235 dist[0] = c->GetY() - tracklet->GetYat(x);
1236 dist[1] = c->GetZ() - tracklet->GetZat(x);
1239 //________________________________________________________
1240 void AliTRDcheckDET::GetEtaPhiAt(const AliExternalTrackParam *track, Double_t x, Double_t &eta, Double_t &phi){
1242 // Get phi and eta at a given radial position
1244 AliExternalTrackParam workpar(*track);
1246 Double_t posLocal[3];
1247 Bool_t sucPos = workpar.GetXYZAt(x, fEventInfo->GetRunInfo()->GetMagneticField(), posLocal);
1248 Double_t sagPhi = sucPos ? TMath::ATan2(posLocal[1], posLocal[0]) : 0.;
1250 eta = workpar.Eta();
1254 //_______________________________________________________
1255 TH1* AliTRDcheckDET::MakePlotChi2() const
1257 // Plot chi2/track normalized to number of degree of freedom
1258 // (tracklets) and compare with the theoretical distribution.
1260 // Alex Bercuci <A.Bercuci@gsi.de>
1264 /* TH2S *h2 = (TH2S*)fContainer->At(kChi2);
1265 TF1 f("fChi2", "[0]*pow(x, [1]-1)*exp(-0.5*x)", 0., 50.);
1266 f.SetParLimits(1,1, 1e100);
1267 TLegend *leg = new TLegend(.7,.7,.95,.95);
1268 leg->SetBorderSize(1); leg->SetHeader("Tracklets per Track");
1270 Bool_t kFIRST = kTRUE;
1271 for(Int_t il=1; il<=h2->GetNbinsX(); il++){
1272 h1 = h2->ProjectionY(Form("pyChi2%d", il), il, il);
1273 if(h1->Integral()<50) continue;
1274 h1->Scale(1./h1->Integral());
1275 h1->SetMarkerStyle(7);h1->SetMarkerColor(il);
1276 h1->SetLineColor(il);h1->SetLineStyle(2);
1277 f.SetParameter(1, .5*il);f.SetLineColor(il);
1278 h1->Fit(&f, "QW+", kFIRST ? "pc": "pcsame");
1279 leg->AddEntry(h1, Form("%d", il), "l");
1281 h1->GetXaxis()->SetRangeUser(0., 25.);
1291 //________________________________________________________
1292 TH1* AliTRDcheckDET::MakePlotNTracklets(){
1294 // Make nice bar plot of the number of tracklets in each method
1296 TH2F *tmp = (TH2F *)fContainer->FindObject("hNtlsBAR");
1297 TH1D *hBAR = tmp->ProjectionY();
1298 TH1F *hSTA = (TH1F *)fContainer->FindObject("hNtlsSTA");
1299 TH1F *hCON = (TH1F *)fContainer->FindObject("hNtls");
1300 TLegend *leg = new TLegend(0.13, 0.75, 0.39, 0.89);
1301 leg->SetBorderSize(1);
1302 leg->SetFillColor(0);
1304 Float_t scale = hCON->Integral();
1305 if(scale) hCON->Scale(100./scale);
1306 hCON->SetFillColor(kRed);hCON->SetLineColor(kRed);
1307 hCON->SetBarWidth(0.2);
1308 hCON->SetBarOffset(0.6);
1309 hCON->SetStats(kFALSE);
1310 hCON->GetYaxis()->SetRangeUser(0.,40.);
1311 hCON->GetYaxis()->SetTitleOffset(1.2);
1312 hCON->Draw("bar1"); leg->AddEntry(hCON, "Total", "f");
1313 hCON->SetMaximum(55.);
1315 if(scale) hBAR->Scale(100./scale);
1316 hBAR->SetFillColor(kGreen);hBAR->SetLineColor(kGreen);
1317 hBAR->SetBarWidth(0.2);
1318 hBAR->SetBarOffset(0.2);
1320 hBAR->SetStats(kFALSE);
1321 hBAR->GetYaxis()->SetRangeUser(0.,40.);
1322 hBAR->GetYaxis()->SetTitleOffset(1.2);
1323 hBAR->Draw("bar1same"); leg->AddEntry(hBAR, "Barrel", "f");
1325 if(scale) hSTA->Scale(100./scale);
1326 hSTA->SetFillColor(kBlue);hSTA->SetLineColor(kBlue);
1327 hSTA->SetBarWidth(0.2);
1328 hSTA->SetBarOffset(0.4);
1330 hSTA->SetStats(kFALSE);
1331 hSTA->GetYaxis()->SetRangeUser(0.,40.);
1332 hSTA->GetYaxis()->SetTitleOffset(1.2);
1333 hSTA->Draw("bar1same"); leg->AddEntry(hSTA, "Stand Alone", "f");
1339 //________________________________________________________
1340 void AliTRDcheckDET::MakePlotnTrackletsVsP(){
1342 // Plot abundance of tracks with number of tracklets as function of momentum
1348 Color_t color[AliTRDgeometry::kNlayer] = {kBlue, kOrange, kBlack, kGreen, kCyan, kRed};
1349 TH1 *h(NULL); TGraphErrors *g[AliTRDgeometry::kNlayer];
1350 for(Int_t itl(0); itl<AliTRDgeometry::kNlayer; itl++){
1351 g[itl] = new TGraphErrors();
1352 g[itl]->SetLineColor(color[itl]);
1353 g[itl]->SetMarkerColor(color[itl]);
1354 g[itl]->SetMarkerStyle(20 + itl);
1357 TH2 *hBar = (TH2F *)fContainer->FindObject("hNtlsBAR");
1358 TAxis *ax(hBar->GetXaxis());
1359 Int_t np(ax->GetNbins());
1360 for(Int_t ipBin(1); ipBin<np; ipBin++){
1361 h = hBar->ProjectionY("npBin", ipBin, ipBin);
1362 if(!Int_t(h->Integral())) continue;
1363 h->Scale(100./h->Integral());
1364 Float_t p(ax->GetBinCenter(ipBin));
1365 Float_t dp(ax->GetBinWidth(ipBin));
1366 Int_t ip(g[0]->GetN());
1367 for(Int_t itl(AliTRDgeometry::kNlayer); itl--;){
1368 g[itl]->SetPoint(ip, p, h->GetBinContent(itl+1));
1369 g[itl]->SetPointError(ip, dp/3.46, h->GetBinError(itl+1));
1373 TLegend *leg = new TLegend(0.76, 0.6, 1., 0.9);
1374 leg->SetBorderSize(0);
1375 leg->SetHeader("Tracklet/Track");
1376 leg->SetFillStyle(0);
1377 h = hBar->ProjectionX("npxBin"); h->Reset();
1379 h->GetYaxis()->SetRangeUser(1., 99.);
1380 h->GetYaxis()->SetMoreLogLabels();
1381 h->GetYaxis()->CenterTitle();
1382 h->GetYaxis()->SetTitleOffset(1.2);
1383 h->SetYTitle("Prob. [%]");
1384 h->GetXaxis()->SetRangeUser(0.4, 12.);
1385 h->GetXaxis()->SetMoreLogLabels();
1386 h->GetXaxis()->CenterTitle();
1388 for(Int_t itl(AliTRDgeometry::kNlayer); itl--;){
1390 leg->AddEntry(g[itl], Form("n = %d", itl+1),"pl");
1394 gPad->SetLogx();gPad->SetLogy();
1397 //________________________________________________________
1398 Bool_t AliTRDcheckDET::MakePlotPulseHeight(){
1400 // Create Plot of the Pluse Height Spectrum
1402 TCanvas *output = gPad->GetCanvas();
1406 TObjArray *arr = (TObjArray*)fContainer->FindObject("<PH>");
1407 h = (TH1F*)arr->At(0);
1408 if((Int_t)h->GetEntries()){
1409 h->SetMarkerStyle(24);
1410 h->SetMarkerColor(kBlack);
1411 h->SetLineColor(kBlack);
1412 h->GetYaxis()->SetTitleOffset(1.5);
1414 // Trending for the pulse height: plateau value, slope and timebin of the maximum
1415 TLinearFitter fit(1,"pol1");
1417 for(Int_t itime = 10; itime <= 20; itime++){
1418 time = Double_t(itime);
1419 Double_t err(h->GetBinError(itime + 1));
1420 if(err>1.e-10) fit.AddPoint(&time, h->GetBinContent(itime + 1), err);
1423 Double_t plateau = fit.GetParameter(0) + 12 * fit.GetParameter(1);
1424 Double_t slope = fit.GetParameter(1);
1425 PutTrendValue("PHplateau", plateau);
1426 PutTrendValue("PHslope", slope);
1427 PutTrendValue("PHamplificationPeak", static_cast<Double_t>(h->GetMaximumBin()-1));
1428 AliDebug(1, Form("plateau %f, slope %f, MaxTime %f", plateau, slope, static_cast<Double_t>(h->GetMaximumBin()-1)));
1431 // copy the second histogram in a new one with the same x-dimension as the phs with respect to time
1432 h1 = (TH1F *)arr->At(1);
1433 h2 = new TH1F("hphs1","Average PH", 31, -0.5, 30.5);
1434 for(Int_t ibin = h1->GetXaxis()->GetFirst(); ibin < h1->GetNbinsX(); ibin++)
1435 h2->SetBinContent(ibin, h1->GetBinContent(ibin));
1436 h2->SetMarkerStyle(22);
1437 h2->SetMarkerColor(kBlue);
1438 h2->SetLineColor(kBlue);
1442 // create axis according to the histogram dimensions of the original second histogram
1443 TGaxis *axis = new TGaxis(gPad->GetUxmin(),
1447 -0.08, 4.88, 510,"-L");
1448 axis->SetLineColor(kBlue);
1449 axis->SetLabelColor(kBlue);
1450 axis->SetTextColor(kBlue);
1451 axis->SetTitle("x_{0}-x_{c} [cm]");
1455 TH2 *ph2d = (TH2F *)arr->At(2);
1456 ph2d->GetYaxis()->SetTitleOffset(1.8);
1457 ph2d->SetStats(kFALSE);
1462 //________________________________________________________
1463 void AliTRDcheckDET::MakePlotMeanClustersLayer(){
1465 // Create Summary plot for the mean number of clusters per layer
1467 TCanvas *output = gPad->GetCanvas();
1468 output->Divide(3,2);
1469 TObjArray *histos = (TObjArray *)fContainer->At(kNclustersLayer);
1471 AliWarning("Histos for each layer not found");
1474 TProfile2D *hlayer = NULL;
1475 for(Int_t ily = 0; ily < AliTRDgeometry::kNlayer; ily++){
1476 if(!(hlayer = dynamic_cast<TProfile2D *>(histos->At(ily)))) continue;
1477 output->cd(ily + 1);
1479 hlayer->Draw("colz");
1483 //________________________________________________________
1484 Bool_t AliTRDcheckDET::MakeBarPlot(TH1 *histo, Int_t color){
1486 // Draw nice bar plots
1488 if(!histo->GetEntries()) return kFALSE;
1489 histo->Scale(100./histo->Integral());
1490 histo->SetFillColor(color);
1491 histo->SetBarOffset(.2);
1492 histo->SetBarWidth(.6);
1493 histo->Draw("bar1");