11 #include <TObjString.h>
14 #include <TProfile2D.h>
18 #include "AliTRDcluster.h"
19 #include "AliESDHeader.h"
20 #include "AliESDRun.h"
21 #include "AliESDtrack.h"
22 #include "AliTRDgeometry.h"
23 #include "AliTRDpadPlane.h"
24 #include "AliTRDSimParam.h"
25 #include "AliTRDseedV1.h"
26 #include "AliTRDtrackV1.h"
27 #include "AliTRDtrackerV1.h"
28 #include "AliTRDReconstructor.h"
29 #include "AliTrackReference.h"
30 #include "AliTrackPointArray.h"
31 #include "AliTracker.h"
32 #include "TTreeStream.h"
34 #include "AliTRDtrackInfo/AliTRDtrackInfo.h"
35 #include "AliTRDtrackInfo/AliTRDeventInfo.h"
36 #include "AliTRDcheckDetector.h"
41 ////////////////////////////////////////////////////////////////////////////
43 // Reconstruction QA //
45 // Task doing basic checks for tracking and detector performance //
48 // Anton Andronic <A.Andronic@gsi.de> //
49 // Markus Fasel <M.Fasel@gsi.de> //
51 ////////////////////////////////////////////////////////////////////////////
53 //_______________________________________________________
54 AliTRDcheckDetector::AliTRDcheckDetector():
55 AliTRDrecoTask("DetChecker", "Basic Detector Checker")
62 // Default constructor
64 DefineInput(1,AliTRDeventInfo::Class());
65 fReconstructor = new AliTRDReconstructor;
66 fReconstructor->SetRecoParam(AliTRDrecoParam::GetLowFluxParam());
67 fGeo = new AliTRDgeometry;
71 //_______________________________________________________
72 AliTRDcheckDetector::~AliTRDcheckDetector(){
76 if(fTriggerNames) delete fTriggerNames;
77 delete fReconstructor;
81 //_______________________________________________________
82 void AliTRDcheckDetector::ConnectInputData(Option_t *opt){
84 // Connect the Input data with the task
86 AliTRDrecoTask::ConnectInputData(opt);
87 fEventInfo = dynamic_cast<AliTRDeventInfo *>(GetInputData(1));
90 //_______________________________________________________
91 void AliTRDcheckDetector::CreateOutputObjects(){
93 // Create Output Objects
95 OpenFile(0,"RECREATE");
96 fContainer = Histos();
97 if(!fTriggerNames) fTriggerNames = new TMap();
100 //_______________________________________________________
101 void AliTRDcheckDetector::Exec(Option_t *opt){
103 // Execution function
104 // Filling TRD quality histos
106 if(!HasMCdata() && fEventInfo->GetEventHeader()->GetEventType() != 7) return; // For real data we select only physical events
107 AliTRDrecoTask::Exec(opt);
108 Int_t nTracks = 0; // Count the number of tracks per event
109 Int_t triggermask = fEventInfo->GetEventHeader()->GetTriggerMask();
110 TString triggername = fEventInfo->GetRunInfo()->GetFiredTriggerClasses(triggermask);
111 if(fDebugLevel > 6)printf("Trigger cluster: %d, Trigger class: %s\n", triggermask, triggername.Data());
112 dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTrigger))->Fill(triggermask);
113 for(Int_t iti = 0; iti < fTracks->GetEntriesFast(); iti++){
114 if(!fTracks->UncheckedAt(iti)) continue;
115 AliTRDtrackInfo *fTrackInfo = dynamic_cast<AliTRDtrackInfo *>(fTracks->UncheckedAt(iti));
116 if(!fTrackInfo->GetTrack()) continue;
120 dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTriggerTracks))->Fill(triggermask);
121 dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNtracksEvent))->Fill(nTracks);
123 if(triggermask <= 20 && !fTriggerNames->FindObject(Form("%d", triggermask))){
124 fTriggerNames->Add(new TObjString(Form("%d", triggermask)), new TObjString(triggername));
125 // also set the label for both histograms
126 TH1 *histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTriggerTracks));
127 histo->GetXaxis()->SetBinLabel(histo->FindBin(triggermask), triggername);
128 histo = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTrigger));
129 histo->GetXaxis()->SetBinLabel(histo->FindBin(triggermask), triggername);
131 PostData(0, fContainer);
134 //_______________________________________________________
135 void AliTRDcheckDetector::Terminate(Option_t *){
137 // Terminate function
141 //_______________________________________________________
142 Bool_t AliTRDcheckDetector::PostProcess(){
144 // Do Postprocessing (for the moment set the number of Reference histograms)
148 h = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNtrackletsTrack));
149 if(h->GetEntries()) h->Scale(100./h->Integral());
151 h = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNtrackletsCross));
152 if(h->GetEntries()) h->Scale(100./h->Integral());
154 h = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNtracksSector));
155 if(h->GetEntries()) h->Scale(100./h->Integral());
157 // Calculate of the trigger clusters purity
158 h = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTrigger));
159 TH1F *h1 = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kNeventsTriggerTracks));
161 Float_t purities[20], val = 0;
162 TString triggernames[20];
163 Int_t nTriggerClasses = 0;
164 for(Int_t ibin = 1; ibin <= h->GetNbinsX(); ibin++){
165 if((val = h1->GetBinContent(ibin))){
166 purities[nTriggerClasses] = val;
167 triggernames[nTriggerClasses] = h1->GetXaxis()->GetBinLabel(ibin);
171 h = dynamic_cast<TH1F *>(fContainer->UncheckedAt(kTriggerPurity));
172 TAxis *ax = h->GetXaxis();
173 for(Int_t itrg = 0; itrg < nTriggerClasses; itrg++){
174 h->Fill(itrg, purities[itrg]);
175 ax->SetBinLabel(itrg+1, triggernames[itrg].Data());
177 ax->SetRangeUser(-0.5, nTriggerClasses+.5);
178 h->GetYaxis()->SetRangeUser(0,1);
185 //_______________________________________________________
186 Bool_t AliTRDcheckDetector::GetRefFigure(Int_t ifig){
188 // Setting Reference Figures
190 TObjArray *arr = 0x0;
191 TH1 *h = 0x0, *h1 = 0x0, *h2 = 0x0;
194 case kNclustersTrack:
195 ((TH1F*)fContainer->At(kNclustersTrack))->Draw("pl");
197 case kNclustersTracklet:
198 ((TH1F*)fContainer->At(kNclustersTracklet))->Draw("pc");
200 case kNtrackletsTrack:
201 h = (TH1F*)fContainer->At(kNtrackletsTrack);
202 if(!h->GetEntries()) break;
203 h->SetFillColor(kGreen);
208 case kNtrackletsCross:
209 h = (TH1F*)fContainer->At(kNtrackletsCross);
210 if(!h->GetEntries()) break;
211 h->SetFillColor(kRed);
216 case kNtrackletsFindable:
217 h = (TH1F*)fContainer->At(kNtrackletsFindable);
218 if(!h->GetEntries()) break;
219 h->Scale(100./h->Integral());
220 h->SetFillColor(kGreen);
226 ((TH1F*)fContainer->At(kNtracksEvent))->Draw("pl");
229 h = (TH1F*)fContainer->At(kNtracksSector);
230 if(!h->GetEntries()) break;
231 h->SetFillColor(kGreen);
237 ((TH1F*)((TObjArray*)fContainer->At(kChi2))->At(0))->Draw("");
240 arr = (TObjArray*)fContainer->At(kPH);
241 h = (TH1F*)arr->At(0);
242 h->SetMarkerStyle(24);
243 h->SetMarkerColor(kBlack);
244 h->SetLineColor(kBlack);
246 // copy the second histogram in a new one with the same x-dimension as the phs with respect to time
247 h1 = (TH1F *)arr->At(1);
248 h2 = new TH1F("hphs1","Average PH", 31, -0.5, 30.5);
249 for(Int_t ibin = h1->GetXaxis()->GetFirst(); ibin < h1->GetNbinsX(); ibin++)
250 h2->SetBinContent(ibin, h1->GetBinContent(ibin));
251 h2->SetMarkerStyle(22);
252 h2->SetMarkerColor(kBlue);
253 h2->SetLineColor(kBlue);
256 // create axis according to the histogram dimensions of the original second histogram
257 axis = new TGaxis(gPad->GetUxmin(),
261 -0.08, 4.88, 510,"-L");
262 axis->SetLineColor(kBlue);
263 axis->SetLabelColor(kBlue);
264 axis->SetTextColor(kBlue);
265 axis->SetTitle("x_{0}-x_{c} [cm]");
269 ((TH1F*)fContainer->At(kChargeCluster))->Draw("c");
271 case kChargeTracklet:
272 ((TH1F*)fContainer->At(kChargeTracklet))->Draw("c");
274 case kNeventsTrigger:
275 ((TH1F*)fContainer->At(kNeventsTrigger))->Draw("");
277 case kNeventsTriggerTracks:
278 ((TH1F*)fContainer->At(kNeventsTriggerTracks))->Draw("");
281 h=(TH1F*)fContainer->At(kTriggerPurity);
284 h->SetFillColor(kGreen);
290 AliInfo(Form("Reference plot [%d] missing result", ifig));
294 //_______________________________________________________
295 TObjArray *AliTRDcheckDetector::Histos(){
297 // Create QA histograms
299 if(fContainer) return fContainer;
301 fContainer = new TObjArray(14);
302 //fContainer->SetOwner(kTRUE);
304 // Register Histograms
306 if(!(h = (TH1F *)gROOT->FindObject("hNcls"))){
307 h = new TH1F("hNcls", "N_{clusters} / track", 181, -0.5, 180.5);
308 h->GetXaxis()->SetTitle("N_{clusters}");
309 h->GetYaxis()->SetTitle("Entries");
311 fContainer->AddAt(h, kNclustersTrack);
313 if(!(h = (TH1F *)gROOT->FindObject("hNclTls"))){
314 h = new TH1F("hNclTls","N_{clusters} / tracklet", 51, -0.5, 50.5);
315 h->GetXaxis()->SetTitle("N_{clusters}");
316 h->GetYaxis()->SetTitle("Entries");
318 fContainer->AddAt(h, kNclustersTracklet);
320 if(!(h = (TH1F *)gROOT->FindObject("hNtls"))){
321 h = new TH1F("hNtls", "N_{tracklets} / track", AliTRDgeometry::kNlayer, 0.5, 6.5);
322 h->GetXaxis()->SetTitle("N^{tracklet}");
323 h->GetYaxis()->SetTitle("freq. [%]");
325 fContainer->AddAt(h, kNtrackletsTrack);
328 if(!(h = (TH1F *)gROOT->FindObject("hNtlsCross"))){
329 h = new TH1F("hNtlsCross", "N_{tracklets}^{cross} / track", 7, -0.5, 6.5);
330 h->GetXaxis()->SetTitle("n_{row cross}");
331 h->GetYaxis()->SetTitle("freq. [%]");
333 fContainer->AddAt(h, kNtrackletsCross);
335 if(!(h = (TH1F *)gROOT->FindObject("hNtlsFindable"))){
336 h = new TH1F("hNtlsFindable", "Found/Findable Tracklets" , 101, -0.005, 1.005);
337 h->GetXaxis()->SetTitle("r [a.u]");
338 h->GetYaxis()->SetTitle("Entries");
340 fContainer->AddAt(h, kNtrackletsFindable);
342 if(!(h = (TH1F *)gROOT->FindObject("hNtrks"))){
343 h = new TH1F("hNtrks", "N_{tracks} / event", 100, 0, 100);
344 h->GetXaxis()->SetTitle("N_{tracks}");
345 h->GetYaxis()->SetTitle("Entries");
347 fContainer->AddAt(h, kNtracksEvent);
349 if(!(h = (TH1F *)gROOT->FindObject("hNtrksSector"))){
350 h = new TH1F("hNtrksSector", "N_{tracks} / sector", AliTRDgeometry::kNsector, -0.5, 17.5);
351 h->GetXaxis()->SetTitle("sector");
352 h->GetYaxis()->SetTitle("freq. [%]");
354 fContainer->AddAt(h, kNtracksSector);
357 TObjArray *arr = new TObjArray(2);
358 arr->SetOwner(kTRUE); arr->SetName("<PH>");
359 fContainer->AddAt(arr, kPH);
360 if(!(h = (TH1F *)gROOT->FindObject("hPHt"))){
361 h = new TProfile("hPHt", "<PH>", 31, -0.5, 30.5);
362 h->GetXaxis()->SetTitle("Time / 100ns");
363 h->GetYaxis()->SetTitle("<PH> [a.u]");
366 if(!(h = (TH1F *)gROOT->FindObject("hPHx")))
367 h = new TProfile("hPHx", "<PH>", 31, -0.08, 4.88);
372 arr = new TObjArray(2);
373 arr->SetOwner(kTRUE); arr->SetName("Chi2");
374 fContainer->AddAt(arr, kChi2);
375 if(!(h = (TH1F *)gROOT->FindObject("hChi2")))
376 h = new TH1F("hChi2", "#Chi2", 200, 0, 20);
379 if(!(h = (TH1F *)gROOT->FindObject("hChi2n")))
380 h = new TH1F("hChi2n", "Norm. Chi2 (tracklets)", 50, 0, 5);
385 if(!(h = (TH1F *)gROOT->FindObject("hQcl"))){
386 h = new TH1F("hQcl", "Q_{cluster}", 200, 0, 1200);
387 h->GetXaxis()->SetTitle("Q_{cluster} [a.u.]");
388 h->GetYaxis()->SetTitle("Entries");
390 fContainer->AddAt(h, kChargeCluster);
392 if(!(h = (TH1F *)gROOT->FindObject("hQtrklt"))){
393 h = new TH1F("hQtrklt", "Q_{tracklet}", 6000, 0, 6000);
394 h->GetXaxis()->SetTitle("Q_{tracklet} [a.u.]");
395 h->GetYaxis()->SetTitle("Entries");
397 fContainer->AddAt(h, kChargeTracklet);
400 if(!(h = (TH1F *)gROOT->FindObject("hEventsTrigger")))
401 h = new TH1F("hEventsTrigger", "Trigger Class", 100, 0, 100);
403 fContainer->AddAt(h, kNeventsTrigger);
405 if(!(h = (TH1F *)gROOT->FindObject("hEventsTriggerTracks")))
406 h = new TH1F("hEventsTriggerTracks", "Trigger Class (Tracks)", 100, 0, 100);
408 fContainer->AddAt(h, kNeventsTriggerTracks);
410 if(!(h = (TH1F *)gROOT->FindObject("hTriggerPurity"))){
411 h = new TH1F("hTriggerPurity", "Trigger Purity", 10, -0.5, 9.5);
412 h->GetXaxis()->SetTitle("Trigger Cluster");
413 h->GetYaxis()->SetTitle("freq.");
415 fContainer->AddAt(h, kTriggerPurity);
424 //_______________________________________________________
425 TH1 *AliTRDcheckDetector::PlotNClustersTracklet(const AliTRDtrackV1 *track){
427 // Plot the mean number of clusters per tracklet
429 if(track) fTrack = track;
431 AliWarning("No Track defined.");
435 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclustersTracklet)))){
436 AliWarning("No Histogram defined.");
439 AliTRDseedV1 *tracklet = 0x0;
440 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
441 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
442 h->Fill(tracklet->GetN2());
447 //_______________________________________________________
448 TH1 *AliTRDcheckDetector::PlotNClustersTrack(const AliTRDtrackV1 *track){
450 // Plot the number of clusters in one track
452 if(track) fTrack = track;
454 AliWarning("No Track defined.");
458 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNclustersTrack)))){
459 AliWarning("No Histogram defined.");
464 AliTRDseedV1 *tracklet = 0x0;
465 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
466 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
467 nclusters += tracklet->GetN();
469 Int_t crossing = Int_t(tracklet->IsRowCross());
470 Int_t detector = tracklet->GetDetector();
471 Float_t theta = TMath::ATan(tracklet->GetZref(1));
472 Float_t phi = TMath::ATan(tracklet->GetYref(1));
473 Float_t momentum = 0.;
475 Int_t kinkIndex = fESD ? fESD->GetKinkIndex() : 0;
476 UShort_t TPCncls = fESD ? fESD->GetTPCncls() : 0;
478 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
481 (*fDebugStream) << "NClustersTrack"
482 << "Detector=" << detector
483 << "crossing=" << crossing
484 << "momentum=" << momentum
488 << "kinkIndex=" << kinkIndex
489 << "TPCncls=" << TPCncls
490 << "nclusters=" << nclusters
499 //_______________________________________________________
500 TH1 *AliTRDcheckDetector::PlotNTrackletsTrack(const AliTRDtrackV1 *track){
502 // Plot the number of tracklets
504 if(track) fTrack = track;
506 AliWarning("No Track defined.");
510 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsTrack)))){
511 AliWarning("No Histogram defined.");
514 Int_t nTracklets = fTrack->GetNumberOfTracklets();
518 // If we have one Tracklet, check in which layer this happens
520 AliTRDseedV1 *tracklet = 0x0;
521 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
522 if((tracklet = fTrack->GetTracklet(il)) && tracklet->IsOK()){layer = il; break;}
524 (*fDebugStream) << "NTrackletsTrack"
533 //_______________________________________________________
534 TH1 *AliTRDcheckDetector::PlotNTrackletsRowCross(const AliTRDtrackV1 *track){
536 // Plot the number of tracklets
538 if(track) fTrack = track;
540 AliWarning("No Track defined.");
544 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsCross)))){
545 AliWarning("No Histogram defined.");
550 AliTRDseedV1 *tracklet = 0x0;
551 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
552 if(!(tracklet = fTrack->GetTracklet(il)) || !tracklet->IsOK()) continue;
554 if(tracklet->IsRowCross()) ncross++;
560 //_______________________________________________________
561 TH1 *AliTRDcheckDetector::PlotFindableTracklets(const AliTRDtrackV1 *track){
563 // Plots the ratio of number of tracklets vs.
564 // number of findable tracklets
566 // Findable tracklets are defined as track prolongation
567 // to layer i does not hit the dead area +- epsilon
569 // In order to check whether tracklet hist active area in Layer i,
570 // the track is refitted and the fitted position + an uncertainty
571 // range is compared to the chamber border (also with a different
574 // For the track fit two cases are distinguished:
575 // If the track is a stand alone track (defined by the status bit
576 // encoding, then the track is fitted with the tilted Rieman model
577 // Otherwise the track is fitted with the Kalman fitter in two steps:
578 // Since the track parameters are give at the outer point, we first
579 // fit in direction inwards. Afterwards we fit again in direction outwards
580 // to extrapolate the track to layers which are not reached by the track
581 // For the Kalman model, the radial track points have to be shifted by
582 // a distance epsilon in the direction that we want to fit
584 const Float_t epsilon = 0.01; // dead area tolerance
585 const Float_t epsilon_R = 1; // shift in radial direction of the anode wire position (Kalman filter only)
586 const Float_t delta_y = 0.7; // Tolerance in the track position in y-direction
587 const Float_t delta_z = 7.0; // Tolerance in the track position in z-direction (Padlength)
588 Double_t x_anode[AliTRDgeometry::kNlayer] = {300.2, 312.8, 325.4, 338.0, 350.6, 363.2}; // Take the default X0
590 if(track) fTrack = track;
592 AliWarning("No Track defined.");
596 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtrackletsFindable)))){
597 AliWarning("No Histogram defined.");
600 Int_t nFound = 0, nFindable = 0;
602 Double_t ymin = 0., ymax = 0., zmin = 0., zmax = 0.;
603 Double_t y = 0., z = 0.;
604 AliTRDseedV1 *tracklet = 0x0;
606 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
607 if((tracklet = fTrack->GetTracklet(il)) && tracklet->IsOK()){
608 tracklet->SetReconstructor(fReconstructor);
612 // 2 Different cases:
613 // 1st stand alone: here we cannot propagate, but be can do a Tilted Rieman Fit
614 // 2nd barrel track: here we propagate the track to the layers
615 AliTrackPoint points[6];
617 memset(xyz, 0, sizeof(Float_t) * 3);
618 if(((fESD->GetStatus() & AliESDtrack::kTRDout) > 0) && !((fESD->GetStatus() & AliESDtrack::kTRDin) > 0)){
620 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
621 xyz[0] = x_anode[il];
622 points[il].SetXYZ(xyz);
624 AliTRDtrackerV1::FitRiemanTilt(const_cast<AliTRDtrackV1 *>(fTrack), 0x0, kTRUE, 6, points);
630 // -> Kalman outwards
631 AliTRDtrackV1 copy_track(*fTrack); // Do Kalman on a (non-constant) copy of the track
632 AliTrackPoint points_inward[6], points_outward[6];
633 for(Int_t il = AliTRDgeometry::kNlayer; il--;){
634 // In order to avoid complications in the Kalman filter if the track points have the same radial
635 // position like the tracklets, we have to shift the radial postion of the anode wire by epsilon
636 // in the direction we want to go
637 // The track points have to be in reverse order for the Kalman Filter inwards
638 xyz[0] = x_anode[AliTRDgeometry::kNlayer - il - 1] - epsilon_R;
639 points_inward[il].SetXYZ(xyz);
640 xyz[0] = x_anode[il] + epsilon_R;
641 points_outward[il].SetXYZ(xyz);
643 /*for(Int_t ipt = 0; ipt < AliTRDgeometry::kNlayer; ipt++)
644 printf("%d. X = %f\n", ipt, points[ipt].GetX());*/
646 AliTRDtrackerV1::FitKalman(©_track, 0x0, kFALSE, 6, points_inward);
647 memcpy(points, points_inward, sizeof(AliTrackPoint) * 6); // Preliminary store the inward results in the Array points
649 AliTRDtrackerV1::FitKalman(©_track, 0x0, kTRUE, 6, points_inward);
650 memcpy(points, points_outward, sizeof(AliTrackPoint) * AliTRDgeometry::kNlayer);
652 for(Int_t il = 0; il < AliTRDgeometry::kNlayer; il++){
653 y = points[il].GetY();
654 z = points[il].GetZ();
655 if((stack = fGeo->GetStack(z, il)) < 0) continue; // Not findable
656 pp = fGeo->GetPadPlane(il, stack);
657 ymin = pp->GetCol0() + epsilon;
658 ymax = pp->GetColEnd() - epsilon;
659 zmin = pp->GetRowEnd() + epsilon;
660 zmax = pp->GetRow0() - epsilon;
661 // ignore y-crossing (material)
662 if((z + delta_z > zmin && z - delta_z < zmax) && (y + delta_y > ymin && y - delta_y < ymax)) nFindable++;
664 Double_t pos_tracklet[2] = {tracklet ? tracklet->GetYfit(0) : 0, tracklet ? tracklet->GetZfit(0) : 0};
665 Int_t hasTracklet = tracklet ? 1 : 0;
666 (*fDebugStream) << "FindableTracklets"
668 << "ytracklet=" << pos_tracklet[0]
670 << "ztracklet=" << pos_tracklet[1]
672 << "tracklet=" << hasTracklet
677 h->Fill(nFindable > 0 ? TMath::Min(nFound/static_cast<Double_t>(nFindable), 1.) : 1);
678 if(fDebugLevel > 2) AliInfo(Form("Findable[Found]: %d[%d|%f]", nFindable, nFound, nFound/static_cast<Float_t>(nFindable > 0 ? nFindable : 1)));
683 //_______________________________________________________
684 TH1 *AliTRDcheckDetector::PlotChi2(const AliTRDtrackV1 *track){
686 // Plot the chi2 of the track
688 if(track) fTrack = track;
690 AliWarning("No Track defined.");
694 if(!(h = dynamic_cast<TH1F *>(((TObjArray*)(fContainer->At(kChi2)))->At(0)))){
695 AliWarning("No Histogram defined.");
698 h->Fill(fTrack->GetChi2());
702 //_______________________________________________________
703 TH1 *AliTRDcheckDetector::PlotChi2Norm(const AliTRDtrackV1 *track){
705 // Plot the chi2 of the track
707 if(track) fTrack = track;
709 AliWarning("No Track defined.");
713 if(!(h = dynamic_cast<TH1F *>(((TObjArray*)(fContainer->At(kChi2)))->At(1)))){
714 AliWarning("No Histogram defined.");
717 Int_t nTracklets = 0;
718 AliTRDseedV1 *tracklet = 0x0;
719 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
720 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
723 h->Fill(fTrack->GetChi2()/nTracklets);
728 //_______________________________________________________
729 TH1 *AliTRDcheckDetector::PlotPHt(const AliTRDtrackV1 *track){
731 // Plot the average pulse height
733 if(track) fTrack = track;
735 AliWarning("No Track defined.");
739 if(!(h = dynamic_cast<TProfile *>(((TObjArray*)(fContainer->At(kPH)))->At(0)))){
740 AliWarning("No Histogram defined.");
743 AliTRDseedV1 *tracklet = 0x0;
744 AliTRDcluster *c = 0x0;
745 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
746 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
747 Int_t crossing = Int_t(tracklet->IsRowCross());
748 Int_t detector = tracklet->GetDetector();
749 for(Int_t itime = 0; itime < AliTRDtrackerV1::GetNTimeBins(); itime++){
750 if(!(c = tracklet->GetClusters(itime))) continue;
751 Int_t localtime = c->GetLocalTimeBin();
752 Double_t absolute_charge = TMath::Abs(c->GetQ());
753 h->Fill(localtime, absolute_charge);
755 Double_t distance[2];
756 GetDistanceToTracklet(distance, tracklet, c);
757 Float_t theta = TMath::ATan(tracklet->GetZref(1));
758 Float_t phi = TMath::ATan(tracklet->GetYref(1));
759 Float_t momentum = 0.;
761 Int_t kinkIndex = fESD ? fESD->GetKinkIndex() : 0;
762 UShort_t TPCncls = fESD ? fESD->GetTPCncls() : 0;
764 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
767 (*fDebugStream) << "PHt"
768 << "Detector=" << detector
769 << "crossing=" << crossing
770 << "Timebin=" << localtime
771 << "Charge=" << absolute_charge
772 << "momentum=" << momentum
776 << "kinkIndex=" << kinkIndex
777 << "TPCncls=" << TPCncls
778 << "dy=" << distance[0]
779 << "dz=" << distance[1]
788 //_______________________________________________________
789 TH1 *AliTRDcheckDetector::PlotPHx(const AliTRDtrackV1 *track){
791 // Plots the average pulse height vs the distance from the anode wire
792 // (plus const anode wire offset)
794 if(track) fTrack = track;
796 AliWarning("No Track defined.");
800 if(!(h = dynamic_cast<TProfile *>(((TObjArray*)(fContainer->At(kPH)))->At(1)))){
801 AliWarning("No Histogram defined.");
804 Float_t offset = .5*AliTRDgeometry::CamHght();
805 AliTRDseedV1 *tracklet = 0x0;
806 AliTRDcluster *c = 0x0;
807 Double_t distance = 0;
808 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
809 if(!(tracklet = fTrack->GetTracklet(itl)) || !(tracklet->IsOK())) continue;
810 tracklet->ResetClusterIter();
811 while((c = tracklet->NextCluster())){
812 distance = tracklet->GetX0() - c->GetX() + offset;
813 h->Fill(distance, TMath::Abs(c->GetQ()));
819 //_______________________________________________________
820 TH1 *AliTRDcheckDetector::PlotChargeCluster(const AliTRDtrackV1 *track){
822 // Plot the cluster charge
824 if(track) fTrack = track;
826 AliWarning("No Track defined.");
830 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChargeCluster)))){
831 AliWarning("No Histogram defined.");
834 AliTRDseedV1 *tracklet = 0x0;
835 AliTRDcluster *c = 0x0;
836 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
837 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK())continue;
838 for(Int_t itime = 0; itime < AliTRDtrackerV1::GetNTimeBins(); itime++){
839 if(!(c = tracklet->GetClusters(itime))) continue;
846 //_______________________________________________________
847 TH1 *AliTRDcheckDetector::PlotChargeTracklet(const AliTRDtrackV1 *track){
849 // Plot the charge deposit per chamber
851 if(track) fTrack = track;
853 AliWarning("No Track defined.");
857 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kChargeTracklet)))){
858 AliWarning("No Histogram defined.");
861 AliTRDseedV1 *tracklet = 0x0;
862 AliTRDcluster *c = 0x0;
864 Int_t nTracklets =fTrack->GetNumberOfTracklets();
865 for(Int_t itl = 0x0; itl < AliTRDgeometry::kNlayer; itl++){
866 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
868 for(Int_t ic = AliTRDseedV1::kNTimeBins; ic--;){
869 if(!(c = tracklet->GetClusters(ic))) continue;
870 Qtot += TMath::Abs(c->GetQ());
874 Int_t crossing = (Int_t)tracklet->IsRowCross();
875 Int_t detector = tracklet->GetDetector();
876 Float_t theta = TMath::ATan(tracklet->GetZfit(1));
877 Float_t phi = TMath::ATan(tracklet->GetYfit(1));
878 Float_t momentum = 0.;
880 Int_t kinkIndex = fESD ? fESD->GetKinkIndex() : 0;
881 UShort_t TPCncls = fESD ? fESD->GetTPCncls() : 0;
883 if(fMC->GetTrackRef()) momentum = fMC->GetTrackRef()->P();
886 (*fDebugStream) << "ChargeTracklet"
887 << "Detector=" << detector
888 << "crossing=" << crossing
889 << "momentum=" << momentum
890 << "nTracklets="<< nTracklets
894 << "kinkIndex=" << kinkIndex
895 << "TPCncls=" << TPCncls
903 //_______________________________________________________
904 TH1 *AliTRDcheckDetector::PlotNTracksSector(const AliTRDtrackV1 *track){
906 // Plot the number of tracks per Sector
908 if(track) fTrack = track;
910 AliWarning("No Track defined.");
914 if(!(h = dynamic_cast<TH1F *>(fContainer->At(kNtracksSector)))){
915 AliWarning("No Histogram defined.");
919 // TODO we should compare with
920 // sector = Int_t(track->GetAlpha() / AliTRDgeometry::GetAlpha());
922 AliTRDseedV1 *tracklet = 0x0;
924 for(Int_t itl = 0; itl < AliTRDgeometry::kNlayer; itl++){
925 if(!(tracklet = fTrack->GetTracklet(itl)) || !tracklet->IsOK()) continue;
926 sector = static_cast<Int_t>(tracklet->GetDetector()/AliTRDgeometry::kNdets);
934 //________________________________________________________
935 void AliTRDcheckDetector::SetRecoParam(AliTRDrecoParam *r)
938 fReconstructor->SetRecoParam(r);
941 //________________________________________________________
942 void AliTRDcheckDetector::GetDistanceToTracklet(Double_t *dist, AliTRDseedV1 *tracklet, AliTRDcluster *c)
944 Float_t x = c->GetX();
945 dist[0] = c->GetY() - tracklet->GetYat(x);
946 dist[1] = c->GetZ() - tracklet->GetZat(x);