1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercialf purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 /* $Id: AliTRDresolution.cxx 27496 2008-07-22 08:35:45Z cblume $ */
18 ////////////////////////////////////////////////////////////////////////////
20 // TRD tracking resolution //
22 // The class performs resolution and residual studies
23 // of the TRD tracks for the following quantities :
24 // - spatial position (y, [z])
25 // - angular (phi) tracklet
26 // - momentum at the track level
28 // The class has to be used for regular detector performance checks using the official macros:
29 // - $ALICE_ROOT/TRD/qaRec/run.C
30 // - $ALICE_ROOT/TRD/qaRec/makeResults.C
32 // For stand alone usage please refer to the following example:
34 // gSystem->Load("libANALYSIS.so");
35 // gSystem->Load("libTRDqaRec.so");
36 // AliTRDresolution *res = new AliTRDresolution();
37 // //res->SetMCdata();
38 // //res->SetVerbose();
39 // //res->SetVisual();
41 // if(!res->PostProcess()) return;
42 // res->GetRefFigure(0);
46 // Alexandru Bercuci <A.Bercuci@gsi.de> //
47 // Markus Fasel <M.Fasel@gsi.de> //
49 ////////////////////////////////////////////////////////////////////////////
54 #include <TObjArray.h>
63 #include <TGraphErrors.h>
64 #include <TGraphAsymmErrors.h>
65 #include <TLinearFitter.h>
69 #include <TTreeStream.h>
70 #include <TGeoManager.h>
71 #include <TDatabasePDG.h>
75 #include "AliESDtrack.h"
76 #include "AliMathBase.h"
77 #include "AliTrackPointArray.h"
79 #include "AliTRDresolution.h"
80 #include "AliTRDgeometry.h"
81 #include "AliTRDpadPlane.h"
82 #include "AliTRDcluster.h"
83 #include "AliTRDseedV1.h"
84 #include "AliTRDtrackV1.h"
85 #include "AliTRDReconstructor.h"
86 #include "AliTRDrecoParam.h"
87 #include "AliTRDpidUtil.h"
88 #include "AliTRDinfoGen.h"
90 #include "info/AliTRDclusterInfo.h"
92 ClassImp(AliTRDresolution)
94 UChar_t const AliTRDresolution::fgNproj[kNviews] = {
98 Char_t const * AliTRDresolution::fgPerformanceName[kNviews] = {
110 Char_t const * AliTRDresolution::fgParticle[11]={
111 " p bar", " K -", " #pi -", " #mu -", " e -",
113 " e +", " #mu +", " #pi +", " K +", " p",
116 // Configure segmentation for y resolution/residuals
117 Int_t const AliTRDresolution::fgkNresYsegm[3] = {
118 AliTRDgeometry::kNsector
119 ,AliTRDgeometry::kNsector*AliTRDgeometry::kNstack
120 ,AliTRDgeometry::kNdet
122 Char_t const *AliTRDresolution::fgkResYsegmName[3] = {
123 "Sector", "Stack", "Detector"};
126 //________________________________________________________
127 AliTRDresolution::AliTRDresolution()
143 // Default constructor
145 SetNameTitle("TRDresolution", "TRD spatial and momentum resolution");
146 SetSegmentationLevel();
147 memset(fXcorr, 0, AliTRDgeometry::kNdet*30*sizeof(Float_t));
150 //________________________________________________________
151 AliTRDresolution::AliTRDresolution(char* name)
152 :AliTRDrecoTask(name, "TRD spatial and momentum resolution")
167 // Default constructor
171 SetSegmentationLevel();
172 memset(fXcorr, 0, AliTRDgeometry::kNdet*30*sizeof(Float_t));
174 DefineOutput(kClToTrk, TObjArray::Class()); // cluster2track
175 DefineOutput(kClToMC, TObjArray::Class()); // cluster2mc
176 /* DefineOutput(kTrkltToTrk, TObjArray::Class()); // tracklet2track
177 DefineOutput(kTrkltToMC, TObjArray::Class()); // tracklet2mc*/
180 //________________________________________________________
181 AliTRDresolution::~AliTRDresolution()
187 if(fGraphS){fGraphS->Delete(); delete fGraphS;}
188 if(fGraphM){fGraphM->Delete(); delete fGraphM;}
189 if(fCl){fCl->Delete(); delete fCl;}
190 if(fMCcl){fMCcl->Delete(); delete fMCcl;}
191 /* if(fTrklt){fTrklt->Delete(); delete fTrklt;}
192 if(fMCtrklt){fMCtrklt->Delete(); delete fMCtrklt;}*/
196 //________________________________________________________
197 void AliTRDresolution::UserCreateOutputObjects()
199 // spatial resolution
201 AliTRDrecoTask::UserCreateOutputObjects();
202 InitExchangeContainers();
205 //________________________________________________________
206 void AliTRDresolution::InitExchangeContainers()
208 // Init containers for subsequent tasks (AliTRDclusterResolution)
210 fCl = new TObjArray(200);
211 fCl->SetOwner(kTRUE);
212 fMCcl = new TObjArray();
213 fMCcl->SetOwner(kTRUE);
214 /* fTrklt = new TObjArray();
215 fTrklt->SetOwner(kTRUE);
216 fMCtrklt = new TObjArray();
217 fMCtrklt->SetOwner(kTRUE);*/
218 PostData(kClToTrk, fCl);
219 PostData(kClToMC, fMCcl);
220 /* PostData(kTrkltToTrk, fTrklt);
221 PostData(kTrkltToMC, fMCtrklt);*/
224 //________________________________________________________
225 void AliTRDresolution::UserExec(Option_t *opt)
233 if(!HasLoadCorrection()) LoadCorrection("correction.lst");
234 AliTRDrecoTask::UserExec(opt);
237 //________________________________________________________
238 Bool_t AliTRDresolution::Pulls(Double_t dyz[2], Double_t cov[3], Double_t tilt) const
240 // Helper function to calculate pulls in the yz plane
241 // using proper tilt rotation
242 // Uses functionality defined by AliTRDseedV1.
244 Double_t t2(tilt*tilt);
248 cc[0] = cov[0] - 2.*tilt*cov[1] + t2*cov[2];
249 cc[1] = cov[1]*(1.-t2) + tilt*(cov[0] - cov[2]);
250 cc[2] = t2*cov[0] + 2.*tilt*cov[1] + cov[2];
252 Double_t sqr[3]={0., 0., 0.};
253 if(AliTRDseedV1::GetCovSqrt(cc, sqr)) return kFALSE;
254 Double_t invsqr[3]={0., 0., 0.};
255 if(AliTRDseedV1::GetCovInv(sqr, invsqr)<1.e-40) return kFALSE;
256 Double_t tmp(dyz[0]);
257 dyz[0] = invsqr[0]*tmp + invsqr[1]*dyz[1];
258 dyz[1] = invsqr[1]*tmp + invsqr[2]*dyz[1];
262 //________________________________________________________
263 TH1* AliTRDresolution::PlotCharge(const AliTRDtrackV1 *track)
266 // Plots the charge distribution
269 if(track) fkTrack = track;
271 AliDebug(4, "No Track defined.");
274 TObjArray *arr = NULL;
275 if(!fContainer || !(arr = ((TObjArray*)fContainer->At(kCharge)))){
276 AliWarning("No output container defined.");
281 AliTRDseedV1 *fTracklet = NULL;
282 AliTRDcluster *c = NULL;
283 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
284 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
285 if(!fTracklet->IsOK()) continue;
286 Float_t x0 = fTracklet->GetX0();
288 for(Int_t itb=AliTRDseedV1::kNtb; itb--;){
289 if(!(c = fTracklet->GetClusters(itb))){
290 if(!(c = fTracklet->GetClusters(AliTRDseedV1::kNtb+itb))) continue;
292 dqdl = fTracklet->GetdQdl(itb, &dl);
293 if(dqdl<1.e-5) continue;
294 dl /= 0.15; // dl/dl0, dl0 = 1.5 mm for nominal vd
295 (h = (TH3S*)arr->At(0))->Fill(dl, x0-c->GetX(), dqdl);
298 // if(!HasMCdata()) continue;
300 // Float_t pt0, y0, z0, dydx0, dzdx0;
301 // if(!fMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
308 //________________________________________________________
309 TH1* AliTRDresolution::PlotCluster(const AliTRDtrackV1 *track)
312 // Plot the cluster distributions
315 if(track) fkTrack = track;
317 AliDebug(4, "No Track defined.");
320 TObjArray *arr = NULL;
321 if(!fContainer || !(arr = ((TObjArray*)fContainer->At(kCluster)))){
322 AliWarning("No output container defined.");
325 ULong_t status = fkESD ? fkESD->GetStatus():0;
328 Double_t covR[7], cov[3], dy[2], dz[2];
329 Float_t pt, x0, y0, z0, dydx, dzdx, tilt(0.);
330 const AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
331 AliTRDseedV1 *fTracklet(NULL); TObjArray *clInfoArr(NULL);
332 // do LINEAR track refit if asked by the user
333 // it is the user responsibility to check if B=0T
334 Float_t param[10]; memset(param, 0, 10*sizeof(Float_t));
335 Int_t np(0), nrc(0); AliTrackPoint clusters[300];
337 Bool_t kPrimary(kFALSE);
338 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
339 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
340 if(!fTracklet->IsOK()) continue;
341 x0 = fTracklet->GetX0();
342 tilt = fTracklet->GetTilt();
343 AliTRDcluster *c = NULL;
344 fTracklet->ResetClusterIter(kFALSE);
345 while((c = fTracklet->PrevCluster())){
346 Float_t xyz[3] = {c->GetX()+fXcorr[c->GetDetector()][c->GetLocalTimeBin()], c->GetY(), c->GetZ()};
347 clusters[np].SetCharge(tilt);
348 clusters[np].SetClusterType(0);
349 clusters[np].SetVolumeID(ily);
350 clusters[np].SetXYZ(xyz);
353 if(fTracklet->IsRowCross()){
354 Float_t xcross(0.), zcross(0.);
355 if(fTracklet->GetEstimatedCrossPoint(xcross, zcross)){
356 clusters[np].SetCharge(tilt);
357 clusters[np].SetClusterType(1);
358 clusters[np].SetVolumeID(ily);
359 clusters[np].SetXYZ(xcross, 0., zcross);
364 if(fTracklet->IsPrimary()) kPrimary = kTRUE;
367 clusters[np].SetCharge(tilt);
368 clusters[np].SetClusterType(1);
369 clusters[np].SetVolumeID(-1);
370 clusters[np].SetXYZ(0., 0., 0.);
373 if(!FitTrack(np, clusters, param)) {
374 AliDebug(1, "Linear track Fit failed.");
377 if(HasTrackSelection()){
378 Bool_t kReject(kFALSE);
379 if(fkTrack->GetNumberOfTracklets() != AliTRDgeometry::kNlayer) kReject = kTRUE;
380 if(!kReject && !UseTrack(np, clusters, param)) kReject = kTRUE;
382 AliDebug(1, "Reject track for residuals analysis.");
387 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
388 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
389 if(!fTracklet->IsOK()) continue;
390 x0 = fTracklet->GetX0();
391 pt = fTracklet->GetPt();
392 sgm[2] = fTracklet->GetDetector();
393 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
394 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
396 // retrive the track angle with the chamber
399 if(!FitTracklet(ily, np, clusters, param, par)) continue;
400 dydx = par[2];//param[3];
402 y0 = par[1] + dydx * (x0 - par[0]);//param[1] + dydx * (x0 - param[0]);
403 z0 = param[2] + dzdx * (x0 - param[0]);
405 y0 = fTracklet->GetYref(0);
406 z0 = fTracklet->GetZref(0);
407 dydx = fTracklet->GetYref(1);
408 dzdx = fTracklet->GetZref(1);
410 /*printf("RC[%c] Primary[%c]\n"
411 " Fit : y0[%f] z0[%f] dydx[%f] dzdx[%f]\n"
412 " Ref: y0[%f] z0[%f] dydx[%f] dzdx[%f]\n", fTracklet->IsRowCross()?'y':'n', fTracklet->IsPrimary()?'y':'n', y0, z0, dydx, dzdx
413 ,fTracklet->GetYref(0),fTracklet->GetZref(0),fTracklet->GetYref(1),fTracklet->GetZref(1));*/
414 tilt = fTracklet->GetTilt();
415 fTracklet->GetCovRef(covR);
416 Double_t t2(tilt*tilt)
418 ,cost(TMath::Sqrt(corr));
419 AliTRDcluster *c = NULL;
420 fTracklet->ResetClusterIter(kFALSE);
421 while((c = fTracklet->PrevCluster())){
422 Float_t xc = c->GetX()+fXcorr[c->GetDetector()][c->GetLocalTimeBin()];
423 Float_t yc = c->GetY();
424 Float_t zc = c->GetZ();
425 Float_t dx = x0 - xc;
426 Float_t yt = y0 - dx*dydx;
427 Float_t zt = z0 - dx*dzdx;
428 dy[0] = yc-yt; dz[0]= zc-zt;
431 dy[1] = cost*(dy[0] - dz[0]*tilt);
432 dz[1] = cost*(dz[0] + dy[0]*tilt);
433 if(pt>fPtThreshold && c->IsInChamber()) ((TH3S*)arr->At(0))->Fill(dydx, dy[1], sgm[fSegmentLevel]);
435 // tilt rotation of covariance for clusters
436 Double_t sy2(c->GetSigmaY2()), sz2(c->GetSigmaZ2());
437 cov[0] = (sy2+t2*sz2)*corr;
438 cov[1] = tilt*(sz2 - sy2)*corr;
439 cov[2] = (t2*sy2+sz2)*corr;
440 // sum with track covariance
441 cov[0]+=covR[0]; cov[1]+=covR[1]; cov[2]+=covR[2];
442 Double_t dyz[2]= {dy[1], dz[1]};
443 Pulls(dyz, cov, tilt);
444 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
446 // Get z-position with respect to anode wire
447 Int_t istk = geo->GetStack(c->GetDetector());
448 AliTRDpadPlane *pp = geo->GetPadPlane(ily, istk);
449 Float_t row0 = pp->GetRow0();
450 Float_t d = row0 - zt + pp->GetAnodeWireOffset();
451 d -= ((Int_t)(2 * d)) / 2.0;
452 if (d > 0.25) d = 0.5 - d;
454 AliTRDclusterInfo *clInfo(NULL);
455 clInfo = new AliTRDclusterInfo;
456 clInfo->SetCluster(c);
457 Float_t covF[] = {cov[0], cov[1], cov[2]};
458 clInfo->SetGlobalPosition(yt, zt, dydx, dzdx, covF);
459 clInfo->SetResolution(dy[1]);
460 clInfo->SetAnisochronity(d);
461 clInfo->SetDriftLength(dx);
462 clInfo->SetTilt(tilt);
463 if(fCl) fCl->Add(clInfo);
464 else AliDebug(1, "Cl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
468 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
469 clInfoArr->SetOwner(kFALSE);
471 clInfoArr->Add(clInfo);
474 if(DebugLevel()>=1 && clInfoArr){
475 (*DebugStream()) << "cluster"
476 <<"status=" << status
477 <<"clInfo.=" << clInfoArr
482 if(clInfoArr) delete clInfoArr;
484 return (TH3S*)arr->At(0);
488 //________________________________________________________
489 TH1* AliTRDresolution::PlotTracklet(const AliTRDtrackV1 *track)
491 // Plot normalized residuals for tracklets to track.
493 // We start from the result that if X=N(|m|, |Cov|)
495 // (Cov^{-1})^{1/2}X = N((Cov^{-1})^{1/2}*|m|, |1|)
497 // in our case X=(y_trklt - y_trk z_trklt - z_trk) and |Cov| = |Cov_trklt| + |Cov_trk| at the radial
498 // reference position.
499 if(track) fkTrack = track;
501 AliDebug(4, "No Track defined.");
504 TObjArray *arr = NULL;
505 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrack ))){
506 AliWarning("No output container defined.");
511 Double_t cov[3], covR[7]/*, sqr[3], inv[3]*/;
512 Double_t pt, phi, tht, x, dx, dy[2], dz[2];
513 AliTRDseedV1 *fTracklet(NULL);
514 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++){
515 if(!(fTracklet = fkTrack->GetTracklet(il))) continue;
516 if(!fTracklet->IsOK()) continue;
517 sgm[2] = fTracklet->GetDetector();
518 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
519 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
520 x = fTracklet->GetX();
521 dx = fTracklet->GetX0() - x;
522 pt = fTracklet->GetPt();
523 phi = fTracklet->GetYref(1);
524 tht = fTracklet->GetZref(1);
526 dy[0]= fTracklet->GetYref(0)-dx*fTracklet->GetYref(1) - fTracklet->GetY();
527 dz[0]= fTracklet->GetZref(0)-dx*fTracklet->GetZref(1) - fTracklet->GetZ();
528 Double_t tilt(fTracklet->GetTilt())
531 ,cost(TMath::Sqrt(corr));
532 Bool_t rc(fTracklet->IsRowCross());
534 // calculate residuals using tilt rotation
535 dy[1]= cost*(dy[0] - dz[0]*tilt);
536 dz[1]= cost*(dz[0] + dy[0]*tilt);
537 ((TH3S*)arr->At(0))->Fill(phi, dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
538 ((TH3S*)arr->At(2))->Fill(tht, dz[1], rc);
540 // compute covariance matrix
541 fTracklet->GetCovAt(x, cov);
542 fTracklet->GetCovRef(covR);
543 cov[0] += covR[0]; cov[1] += covR[1]; cov[2] += covR[2];
544 Double_t dyz[2]= {dy[1], dz[1]};
545 Pulls(dyz, cov, tilt);
546 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
547 ((TH3S*)arr->At(3))->Fill(tht, dyz[1], rc);
549 Double_t dphi((phi-fTracklet->GetYfit(1))/(1-phi*fTracklet->GetYfit(1)));
550 Double_t dtht((tht-fTracklet->GetZfit(1))/(1-tht*fTracklet->GetZfit(1)));
551 ((TH2I*)arr->At(4))->Fill(phi, TMath::ATan(dphi));
554 UChar_t err(fTracklet->GetErrorMsg());
555 (*DebugStream()) << "tracklet"
573 return (TH2I*)arr->At(0);
577 //________________________________________________________
578 TH1* AliTRDresolution::PlotTrackIn(const AliTRDtrackV1 *track)
580 // Store resolution/pulls of Kalman before updating with the TRD information
581 // at the radial position of the first tracklet. The following points are used
583 // - the (y,z,snp) of the first TRD tracklet
584 // - the (y, z, snp, tgl, pt) of the MC track reference
586 // Additionally the momentum resolution/pulls are calculated for usage in the
589 if(track) fkTrack = track;
591 AliDebug(4, "No Track defined.");
594 TObjArray *arr = NULL;
595 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackIn))){
596 AliWarning("No output container defined.");
599 AliExternalTrackParam *tin = NULL;
600 if(!(tin = fkTrack->GetTrackIn())){
601 AliWarning("Track did not entered TRD fiducial volume.");
606 Double_t x = tin->GetX();
607 AliTRDseedV1 *fTracklet = NULL;
608 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
609 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
612 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
613 AliWarning("Tracklet did not match Track.");
617 sgm[2] = fTracklet->GetDetector();
618 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
619 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
620 Double_t tilt(fTracklet->GetTilt())
623 ,cost(TMath::Sqrt(corr));
624 Bool_t rc(fTracklet->IsRowCross());
626 const Int_t kNPAR(5);
627 Double_t parR[kNPAR]; memcpy(parR, tin->GetParameter(), kNPAR*sizeof(Double_t));
628 Double_t covR[3*kNPAR]; memcpy(covR, tin->GetCovariance(), 3*kNPAR*sizeof(Double_t));
629 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
631 // define sum covariances
632 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
633 Double_t *pc = &covR[0], *pp = &parR[0];
634 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
636 for(Int_t ic = 0; ic<=ir; ic++,pc++){
637 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
640 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
641 //COV.Print(); PAR.Print();
643 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
644 Double_t dy[2]={parR[0] - fTracklet->GetY(), 0.}
645 ,dz[2]={parR[1] - fTracklet->GetZ(), 0.}
646 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
647 // calculate residuals using tilt rotation
648 dy[1] = cost*(dy[0] - dz[0]*tilt);
649 dz[1] = cost*(dz[0] + dy[0]*tilt);
651 if(1./PAR[4]>fPtThreshold) ((TH3S*)arr->At(0))->Fill(fTracklet->GetYref(1), dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
652 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
653 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
655 Double_t dyz[2] = {dy[1], dz[1]};
656 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
657 Pulls(dyz, cc, tilt);
658 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
659 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
663 // register reference histo for mini-task
664 h = (TH2I*)arr->At(0);
667 (*DebugStream()) << "trackIn"
673 Double_t y = fTracklet->GetY();
674 Double_t z = fTracklet->GetZ();
675 (*DebugStream()) << "trackletIn"
685 if(!HasMCdata()) return h;
687 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
688 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
689 Int_t pdg = fkMC->GetPDG(),
690 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
692 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
693 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
694 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
696 // translate to reference radial position
697 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
698 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
700 TVectorD PARMC(kNPAR);
701 PARMC[0]=y0; PARMC[1]=z0;
702 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
705 // TMatrixDSymEigen eigen(COV);
706 // TVectorD evals = eigen.GetEigenValues();
707 // TMatrixDSym evalsm(kNPAR);
708 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
709 // TMatrixD evecs = eigen.GetEigenVectors();
710 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
713 if(!(arr = (TObjArray*)fContainer->At(kMCtrackIn))) {
714 AliWarning("No MC container defined.");
718 // y resolution/pulls
719 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
720 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], (PARMC[0]-PAR[0])/TMath::Sqrt(COV(0,0)), (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)));
721 // z resolution/pulls
722 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
723 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
724 // phi resolution/snp pulls
725 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
726 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
727 // theta resolution/tgl pulls
728 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
729 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
730 // pt resolution\\1/pt pulls\\p resolution/pull
731 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
732 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
734 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
735 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
736 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
738 // p*p*PAR[4]*PAR[4]*COV(4,4)
739 // +2.*PAR[3]*COV(3,4)/PAR[4]
740 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
741 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
745 (*DebugStream()) << "trackInMC"
752 //________________________________________________________
753 TH1* AliTRDresolution::PlotTrackOut(const AliTRDtrackV1 *track)
755 // Store resolution/pulls of Kalman after last update with the TRD information
756 // at the radial position of the first tracklet. The following points are used
758 // - the (y,z,snp) of the first TRD tracklet
759 // - the (y, z, snp, tgl, pt) of the MC track reference
761 // Additionally the momentum resolution/pulls are calculated for usage in the
764 if(track) fkTrack = track;
766 AliDebug(4, "No Track defined.");
769 TObjArray *arr = NULL;
770 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackOut))){
771 AliWarning("No output container defined.");
774 AliExternalTrackParam *tout = NULL;
775 if(!(tout = fkTrack->GetTrackOut())){
776 AliDebug(2, "Track did not exit TRD.");
781 Double_t x = tout->GetX();
782 AliTRDseedV1 *fTracklet(NULL);
783 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
784 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
787 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
788 AliWarning("Tracklet did not match Track position.");
792 sgm[2] = fTracklet->GetDetector();
793 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
794 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
795 Double_t tilt(fTracklet->GetTilt())
798 ,cost(TMath::Sqrt(corr));
799 Bool_t rc(fTracklet->IsRowCross());
801 const Int_t kNPAR(5);
802 Double_t parR[kNPAR]; memcpy(parR, tout->GetParameter(), kNPAR*sizeof(Double_t));
803 Double_t covR[3*kNPAR]; memcpy(covR, tout->GetCovariance(), 3*kNPAR*sizeof(Double_t));
804 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
806 // define sum covariances
807 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
808 Double_t *pc = &covR[0], *pp = &parR[0];
809 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
811 for(Int_t ic = 0; ic<=ir; ic++,pc++){
812 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
815 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
816 //COV.Print(); PAR.Print();
818 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
819 Double_t dy[3]={parR[0] - fTracklet->GetY(), 0., 0.}
820 ,dz[3]={parR[1] - fTracklet->GetZ(), 0., 0.}
821 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
822 // calculate residuals using tilt rotation
823 dy[1] = cost*(dy[0] - dz[0]*tilt);
824 dz[1] = cost*(dz[0] + dy[0]*tilt);
826 if(1./PAR[4]>fPtThreshold) ((TH3S*)arr->At(0))->Fill(fTracklet->GetYref(1), 1.e2*dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]); // scale to fit general residual range !!!
827 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
828 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
830 Double_t dyz[2] = {dy[1], dz[1]};
831 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
832 Pulls(dyz, cc, tilt);
833 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
834 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
836 // register reference histo for mini-task
837 h = (TH2I*)arr->At(0);
840 (*DebugStream()) << "trackOut"
846 Double_t y = fTracklet->GetY();
847 Double_t z = fTracklet->GetZ();
848 (*DebugStream()) << "trackletOut"
858 if(!HasMCdata()) return h;
860 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
861 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
862 Int_t pdg = fkMC->GetPDG(),
863 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
865 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
866 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
867 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
869 // translate to reference radial position
870 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
871 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
873 TVectorD PARMC(kNPAR);
874 PARMC[0]=y0; PARMC[1]=z0;
875 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
878 // TMatrixDSymEigen eigen(COV);
879 // TVectorD evals = eigen.GetEigenValues();
880 // TMatrixDSym evalsm(kNPAR);
881 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
882 // TMatrixD evecs = eigen.GetEigenVectors();
883 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
886 if(!(arr = (TObjArray*)fContainer->At(kMCtrackOut))){
887 AliWarning("No MC container defined.");
890 // y resolution/pulls
891 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
892 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], (PARMC[0]-PAR[0])/TMath::Sqrt(COV(0,0)), (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)));
893 // z resolution/pulls
894 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
895 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
896 // phi resolution/snp pulls
897 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
898 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
899 // theta resolution/tgl pulls
900 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
901 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
902 // pt resolution\\1/pt pulls\\p resolution/pull
903 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
904 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
906 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
907 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
908 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
910 // p*p*PAR[4]*PAR[4]*COV(4,4)
911 // +2.*PAR[3]*COV(3,4)/PAR[4]
912 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
913 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
917 (*DebugStream()) << "trackOutMC"
924 //________________________________________________________
925 TH1* AliTRDresolution::PlotMC(const AliTRDtrackV1 *track)
928 // Plot MC distributions
932 AliDebug(2, "No MC defined. Results will not be available.");
935 if(track) fkTrack = track;
937 AliDebug(4, "No Track defined.");
941 AliWarning("No output container defined.");
944 // retriev track characteristics
945 Int_t pdg = fkMC->GetPDG(),
946 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
949 label(fkMC->GetLabel());
950 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
951 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
952 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
954 TObjArray *arr(NULL);TH1 *h(NULL);
956 Double_t xAnode, x, y, z, pt, dydx, dzdx, dzdl;
957 Float_t pt0, x0, y0, z0, dx, dy, dz, dydx0, dzdx0;
958 Double_t covR[7]/*, cov[3]*/;
961 TVectorD dX(12), dY(12), dZ(12), vPt(12), dPt(12), cCOV(12*15);
962 fkMC->PropagateKalman(&dX, &dY, &dZ, &vPt, &dPt, &cCOV);
963 (*DebugStream()) << "MCkalman"
973 AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
974 AliTRDseedV1 *fTracklet(NULL); TObjArray *clInfoArr(NULL);
975 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
976 if(!(fTracklet = fkTrack->GetTracklet(ily)))/* ||
977 !fTracklet->IsOK())*/ continue;
979 sgm[2] = fTracklet->GetDetector();
980 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
981 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
982 Double_t tilt(fTracklet->GetTilt())
985 ,cost(TMath::Sqrt(corr));
986 x0 = fTracklet->GetX0();
987 //radial shift with respect to the MC reference (radial position of the pad plane)
988 x= fTracklet->GetX();
989 Bool_t rc(fTracklet->IsRowCross());
990 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
991 xAnode = fTracklet->GetX0();
993 // MC track position at reference radial position
996 (*DebugStream()) << "MC"
1008 Float_t ymc = y0 - dx*dydx0;
1009 Float_t zmc = z0 - dx*dzdx0;
1010 //p = pt0*TMath::Sqrt(1.+dzdx0*dzdx0); // pt -> p
1012 // Kalman position at reference radial position
1014 dydx = fTracklet->GetYref(1);
1015 dzdx = fTracklet->GetZref(1);
1016 dzdl = fTracklet->GetTgl();
1017 y = fTracklet->GetYref(0) - dx*dydx;
1019 z = fTracklet->GetZref(0) - dx*dzdx;
1021 pt = TMath::Abs(fTracklet->GetPt());
1022 fTracklet->GetCovRef(covR);
1024 arr = (TObjArray*)((TObjArray*)fContainer->At(kMCtrack))->At(ily);
1025 // y resolution/pulls
1026 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1027 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(covR[0]), dz/TMath::Sqrt(covR[2]));
1028 // z resolution/pulls
1029 ((TH3S*)arr->At(2))->Fill(dzdx0, dz, 0);
1030 ((TH3S*)arr->At(3))->Fill(dzdx0, dz/TMath::Sqrt(covR[2]), 0);
1031 // phi resolution/ snp pulls
1032 Double_t dtgp = (dydx - dydx0)/(1.- dydx*dydx0);
1033 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dtgp));
1034 Double_t dsnp = dydx/TMath::Sqrt(1.+dydx*dydx) - dydx0/TMath::Sqrt(1.+dydx0*dydx0);
1035 ((TH2I*)arr->At(5))->Fill(dydx0, dsnp/TMath::Sqrt(covR[3]));
1036 // theta resolution/ tgl pulls
1037 Double_t dzdl0 = dzdx0/TMath::Sqrt(1.+dydx0*dydx0),
1038 dtgl = (dzdl - dzdl0)/(1.- dzdl*dzdl0);
1039 ((TH2I*)arr->At(6))->Fill(dzdl0,
1041 ((TH2I*)arr->At(7))->Fill(dzdl0, (dzdl - dzdl0)/TMath::Sqrt(covR[4]));
1042 // pt resolution \\ 1/pt pulls \\ p resolution for PID
1043 Double_t p0 = TMath::Sqrt(1.+ dzdl0*dzdl0)*pt0,
1044 p = TMath::Sqrt(1.+ dzdl*dzdl)*pt;
1045 ((TH3S*)((TObjArray*)arr->At(8)))->Fill(pt0, pt/pt0-1., sign*sIdx);
1046 ((TH3S*)((TObjArray*)arr->At(9)))->Fill(1./pt0, (1./pt-1./pt0)/TMath::Sqrt(covR[6]), sign*sIdx);
1047 ((TH3S*)((TObjArray*)arr->At(10)))->Fill(p0, p/p0-1., sign*sIdx);
1049 // Fill Debug stream for Kalman track
1050 if(DebugLevel()>=4){
1051 (*DebugStream()) << "MCtrack"
1058 << "s2y=" << covR[0]
1059 << "s2z=" << covR[2]
1063 // recalculate tracklet based on the MC info
1064 AliTRDseedV1 tt(*fTracklet);
1065 tt.SetZref(0, z0 - (x0-xAnode)*dzdx0);
1066 tt.SetZref(1, dzdx0);
1067 tt.SetReconstructor(AliTRDinfoGen::Reconstructor());
1069 x= tt.GetX();y= tt.GetY();z= tt.GetZ();
1070 dydx = tt.GetYfit(1);
1072 ymc = y0 - dx*dydx0;
1073 zmc = z0 - dx*dzdx0;
1076 Float_t dphi = (dydx - dydx0);
1077 dphi /= (1.- dydx*dydx0);
1079 // add tracklet residuals for y and dydx
1080 arr = (TObjArray*)fContainer->At(kMCtracklet);
1082 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1083 if(tt.GetS2Y()>0. && tt.GetS2Z()>0.) ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(tt.GetS2Y()), dz/TMath::Sqrt(tt.GetS2Z()));
1084 ((TH3S*)arr->At(2))->Fill(dzdl0, dz, rc);
1085 if(tt.GetS2Z()>0.) ((TH3S*)arr->At(3))->Fill(dzdl0, dz/TMath::Sqrt(tt.GetS2Z()), rc);
1086 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dphi));
1088 // Fill Debug stream for tracklet
1089 if(DebugLevel()>=4){
1090 Float_t s2y = tt.GetS2Y();
1091 Float_t s2z = tt.GetS2Z();
1092 (*DebugStream()) << "MCtracklet"
1103 AliTRDpadPlane *pp = geo->GetPadPlane(ily, AliTRDgeometry::GetStack(sgm[2]));
1104 Float_t zr0 = pp->GetRow0() + pp->GetAnodeWireOffset();
1105 //Double_t exb = AliTRDCommonParam::Instance()->GetOmegaTau(1.5);
1107 arr = (TObjArray*)fContainer->At(kMCcluster);
1108 AliTRDcluster *c = NULL;
1109 tt.ResetClusterIter(kFALSE);
1110 while((c = tt.PrevCluster())){
1111 Float_t q = TMath::Abs(c->GetQ());
1112 x = c->GetX()+fXcorr[c->GetDetector()][c->GetLocalTimeBin()]; y = c->GetY();z = c->GetZ();
1116 dy = cost*(y - ymc - tilt*(z-zmc));
1117 dz = cost*(z - zmc + tilt*(y-ymc));
1120 if(q>20. && q<250. && pt0>fPtThreshold && c->IsInChamber()){
1121 ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1122 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(c->GetSigmaY2()), dz/TMath::Sqrt(c->GetSigmaZ2()));
1125 // Fill calibration container
1126 Float_t d = zr0 - zmc;
1127 d -= ((Int_t)(2 * d)) / 2.0;
1128 if (d > 0.25) d = 0.5 - d;
1129 AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
1130 clInfo->SetCluster(c);
1131 clInfo->SetMC(pdg, label);
1132 clInfo->SetGlobalPosition(ymc, zmc, dydx0, dzdx0);
1133 clInfo->SetResolution(dy);
1134 clInfo->SetAnisochronity(d);
1135 clInfo->SetDriftLength(dx);
1136 clInfo->SetTilt(tilt);
1137 if(fMCcl) fMCcl->Add(clInfo);
1138 else AliDebug(1, "MCcl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
1139 if(DebugLevel()>=5){
1141 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
1142 clInfoArr->SetOwner(kFALSE);
1144 clInfoArr->Add(clInfo);
1148 if(DebugLevel()>=5 && clInfoArr){
1149 (*DebugStream()) << "MCcluster"
1150 <<"clInfo.=" << clInfoArr
1155 if(clInfoArr) delete clInfoArr;
1160 //________________________________________________________
1161 Bool_t AliTRDresolution::GetRefFigure(Int_t ifig)
1164 // Get the reference figures
1167 Float_t xy[4] = {0., 0., 0., 0.};
1169 AliWarning("Please provide a canvas to draw results.");
1172 Int_t selection[100], n(0), selStart(0); //
1173 Int_t ly0(0), dly(5);
1174 //Int_t ly0(1), dly(2); // used for SA
1175 TList *l(NULL); TVirtualPad *pad(NULL);
1176 TGraphErrors *g(NULL);TGraphAsymmErrors *ga(NULL);
1178 case 0: // charge resolution
1179 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1180 ((TVirtualPad*)l->At(0))->cd();
1181 ga=((TGraphAsymmErrors*)((TObjArray*)fGraphM->At(kCharge))->At(0));
1182 if(ga->GetN()) ga->Draw("apl");
1183 ((TVirtualPad*)l->At(1))->cd();
1184 g = ((TGraphErrors*)((TObjArray*)fGraphS->At(kCharge))->At(0));
1185 if(g->GetN()) g->Draw("apl");
1187 case 1: // cluster2track residuals
1188 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1189 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1190 pad = (TVirtualPad*)l->At(0); pad->cd();
1191 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1192 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1193 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1194 pad=(TVirtualPad*)l->At(1); pad->cd();
1195 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1196 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1197 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1199 case 2: // cluster2track residuals
1200 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1201 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1202 pad = (TVirtualPad*)l->At(0); pad->cd();
1203 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1204 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1205 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1206 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-0.5; xy[3] = 2.5;
1207 pad=(TVirtualPad*)l->At(1); pad->cd();
1208 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1209 if(!GetGraphArray(xy, kCluster, 1, 1)) break;
1212 gPad->Divide(3, 2, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1213 xy[0] = -.3; xy[1] = -20.; xy[2] = .3; xy[3] = 100.;
1214 ((TVirtualPad*)l->At(0))->cd();
1215 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1216 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1218 ((TVirtualPad*)l->At(1))->cd();
1219 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1220 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1222 ((TVirtualPad*)l->At(2))->cd();
1223 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1224 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1226 ((TVirtualPad*)l->At(3))->cd();
1227 selStart=fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1228 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1230 ((TVirtualPad*)l->At(4))->cd();
1231 selStart=fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1232 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1234 ((TVirtualPad*)l->At(5))->cd();
1235 selStart=2*fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1236 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1239 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1241 xy[0] = -1.; xy[1] = -150.; xy[2] = 1.; xy[3] = 1000.;
1242 ((TVirtualPad*)l->At(0))->cd();
1244 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1246 xy[0] = -1.; xy[1] = -1500.; xy[2] = 1.; xy[3] = 10000.;
1247 ((TVirtualPad*)l->At(1))->cd();
1249 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1252 case 5: // kTrack pulls
1253 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1255 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1256 ((TVirtualPad*)l->At(0))->cd();
1257 if(!GetGraphArray(xy, kTrack, 1, 1)) break;
1259 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1260 ((TVirtualPad*)l->At(1))->cd();
1261 if(!GetGraphArray(xy, kTrack, 3, 1)) break;
1263 case 6: // kTrack phi
1264 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1265 if(GetGraph(&xy[0], kTrack , 4)) return kTRUE;
1267 case 7: // kTrackIn y
1268 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1269 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1270 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1271 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1272 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1273 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1274 pad=((TVirtualPad*)l->At(1)); pad->cd();
1275 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1276 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1277 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1279 case 8: // kTrackIn y
1280 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1281 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1282 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1283 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1284 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1285 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1286 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1287 pad=((TVirtualPad*)l->At(1)); pad->cd();
1288 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1289 if(!GetGraphArray(xy, kTrackIn, 1, 1)) break;
1291 case 9: // kTrackIn z
1292 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1293 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1294 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1295 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1297 if(!GetGraphArray(xy, kTrackIn, 2, 1, 1, selection)) break;
1298 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1299 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1300 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1301 if(!GetGraphArray(xy, kTrackIn, 3, 1)) break;
1303 case 10: // kTrackIn phi
1304 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1305 if(GetGraph(&xy[0], kTrackIn, 4)) return kTRUE;
1307 case 11: // kTrackOut y
1308 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1309 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1310 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1311 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1312 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1313 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1314 pad=((TVirtualPad*)l->At(1)); pad->cd();
1315 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1316 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1317 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1319 case 12: // kTrackOut y
1320 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1321 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1322 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1323 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1324 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1325 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1326 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1327 pad=((TVirtualPad*)l->At(1)); pad->cd();
1328 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1329 if(!GetGraphArray(xy, kTrackOut, 1, 1)) break;
1331 case 13: // kTrackOut z
1332 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1333 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1334 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1335 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1336 if(!GetGraphArray(xy, kTrackOut, 2, 1)) break;
1337 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1338 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1339 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1340 if(!GetGraphArray(xy, kTrackOut, 3, 1)) break;
1342 case 14: // kTrackOut phi
1343 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1344 if(GetGraph(&xy[0], kTrackOut, 4)) return kTRUE;
1346 case 15: // kMCcluster
1347 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1348 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1349 ((TVirtualPad*)l->At(0))->cd();
1350 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1351 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1352 ((TVirtualPad*)l->At(1))->cd();
1353 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1354 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1356 case 16: // kMCcluster
1357 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1358 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1359 ((TVirtualPad*)l->At(0))->cd();
1360 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1361 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1362 ((TVirtualPad*)l->At(1))->cd();
1363 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1364 if(!GetGraphArray(xy, kMCcluster, 1, 1)) break;
1366 case 17: //kMCtracklet [y]
1367 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1368 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1369 ((TVirtualPad*)l->At(0))->cd();
1370 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1371 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1372 ((TVirtualPad*)l->At(1))->cd();
1373 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1374 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1376 case 18: //kMCtracklet [y]
1377 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1378 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1379 ((TVirtualPad*)l->At(0))->cd();
1380 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1381 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1382 ((TVirtualPad*)l->At(1))->cd();
1383 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1384 if(!GetGraphArray(xy, kMCtracklet, 1, 1)) break;
1386 case 19: //kMCtracklet [z]
1387 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1388 xy[0]=-1.; xy[1]=-100.; xy[2]=1.; xy[3] =2500.;
1389 ((TVirtualPad*)l->At(0))->cd();
1390 if(!GetGraphArray(xy, kMCtracklet, 2)) break;
1391 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1392 ((TVirtualPad*)l->At(1))->cd();
1393 if(!GetGraphArray(xy, kMCtracklet, 3)) break;
1395 case 20: //kMCtracklet [phi]
1396 xy[0]=-.3; xy[1]=-3.; xy[2]=.3; xy[3] =25.;
1397 if(!GetGraph(&xy[0], kMCtracklet, 4)) break;
1399 case 21: //kMCtrack [y] ly [0]
1400 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1401 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1402 ((TVirtualPad*)l->At(0))->cd();
1403 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1404 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1405 ((TVirtualPad*)l->At(1))->cd();
1406 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1407 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1409 case 22: //kMCtrack [y] ly [1]
1410 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1411 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1412 ((TVirtualPad*)l->At(0))->cd();
1413 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1414 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1415 ((TVirtualPad*)l->At(1))->cd();
1416 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1417 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1419 case 23: //kMCtrack [y] ly [2]
1420 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1421 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1422 ((TVirtualPad*)l->At(0))->cd();
1423 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1424 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1425 ((TVirtualPad*)l->At(1))->cd();
1426 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1427 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1429 case 24: //kMCtrack [y] ly [3]
1430 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1431 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1432 ((TVirtualPad*)l->At(0))->cd();
1433 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1434 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1435 ((TVirtualPad*)l->At(1))->cd();
1436 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1437 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1439 case 25: //kMCtrack [y] ly [4]
1440 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1441 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1442 ((TVirtualPad*)l->At(0))->cd();
1443 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1444 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1445 ((TVirtualPad*)l->At(1))->cd();
1446 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1447 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1449 case 26: //kMCtrack [y] ly [5]
1450 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1451 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1452 ((TVirtualPad*)l->At(0))->cd();
1453 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1454 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1455 ((TVirtualPad*)l->At(1))->cd();
1456 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1457 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1459 case 27: //kMCtrack [y pulls]
1460 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1461 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 5.5;
1462 ((TVirtualPad*)l->At(0))->cd();
1463 selStart=0; for(n=0; n<6; n++) selection[n]=selStart+n;
1464 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1465 ((TVirtualPad*)l->At(1))->cd();
1466 selStart=6; for(n=0; n<6; n++) selection[n]=selStart+n;
1467 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1469 case 28: //kMCtrack [z]
1470 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1471 xy[0]=-1.; xy[1]=-1500.; xy[2]=1.; xy[3] =6000.;
1472 ((TVirtualPad*)l->At(0))->cd();
1473 if(!GetGraphArray(xy, kMCtrack, 2)) break;
1474 xy[0] = -1.; xy[1] = -1.5; xy[2] = 1.; xy[3] = 5.;
1475 ((TVirtualPad*)l->At(1))->cd();
1476 if(!GetGraphArray(xy, kMCtrack, 3)) break;
1478 case 29: //kMCtrack [phi/snp]
1479 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1480 xy[0]=-.2; xy[1]=-0.5; xy[2]=.2; xy[3] =10.;
1481 ((TVirtualPad*)l->At(0))->cd();
1482 if(!GetGraphArray(xy, kMCtrack, 4)) break;
1483 xy[0] = -.2; xy[1] = -1.5; xy[2] = .2; xy[3] = 5.;
1484 ((TVirtualPad*)l->At(1))->cd();
1485 if(!GetGraphArray(xy, kMCtrack, 5)) break;
1487 case 30: //kMCtrack [theta/tgl]
1488 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1489 xy[0]=-1.; xy[1]=-0.5; xy[2]=1.; xy[3] =5.;
1490 ((TVirtualPad*)l->At(0))->cd();
1491 if(!GetGraphArray(xy, kMCtrack, 6)) break;
1492 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
1493 ((TVirtualPad*)l->At(1))->cd();
1494 if(!GetGraphArray(xy, kMCtrack, 7)) break;
1496 case 31: //kMCtrack [pt]
1497 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1498 pad = (TVirtualPad*)l->At(0); pad->cd();
1499 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1502 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1503 selection[n++] = il*11 + 2; // pi-
1504 selection[n++] = il*11 + 8; // pi+
1506 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1507 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1508 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#pi#pm")) break;
1509 pad->Modified(); pad->Update(); pad->SetLogx();
1510 pad = (TVirtualPad*)l->At(1); pad->cd();
1511 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1514 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1515 selection[n++] = il*11 + 3; // mu-
1516 selection[n++] = il*11 + 7; // mu+
1518 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#mu#pm")) break;
1519 pad->Modified(); pad->Update(); pad->SetLogx();
1521 case 32: //kMCtrack [pt]
1522 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1523 pad = (TVirtualPad*)l->At(0); pad->cd();
1524 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1527 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1528 selection[n++] = il*11 + 0; // p bar
1529 selection[n++] = il*11 + 10; // p
1531 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1532 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1533 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "p&p bar")) break;
1534 pad->Modified(); pad->Update(); pad->SetLogx();
1535 pad = (TVirtualPad*)l->At(1); pad->cd();
1536 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1539 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1540 selection[n++] = il*11 + 4; // e-
1541 selection[n++] = il*11 + 6; // e+
1543 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1544 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1545 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "e#pm")) break;
1546 pad->Modified(); pad->Update(); pad->SetLogx();
1548 case 33: //kMCtrack [1/pt] pulls
1549 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1550 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 4.5; // SA
1551 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1552 pad = (TVirtualPad*)l->At(0); pad->cd();
1553 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1556 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1557 selection[n++] = il*11 + 2; // pi-
1558 selection[n++] = il*11 + 8; // pi+
1560 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#pi#pm")) break;
1561 pad = (TVirtualPad*)l->At(1); pad->cd();
1562 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1565 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1566 selection[n++] = il*11 + 3; // mu-
1567 selection[n++] = il*11 + 7; // mu+
1569 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#mu#pm")) break;
1571 case 34: //kMCtrack [1/pt] pulls
1572 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1573 pad = (TVirtualPad*)l->At(0); pad->cd();
1574 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1577 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1578 selection[n++] = il*11 + 0; // p bar
1579 selection[n++] = il*11 + 10; // p
1581 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1582 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 6.; // SA
1583 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "p & p bar")) break;
1584 pad = (TVirtualPad*)l->At(1); pad->cd();
1585 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1588 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1589 selection[n++] = il*11 + 4; // e-
1590 selection[n++] = il*11 + 6; // e+
1592 xy[0] = 0.; xy[1] = -2.; xy[2] = 2.; xy[3] = 4.5;
1593 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "e#pm")) break;
1595 case 35: //kMCtrack [p]
1596 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1597 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1598 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1599 pad = (TVirtualPad*)l->At(0); pad->cd();
1600 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1603 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1604 selection[n++] = il*11 + 2; // pi-
1605 selection[n++] = il*11 + 8; // pi+
1607 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#pi#pm")) break;
1608 pad->Modified(); pad->Update(); pad->SetLogx();
1609 pad = (TVirtualPad*)l->At(1); pad->cd();
1610 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1613 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1614 selection[n++] = il*11 + 3; // mu-
1615 selection[n++] = il*11 + 7; // mu+
1617 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#mu#pm")) break;
1618 pad->Modified(); pad->Update(); pad->SetLogx();
1620 case 36: //kMCtrack [p]
1621 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1622 pad = (TVirtualPad*)l->At(0); pad->cd();
1623 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1626 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1627 selection[n++] = il*11 + 0; // p bar
1628 selection[n++] = il*11 + 10; // p
1630 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1631 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.; // SA
1632 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "p & p bar")) break;
1633 pad->Modified(); pad->Update(); pad->SetLogx();
1634 pad = (TVirtualPad*)l->At(1); pad->cd();
1635 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1638 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1639 selection[n++] = il*11 + 4; // e-
1640 selection[n++] = il*11 + 6; // e+
1642 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1643 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1644 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "e#pm")) break;
1645 pad->Modified(); pad->Update(); pad->SetLogx();
1647 case 37: // kMCtrackIn [y]
1648 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1649 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1650 ((TVirtualPad*)l->At(0))->cd();
1651 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1652 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1653 ((TVirtualPad*)l->At(1))->cd();
1654 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1655 if(!GetGraphArray(&xy[0], kMCtrackIn, 0, 1, n, selection)) break;
1657 case 38: // kMCtrackIn [y]
1658 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1659 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1660 ((TVirtualPad*)l->At(0))->cd();
1661 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1662 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1663 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1664 ((TVirtualPad*)l->At(1))->cd();
1665 if(!GetGraphArray(xy, kMCtrackIn, 1, 1)) break;
1667 case 39: // kMCtrackIn [z]
1668 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1669 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =800.;
1670 ((TVirtualPad*)l->At(0))->cd();
1671 if(!GetGraphArray(xy, kMCtrackIn, 2, 1)) break;
1672 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1673 ((TVirtualPad*)l->At(1))->cd();
1674 if(!GetGraphArray(xy, kMCtrackIn, 3, 1)) break;
1676 case 40: // kMCtrackIn [phi|snp]
1677 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1678 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1679 ((TVirtualPad*)l->At(0))->cd();
1680 if(!GetGraph(&xy[0], kMCtrackIn, 4)) break;
1681 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1682 ((TVirtualPad*)l->At(1))->cd();
1683 if(!GetGraph(&xy[0], kMCtrackIn, 5)) break;
1685 case 41: // kMCtrackIn [theta|tgl]
1686 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1687 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1688 ((TVirtualPad*)l->At(0))->cd();
1689 if(!GetGraph(&xy[0], kMCtrackIn, 6)) break;
1690 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 1.5;
1691 ((TVirtualPad*)l->At(1))->cd();
1692 if(!GetGraph(&xy[0], kMCtrackIn, 7)) break;
1694 case 42: // kMCtrackIn [pt]
1695 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1696 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1697 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.; // SA
1698 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1699 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1700 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1701 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1702 pad = (TVirtualPad*)l->At(1); pad->cd(); pad->SetLogx();
1703 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1704 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1705 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1707 case 43: //kMCtrackIn [1/pt] pulls
1708 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1709 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1710 pad = (TVirtualPad*)l->At(0); pad->cd();
1711 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1712 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1713 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1714 pad = (TVirtualPad*)l->At(1); pad->cd();
1715 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1716 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1717 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1719 case 44: // kMCtrackIn [p]
1720 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1721 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1722 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1723 pad = ((TVirtualPad*)l->At(0));pad->cd();pad->SetLogx();
1724 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1725 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1726 if(!GetGraphArray(xy, kMCtrackIn, 10, 1, n, selection)) break;
1727 pad = ((TVirtualPad*)l->At(1)); pad->cd();pad->SetLogx();
1728 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1729 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1730 if(!GetGraphArray(xy, kMCtrackIn, 10, 1, n, selection)) break;
1732 case 45: // kMCtrackOut [y]
1733 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1734 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1735 ((TVirtualPad*)l->At(0))->cd();
1736 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1737 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1738 ((TVirtualPad*)l->At(1))->cd();
1739 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1740 if(!GetGraphArray(&xy[0], kMCtrackOut, 0, 1, n, selection)) break;
1742 case 46: // kMCtrackOut [y]
1743 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1744 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1745 ((TVirtualPad*)l->At(0))->cd();
1746 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1747 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1748 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1749 ((TVirtualPad*)l->At(1))->cd();
1750 if(!GetGraphArray(xy, kMCtrackOut, 1, 1)) break;
1752 case 47: // kMCtrackOut [z]
1753 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1754 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =1500.;
1755 ((TVirtualPad*)l->At(0))->cd();
1756 if(!GetGraphArray(xy, kMCtrackOut, 2, 1)) break;
1757 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1758 ((TVirtualPad*)l->At(1))->cd();
1759 if(!GetGraphArray(xy, kMCtrackOut, 3, 1)) break;
1761 case 48: // kMCtrackOut [phi|snp]
1762 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1763 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1764 ((TVirtualPad*)l->At(0))->cd();
1765 if(!GetGraph(&xy[0], kMCtrackOut, 4)) break;
1766 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1767 ((TVirtualPad*)l->At(1))->cd();
1768 if(!GetGraph(&xy[0], kMCtrackOut, 5)) break;
1770 case 49: // kMCtrackOut [theta|tgl]
1771 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1772 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1773 ((TVirtualPad*)l->At(0))->cd();
1774 if(!GetGraph(&xy[0], kMCtrackOut, 6)) break;
1775 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 15.;
1776 ((TVirtualPad*)l->At(1))->cd();
1777 if(!GetGraph(&xy[0], kMCtrackOut, 7)) break;
1779 case 50: // kMCtrackOut [pt]
1780 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1781 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1782 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1783 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1784 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1785 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1786 pad = (TVirtualPad*)l->At(1); pad->cd();pad->SetLogx();
1787 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1788 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1789 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1791 case 51: //kMCtrackOut [1/pt] pulls
1792 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1793 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1794 pad = (TVirtualPad*)l->At(0); pad->cd();
1795 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1796 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1797 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1798 pad = (TVirtualPad*)l->At(1); pad->cd();
1799 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1800 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1801 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1803 case 52: // kMCtrackOut [p]
1804 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1805 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1806 pad = ((TVirtualPad*)l->At(0));pad->cd();pad->SetLogx();
1807 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1808 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1809 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1810 pad = ((TVirtualPad*)l->At(1)); pad->cd();pad->SetLogx();
1811 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1812 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1813 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1816 AliWarning(Form("Reference plot [%d] missing result", ifig));
1820 //________________________________________________________
1821 void AliTRDresolution::MakeSummary()
1823 // Build summary plots
1825 if(!fGraphS || !fGraphM){
1826 AliError("Missing results");
1829 Float_t xy[4] = {0., 0., 0., 0.};
1831 TH2 *h2 = new TH2I("h2SF", "", 20, -.2, .2, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5);
1832 h2->GetXaxis()->CenterTitle();
1833 h2->GetYaxis()->CenterTitle();
1834 h2->GetZaxis()->CenterTitle();h2->GetZaxis()->SetTitleOffset(1.4);
1836 Int_t ih2(0), iSumPlot(0);
1837 TCanvas *cOut = new TCanvas(Form("TRDsummary%s_%d", GetName(), iSumPlot++), "Cluster & Tracklet Resolution", 1024, 768);
1838 cOut->Divide(3,2, 2.e-3, 2.e-3, kYellow-7);
1839 TVirtualPad *p(NULL);
1842 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1843 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1844 h2->SetTitle(Form("Cluster-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1845 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kCluster))->At(0), h2);
1846 GetRange(h2, 1, range);
1847 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1852 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1853 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1854 h2->SetTitle(Form("Cluster-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1855 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kCluster))->At(0), h2);
1856 GetRange(h2, 0, range);
1857 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1862 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1863 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1864 if(!GetGraphArray(xy, kCluster, 1, 1)) return;
1867 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1868 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1869 h2->SetTitle(Form("Tracklet-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1870 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kTrack))->At(0), h2);
1871 GetRange(h2, 1, range);
1872 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1877 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1878 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1879 h2->SetTitle(Form("Tracklet-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1880 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kTrack))->At(0), h2);
1881 GetRange(h2, 0, range);
1882 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1887 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1888 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1889 if(!GetGraphArray(xy, kTrack, 1, 1)) return;
1891 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1894 (!fGraphS->At(kMCcluster) || !fGraphM->At(kMCcluster) ||
1895 !fGraphS->At(kMCtracklet) || !fGraphM->At(kMCtracklet))){
1899 cOut->Clear(); cOut->SetName(Form("TRDsummary%s_%d", GetName(), iSumPlot++));
1900 cOut->Divide(3, 2, 2.e-3, 2.e-3, kBlue-10);
1903 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1904 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1905 h2->SetTitle(Form("Cluster-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1906 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCcluster))->At(0), h2);
1907 GetRange(h2, 1, range);
1908 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1913 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1914 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1916 h2->SetTitle(Form("Cluster-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1917 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCcluster))->At(0), h2);
1918 GetRange(h2, 0, range);
1919 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1924 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1925 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1926 if(!GetGraphArray(xy, kMCcluster, 1, 1)) AliWarning("Missing MC cluster plot.");
1929 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1930 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1932 h2->SetTitle(Form("Tracklet-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1933 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCtracklet))->At(0), h2);
1934 GetRange(h2, 1, range);
1935 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1940 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1941 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1943 h2->SetTitle(Form("Tracklet-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1944 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCtracklet))->At(0), h2);
1945 GetRange(h2, 0, range);
1946 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1951 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1952 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1953 GetGraphArray(xy, kMCtracklet, 1, 1);
1955 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1959 //________________________________________________________
1960 void AliTRDresolution::GetRange(TH2 *h2, Char_t mod, Float_t *range)
1962 // Returns the range of the bulk of data in histogram h2. Removes outliers.
1963 // The "range" vector should be initialized with 2 elements
1964 // Option "mod" can be any of
1965 // - 0 : gaussian like distribution
1966 // - 1 : tailed distribution
1968 Int_t nx(h2->GetNbinsX())
1969 , ny(h2->GetNbinsY())
1971 Double_t *data=new Double_t[n];
1972 for(Int_t ix(1), in(0); ix<=nx; ix++){
1973 for(Int_t iy(1); iy<=ny; iy++)
1974 data[in++] = h2->GetBinContent(ix, iy);
1976 Double_t mean, sigm;
1977 AliMathBase::EvaluateUni(n, data, mean, sigm, Int_t(n*.8));
1979 range[0]=mean-3.*sigm; range[1]=mean+3.*sigm;
1980 if(mod==1) range[0]=TMath::Max(Float_t(1.e-3), range[0]);
1981 AliDebug(2, Form("h[%s] range0[%f %f]", h2->GetName(), range[0], range[1]));
1982 TH1S h1("h1SF0", "", 100, range[0], range[1]);
1987 case 0:// gaussian distribution
1989 TF1 fg("fg", "gaus", mean-3.*sigm, mean+3.*sigm);
1991 mean=fg.GetParameter(1); sigm=fg.GetParameter(2);
1992 range[0] = mean-2.5*sigm;range[1] = mean+2.5*sigm;
1993 AliDebug(2, Form(" rangeG[%f %f]", range[0], range[1]));
1996 case 1:// tailed distribution
1998 Int_t bmax(h1.GetMaximumBin());
1999 Int_t jBinMin(1), jBinMax(100);
2000 for(Int_t ibin(bmax); ibin--;){
2001 if(h1.GetBinContent(ibin)<1.){
2002 jBinMin=ibin; break;
2005 for(Int_t ibin(bmax); ibin++;){
2006 if(h1.GetBinContent(ibin)<1.){
2007 jBinMax=ibin; break;
2010 range[0]=h1.GetBinCenter(jBinMin); range[1]=h1.GetBinCenter(jBinMax);
2011 AliDebug(2, Form(" rangeT[%f %f]", range[0], range[1]));
2019 //________________________________________________________
2020 void AliTRDresolution::MakeSummaryPlot(TObjArray *a, TH2 *h2)
2022 // Core functionality for MakeSummary function.
2026 TGraphErrors *g(NULL); TAxis *ax(h2->GetXaxis());
2027 for(Int_t iseg(0); iseg<fgkNresYsegm[fSegmentLevel]; iseg++){
2028 g=(TGraphErrors*)a->At(iseg);
2029 for(Int_t in(0); in<g->GetN(); in++){
2030 g->GetPoint(in, x, y);
2031 h2->SetBinContent(ax->FindBin(x), iseg+1, y);
2037 //________________________________________________________
2038 Bool_t AliTRDresolution::PostProcess()
2040 // Fit, Project, Combine, Extract values from the containers filled during execution
2042 /*fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));*/
2044 AliError("ERROR: list not available");
2048 // define general behavior parameters
2049 const Color_t fgColorS[11]={
2050 kOrange, kOrange-3, kMagenta+1, kViolet, kRed,
2052 kRed, kViolet, kMagenta+1, kOrange-3, kOrange
2054 const Color_t fgColorM[11]={
2055 kCyan-5, kAzure-4, kBlue-7, kBlue+2, kViolet+10,
2057 kViolet+10, kBlue+2, kBlue-7, kAzure-4, kCyan-5
2059 const Marker_t fgMarker[11]={
2065 TGraph *gm= NULL, *gs= NULL;
2066 if(!fGraphS && !fGraphM){
2067 TObjArray *aM(NULL), *aS(NULL);
2068 Int_t n = fContainer->GetEntriesFast();
2069 fGraphS = new TObjArray(n); fGraphS->SetOwner();
2070 fGraphM = new TObjArray(n); fGraphM->SetOwner();
2071 for(Int_t ig(0), nc(0); ig<n; ig++){
2072 fGraphM->AddAt(aM = new TObjArray(fgNproj[ig]), ig);
2073 fGraphS->AddAt(aS = new TObjArray(fgNproj[ig]), ig);
2075 for(Int_t ic=0; ic<fgNproj[ig]; ic++, nc++){
2076 AliDebug(2, Form("building G[%d] P[%d] N[%d]", ig, ic, fNcomp[nc]));
2078 TObjArray *agS(NULL), *agM(NULL);
2079 aS->AddAt(agS = new TObjArray(fNcomp[nc]), ic);
2080 aM->AddAt(agM = new TObjArray(fNcomp[nc]), ic);
2081 for(Int_t is=fNcomp[nc]; is--;){
2082 agS->AddAt(gs = new TGraphErrors(), is);
2083 Int_t is0(is%11), il0(is/11);
2084 gs->SetMarkerStyle(fgMarker[is0]);
2085 gs->SetMarkerColor(fgColorS[is0]);
2086 gs->SetLineColor(fgColorS[is0]);
2087 gs->SetLineStyle(il0);gs->SetLineWidth(2);
2088 gs->SetName(Form("s_%d_%02d_%02d", ig, ic, is));
2090 agM->AddAt(gm = new TGraphErrors(), is);
2091 gm->SetMarkerStyle(fgMarker[is0]);
2092 gm->SetMarkerColor(fgColorM[is0]);
2093 gm->SetLineColor(fgColorM[is0]);
2094 gm->SetLineStyle(il0);gm->SetLineWidth(2);
2095 gm->SetName(Form("m_%d_%02d_%02d", ig, ic, is));
2096 // this is important for labels in the legend
2098 gs->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2099 gm->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2101 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"z":"y", is/2));
2102 gm->SetTitle(Form("%s Ly[%d]", is%2?"z":"y", is/2));
2103 } else if(ic==2||ic==3) {
2104 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"RC":"no RC", is/2));
2105 gm->SetTitle(Form("%s Ly[%d]", is%2?"RC":"no RC", is/2));
2107 gs->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2108 gm->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2110 gs->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2111 gm->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2115 aS->AddAt(gs = new TGraphErrors(), ic);
2116 gs->SetMarkerStyle(23);
2117 gs->SetMarkerColor(kRed);
2118 gs->SetLineColor(kRed);
2119 gs->SetNameTitle(Form("s_%d_%02d", ig, ic), "sigma");
2121 aM->AddAt(gm = ig ? (TGraph*)new TGraphErrors() : (TGraph*)new TGraphAsymmErrors(), ic);
2122 gm->SetLineColor(kBlack);
2123 gm->SetMarkerStyle(7);
2124 gm->SetMarkerColor(kBlack);
2125 gm->SetNameTitle(Form("m_%d_%02d", ig, ic), "mean");
2131 /* printf("\n\n\n"); fGraphS->ls();
2132 printf("\n\n\n"); fGraphM->ls();*/
2137 TF1 fg("fGauss", "gaus", -.5, .5);
2138 // Landau for charge resolution
2139 TF1 fch("fClCh", "landau", 0., 1000.);
2140 // Landau for e+- pt resolution
2141 TF1 fpt("fPt", "landau", -0.1, 0.2);
2143 //PROCESS EXPERIMENTAL DISTRIBUTIONS
2144 // Charge resolution
2145 //Process3DL(kCharge, 0, &fl);
2146 // Clusters residuals
2147 Process3D(kCluster, 0, &fg, 1.e4);
2148 Process3Dlinked(kCluster, 1, &fg);
2150 // Tracklet residual/pulls
2151 Process3D(kTrack , 0, &fg, 1.e4);
2152 Process3Dlinked(kTrack , 1, &fg);
2153 Process3D(kTrack , 2, &fg, 1.e4);
2154 Process3D(kTrack , 3, &fg);
2155 Process2D(kTrack , 4, &fg, 1.e3);
2157 // TRDin residual/pulls
2158 Process3D(kTrackIn, 0, &fg, 1.e4);
2159 Process3Dlinked(kTrackIn, 1, &fg);
2160 Process3D(kTrackIn, 2, &fg, 1.e4);
2161 Process3D(kTrackIn, 3, &fg);
2162 Process2D(kTrackIn, 4, &fg, 1.e3);
2164 // TRDout residual/pulls
2165 Process3D(kTrackOut, 0, &fg, 1.e3); // scale to fit - see PlotTrackOut
2166 Process3Dlinked(kTrackOut, 1, &fg);
2167 Process3D(kTrackOut, 2, &fg, 1.e4);
2168 Process3D(kTrackOut, 3, &fg);
2169 Process2D(kTrackOut, 4, &fg, 1.e3);
2172 if(!HasMCdata()) return kTRUE;
2175 //PROCESS MC RESIDUAL DISTRIBUTIONS
2177 // CLUSTER Y RESOLUTION/PULLS
2178 Process3D(kMCcluster, 0, &fg, 1.e4);
2179 Process3Dlinked(kMCcluster, 1, &fg, 1.);
2182 // TRACKLET RESOLUTION/PULLS
2183 Process3D(kMCtracklet, 0, &fg, 1.e4); // y
2184 Process3Dlinked(kMCtracklet, 1, &fg, 1.); // y pulls
2185 Process3D(kMCtracklet, 2, &fg, 1.e4); // z
2186 Process3D(kMCtracklet, 3, &fg, 1.); // z pulls
2187 Process2D(kMCtracklet, 4, &fg, 1.e3); // phi
2190 // TRACK RESOLUTION/PULLS
2191 Process3Darray(kMCtrack, 0, &fg, 1.e4); // y
2192 Process3DlinkedArray(kMCtrack, 1, &fg); // y PULL
2193 Process3Darray(kMCtrack, 2, &fg, 1.e4); // z
2194 Process3Darray(kMCtrack, 3, &fg); // z PULL
2195 Process2Darray(kMCtrack, 4, &fg, 1.e3); // phi
2196 Process2Darray(kMCtrack, 5, &fg); // snp PULL
2197 Process2Darray(kMCtrack, 6, &fg, 1.e3); // theta
2198 Process2Darray(kMCtrack, 7, &fg); // tgl PULL
2199 Process3Darray(kMCtrack, 8, &fg, 1.e2); // pt resolution
2200 Process3Darray(kMCtrack, 9, &fg); // 1/pt pulls
2201 Process3Darray(kMCtrack, 10, &fg, 1.e2); // p resolution
2204 // TRACK TRDin RESOLUTION/PULLS
2205 Process3D(kMCtrackIn, 0, &fg, 1.e4);// y resolution
2206 Process3Dlinked(kMCtrackIn, 1, &fg); // y pulls
2207 Process3D(kMCtrackIn, 2, &fg, 1.e4);// z resolution
2208 Process3D(kMCtrackIn, 3, &fg); // z pulls
2209 Process2D(kMCtrackIn, 4, &fg, 1.e3);// phi resolution
2210 Process2D(kMCtrackIn, 5, &fg); // snp pulls
2211 Process2D(kMCtrackIn, 6, &fg, 1.e3);// theta resolution
2212 Process2D(kMCtrackIn, 7, &fg); // tgl pulls
2213 Process3D(kMCtrackIn, 8, &fg, 1.e2);// pt resolution
2214 Process3D(kMCtrackIn, 9, &fg); // 1/pt pulls
2215 Process3D(kMCtrackIn, 10, &fg, 1.e2);// p resolution
2218 // TRACK TRDout RESOLUTION/PULLS
2219 Process3D(kMCtrackOut, 0, &fg, 1.e4);// y resolution
2220 Process3Dlinked(kMCtrackOut, 1, &fg); // y pulls
2221 Process3D(kMCtrackOut, 2, &fg, 1.e4);// z resolution
2222 Process3D(kMCtrackOut, 3, &fg); // z pulls
2223 Process2D(kMCtrackOut, 4, &fg, 1.e3);// phi resolution
2224 Process2D(kMCtrackOut, 5, &fg); // snp pulls
2225 Process2D(kMCtrackOut, 6, &fg, 1.e3);// theta resolution
2226 Process2D(kMCtrackOut, 7, &fg); // tgl pulls
2227 Process3D(kMCtrackOut, 8, &fg, 1.e2);// pt resolution
2228 Process3D(kMCtrackOut, 9, &fg); // 1/pt pulls
2229 Process3D(kMCtrackOut, 10, &fg, 1.e2);// p resolution
2236 //________________________________________________________
2237 void AliTRDresolution::Terminate(Option_t *opt)
2239 AliTRDrecoTask::Terminate(opt);
2240 if(HasPostProcess()) PostProcess();
2243 //________________________________________________________
2244 void AliTRDresolution::AdjustF1(TH1 *h, TF1 *f)
2246 // Helper function to avoid duplication of code
2247 // Make first guesses on the fit parameters
2249 // find the intial parameters of the fit !! (thanks George)
2250 Int_t nbinsy = Int_t(.5*h->GetNbinsX());
2252 for(Int_t jbin=nbinsy-4; jbin<=nbinsy+4; jbin++) sum+=h->GetBinContent(jbin); sum/=9.;
2253 f->SetParLimits(0, 0., 3.*sum);
2254 f->SetParameter(0, .9*sum);
2255 Double_t rms = h->GetRMS();
2256 f->SetParLimits(1, -rms, rms);
2257 f->SetParameter(1, h->GetMean());
2259 f->SetParLimits(2, 0., 2.*rms);
2260 f->SetParameter(2, rms);
2261 if(f->GetNpar() <= 4) return;
2263 f->SetParLimits(3, 0., sum);
2264 f->SetParameter(3, .1*sum);
2266 f->SetParLimits(4, -.3, .3);
2267 f->SetParameter(4, 0.);
2269 f->SetParLimits(5, 0., 1.e2);
2270 f->SetParameter(5, 2.e-1);
2273 //________________________________________________________
2274 TObjArray* AliTRDresolution::BuildMonitorContainerCluster(const char* name, Bool_t expand)
2276 // Build performance histograms for AliTRDcluster.vs TRD track or MC
2277 // - y reziduals/pulls
2279 TObjArray *arr = new TObjArray(2);
2280 arr->SetName(name); arr->SetOwner();
2281 TH1 *h(NULL); char hname[100], htitle[300];
2283 // tracklet resolution/pull in y direction
2284 snprintf(hname, 100, "%s_%s_Y", GetNameId(), name);
2285 snprintf(htitle, 300, "Y res for \"%s\" @ %s;tg(#phi);#Delta y [cm];%s", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2286 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2287 Int_t nybins=fgkNresYsegm[fSegmentLevel];
2288 if(expand) nybins*=2;
2289 h = new TH3S(hname, htitle,
2290 48, -.48, .48, // phi
2291 60, -fDyRange, fDyRange, // dy
2292 nybins, -0.5, nybins-0.5);// segment
2295 snprintf(hname, 100, "%s_%s_YZpull", GetNameId(), name);
2296 snprintf(htitle, 300, "YZ pull for \"%s\" @ %s;%s;#Delta y / #sigma_{y};#Delta z / #sigma_{z}", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2297 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2298 h = new TH3S(hname, htitle, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5, 100, -4.5, 4.5, 100, -4.5, 4.5);
2305 //________________________________________________________
2306 TObjArray* AliTRDresolution::BuildMonitorContainerTracklet(const char* name, Bool_t expand)
2308 // Build performance histograms for AliExternalTrackParam.vs TRD tracklet
2309 // - y reziduals/pulls
2310 // - z reziduals/pulls
2312 TObjArray *arr = BuildMonitorContainerCluster(name, expand);
2314 TH1 *h(NULL); char hname[100], htitle[300];
2316 // tracklet resolution/pull in z direction
2317 snprintf(hname, 100, "%s_%s_Z", GetNameId(), name);
2318 snprintf(htitle, 300, "Z res for \"%s\" @ %s;tg(#theta);#Delta z [cm];row cross", GetNameId(), name);
2319 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2320 h = new TH3S(hname, htitle, 50, -1., 1., 100, -1.5, 1.5, 2, -0.5, 1.5);
2323 snprintf(hname, 100, "%s_%s_Zpull", GetNameId(), name);
2324 snprintf(htitle, 300, "Z pull for \"%s\" @ %s;tg(#theta);#Delta z / #sigma_{z};row cross", GetNameId(), name);
2325 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2326 h = new TH3S(hname, htitle, 50, -1., 1., 100, -5.5, 5.5, 2, -0.5, 1.5);
2327 h->GetZaxis()->SetBinLabel(1, "no RC");
2328 h->GetZaxis()->SetBinLabel(2, "RC");
2332 // tracklet to track phi resolution
2333 snprintf(hname, 100, "%s_%s_PHI", GetNameId(), name);
2334 snprintf(htitle, 300, "#Phi res for \"%s\" @ %s;tg(#phi);#Delta #phi [rad];entries", GetNameId(), name);
2335 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2336 h = new TH2I(hname, htitle, 21, -.33, .33, 100, -.5, .5);
2343 //________________________________________________________
2344 TObjArray* AliTRDresolution::BuildMonitorContainerTrack(const char* name)
2346 // Build performance histograms for AliExternalTrackParam.vs MC
2347 // - y resolution/pulls
2348 // - z resolution/pulls
2349 // - phi resolution, snp pulls
2350 // - theta resolution, tgl pulls
2351 // - pt resolution, 1/pt pulls, p resolution
2353 TObjArray *arr = BuildMonitorContainerTracklet(name);
2355 TH1 *h(NULL); char hname[100], htitle[300];
2359 snprintf(hname, 100, "%s_%s_SNPpull", GetNameId(), name);
2360 snprintf(htitle, 300, "SNP pull for \"%s\" @ %s;tg(#phi);#Delta snp / #sigma_{snp};entries", GetNameId(), name);
2361 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2362 h = new TH2I(hname, htitle, 60, -.3, .3, 100, -4.5, 4.5);
2367 snprintf(hname, 100, "%s_%s_THT", GetNameId(), name);
2368 snprintf(htitle, 300, "#Theta res for \"%s\" @ %s;tg(#theta);#Delta #theta [rad];entries", GetNameId(), name);
2369 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2370 h = new TH2I(hname, htitle, 100, -1., 1., 100, -5e-3, 5e-3);
2374 snprintf(hname, 100, "%s_%s_TGLpull", GetNameId(), name);
2375 snprintf(htitle, 300, "TGL pull for \"%s\" @ %s;tg(#theta);#Delta tgl / #sigma_{tgl};entries", GetNameId(), name);
2376 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2377 h = new TH2I(hname, htitle, 100, -1., 1., 100, -4.5, 4.5);
2381 const Int_t kNpt(14);
2382 const Int_t kNdpt(150);
2383 const Int_t kNspc = 2*AliPID::kSPECIES+1;
2384 Float_t lPt=0.1, lDPt=-.1, lSpc=-5.5;
2385 Float_t binsPt[kNpt+1], binsSpc[kNspc+1], binsDPt[kNdpt+1];
2386 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2387 for(Int_t i=0; i<kNspc+1; i++,lSpc+=1.) binsSpc[i]=lSpc;
2388 for(Int_t i=0; i<kNdpt+1; i++,lDPt+=2.e-3) binsDPt[i]=lDPt;
2391 snprintf(hname, 100, "%s_%s_Pt", GetNameId(), name);
2392 snprintf(htitle, 300, "#splitline{P_{t} res for}{\"%s\" @ %s};p_{t} [GeV/c];#Delta p_{t}/p_{t}^{MC};SPECIES", GetNameId(), name);
2393 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2394 h = new TH3S(hname, htitle,
2395 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2397 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2401 snprintf(hname, 100, "%s_%s_1Pt", GetNameId(), name);
2402 snprintf(htitle, 300, "#splitline{1/P_{t} pull for}{\"%s\" @ %s};1/p_{t}^{MC} [c/GeV];#Delta(1/p_{t})/#sigma(1/p_{t});SPECIES", GetNameId(), name);
2403 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2404 h = new TH3S(hname, htitle,
2405 kNpt, 0., 2., 100, -4., 4., kNspc, -5.5, 5.5);
2407 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2411 snprintf(hname, 100, "%s_%s_P", GetNameId(), name);
2412 snprintf(htitle, 300, "P res for \"%s\" @ %s;p [GeV/c];#Delta p/p^{MC};SPECIES", GetNameId(), name);
2413 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2414 h = new TH3S(hname, htitle,
2415 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2417 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2425 //________________________________________________________
2426 TObjArray* AliTRDresolution::Histos()
2429 // Define histograms
2432 if(fContainer) return fContainer;
2434 fContainer = new TObjArray(kNviews);
2435 //fContainer->SetOwner(kTRUE);
2437 TObjArray *arr(NULL);
2439 // binnings for plots containing momentum or pt
2440 const Int_t kNpt(14), kNphi(48), kNdy(60);
2441 Float_t lPhi=-.48, lDy=-.3, lPt=0.1;
2442 Float_t binsPhi[kNphi+1], binsDy[kNdy+1], binsPt[kNpt+1];
2443 for(Int_t i=0; i<kNphi+1; i++,lPhi+=.02) binsPhi[i]=lPhi;
2444 for(Int_t i=0; i<kNdy+1; i++,lDy+=.01) binsDy[i]=lDy;
2445 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2447 // cluster to track residuals/pulls
2448 fContainer->AddAt(arr = new TObjArray(2), kCharge);
2449 arr->SetName("Charge");
2450 if(!(h = (TH3S*)gROOT->FindObject("hCharge"))){
2451 h = new TH3S("hCharge", "Charge Resolution", 20, 1., 2., 24, 0., 3.6, 100, 0., 500.);
2452 h->GetXaxis()->SetTitle("dx/dx_{0}");
2453 h->GetYaxis()->SetTitle("x_{d} [cm]");
2454 h->GetZaxis()->SetTitle("dq/dx [ADC/cm]");
2458 // cluster to track residuals/pulls
2459 fContainer->AddAt(BuildMonitorContainerCluster("Cl"), kCluster);
2460 // tracklet to TRD track
2461 fContainer->AddAt(BuildMonitorContainerTracklet("Trk", kTRUE), kTrack);
2462 // tracklet to TRDin
2463 fContainer->AddAt(BuildMonitorContainerTracklet("TrkIN", kTRUE), kTrackIn);
2464 // tracklet to TRDout
2465 fContainer->AddAt(BuildMonitorContainerTracklet("TrkOUT"), kTrackOut);
2468 // Resolution histos
2469 if(!HasMCdata()) return fContainer;
2471 // cluster resolution
2472 fContainer->AddAt(BuildMonitorContainerCluster("MCcl"), kMCcluster);
2474 // tracklet resolution
2475 fContainer->AddAt(BuildMonitorContainerTracklet("MCtracklet"), kMCtracklet);
2478 fContainer->AddAt(arr = new TObjArray(AliTRDgeometry::kNlayer), kMCtrack);
2479 arr->SetName("MCtrk");
2480 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++) arr->AddAt(BuildMonitorContainerTrack(Form("MCtrk_Ly%d", il)), il);
2482 // TRDin TRACK RESOLUTION
2483 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkIN"), kMCtrackIn);
2485 // TRDout TRACK RESOLUTION
2486 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkOUT"), kMCtrackOut);
2491 //________________________________________________________
2492 Bool_t AliTRDresolution::Load(const Char_t *file, const Char_t *dir)
2494 // Custom load function. Used to guess the segmentation level of the data.
2496 if(!AliTRDrecoTask::Load(file, dir)) return kFALSE;
2498 // look for cluster residual plot - always available
2499 TH3S* h3((TH3S*)((TObjArray*)fContainer->At(kClToTrk))->At(0));
2500 Int_t segmentation(h3->GetNbinsZ()/2);
2501 if(segmentation==fgkNresYsegm[0]){ // default segmentation. Nothing to do
2503 } else if(segmentation==fgkNresYsegm[1]){ // stack segmentation.
2504 SetSegmentationLevel(1);
2505 } else if(segmentation==fgkNresYsegm[2]){ // detector segmentation.
2506 SetSegmentationLevel(2);
2508 AliError(Form("Unknown segmentation [%d].", h3->GetNbinsZ()));
2512 AliDebug(2, Form("Segmentation set to level \"%s\"", fgkResYsegmName[fSegmentLevel]));
2516 //________________________________________________________
2517 Bool_t AliTRDresolution::Process(TH2* const h2, TGraphErrors **g, Int_t stat)
2519 // Robust function to process sigma/mean for 2D plot dy(x)
2520 // For each x bin a gauss fit is performed on the y projection and the range
2521 // with the minimum chi2/ndf is choosen
2524 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>0) printf("D-AliTRDresolution::Process() : NULL pointer input container.\n");
2527 if(!Int_t(h2->GetEntries())){
2528 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>0) printf("D-AliTRDresolution::Process() : Empty h[%s - %s].\n", h2->GetName(), h2->GetTitle());
2531 if(!g || !g[0]|| !g[1]) {
2532 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>0) printf("D-AliTRDresolution::Process() : NULL pointer output container.\n");
2536 TAxis *ax(h2->GetXaxis()), *ay(h2->GetYaxis());
2537 Float_t ymin(ay->GetXmin()), ymax(ay->GetXmax()), dy(ay->GetBinWidth(1)), y0(0.), y1(0.);
2538 TF1 f("f", "gaus", ymin, ymax);
2540 if((n=g[0]->GetN())) for(;n--;) g[0]->RemovePoint(n);
2541 if((n=g[1]->GetN())) for(;n--;) g[1]->RemovePoint(n);
2543 if((h=(TH1D*)gROOT->FindObject("py"))) delete h;
2544 Double_t x(0.), y(0.), ex(0.), ey(0.), sy(0.), esy(0.);
2548 Float_t chi2OverNdf(0.);
2549 for(Int_t ix = 1, np=0; ix<=ax->GetNbins(); ix++){
2550 x = ax->GetBinCenter(ix); ex= ax->GetBinWidth(ix)*0.288; // w/sqrt(12)
2551 ymin = ay->GetXmin(); ymax = ay->GetXmax();
2553 h = h2->ProjectionY("py", ix, ix);
2554 if((n=(Int_t)h->GetEntries())<stat){
2555 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("I-AliTRDresolution::Process() : Low statistics @ x[%f] stat[%d]=%d [%d].\n", x, ix, n, stat);
2558 // looking for a first order mean value
2559 f.SetParameter(1, 0.); f.SetParameter(2, 3.e-2);
2561 chi2OverNdf = f.GetChisquare()/f.GetNDF();
2562 printf("x[%f] range[%f %f] chi2[%f] ndf[%d] chi2/ndf[%f]\n", x, ymin, ymax, f.GetChisquare(),f.GetNDF(),chi2OverNdf);
2563 y = f.GetParameter(1); y0 = y-4*dy; y1 = y+4*dy;
2564 ey = f.GetParError(1);
2565 sy = f.GetParameter(2); esy = f.GetParError(2);
2566 // // looking for the best chi2/ndf value
2567 // while(ymin<y0 && ymax>y1){
2568 // f.SetParameter(1, y);
2569 // f.SetParameter(2, sy);
2570 // h->Fit(&f, "QNW", "", y0, y1);
2571 // printf(" range[%f %f] chi2[%f] ndf[%d] chi2/ndf[%f]\n", y0, y1, f.GetChisquare(),f.GetNDF(),f.GetChisquare()/f.GetNDF());
2572 // if(f.GetChisquare()/f.GetNDF() < Chi2OverNdf){
2573 // chi2OverNdf = f.GetChisquare()/f.GetNDF();
2574 // y = f.GetParameter(1); ey = f.GetParError(1);
2575 // sy = f.GetParameter(2); esy = f.GetParError(2);
2576 // printf(" set y[%f] sy[%f] chi2/ndf[%f]\n", y, sy, chi2OverNdf);
2580 g[0]->SetPoint(np, x, y);
2581 g[0]->SetPointError(np, ex, ey);
2582 g[1]->SetPoint(np, x, sy);
2583 g[1]->SetPointError(np, ex, esy);
2590 //________________________________________________________
2591 Bool_t AliTRDresolution::Process(TH2 * const h2, TF1 *f, Float_t k, TGraphErrors **g)
2594 // Do the processing
2597 Char_t pn[10]; snprintf(pn, 10, "p%03d", fIdxPlot);
2599 if((n=g[0]->GetN())) for(;n--;) g[0]->RemovePoint(n);
2600 if((n=g[1]->GetN())) for(;n--;) g[1]->RemovePoint(n);
2601 if(Int_t(h2->GetEntries())){
2602 AliDebug(4, Form("%s: g[%s %s]", pn, g[0]->GetName(), g[0]->GetTitle()));
2604 AliDebug(2, Form("%s: g[%s %s]: Missing entries.", pn, g[0]->GetName(), g[0]->GetTitle()));
2609 const Int_t kINTEGRAL=1;
2610 for(Int_t ibin = 0; ibin < Int_t(h2->GetNbinsX()/kINTEGRAL); ibin++){
2611 Int_t abin(ibin*kINTEGRAL+1),bbin(abin+kINTEGRAL-1),mbin(abin+Int_t(kINTEGRAL/2));
2612 Double_t x = h2->GetXaxis()->GetBinCenter(mbin);
2613 TH1D *h = h2->ProjectionY(pn, abin, bbin);
2614 if((n=(Int_t)h->GetEntries())<150){
2615 AliDebug(4, Form(" x[%f] range[%d %d] stat[%d] low statistics !", x, abin, bbin, n));
2619 Int_t ip = g[0]->GetN();
2620 AliDebug(4, Form(" x_%d[%f] range[%d %d] stat[%d] M[%f] Sgm[%f]", ip, x, abin, bbin, n, f->GetParameter(1), f->GetParameter(2)));
2621 g[0]->SetPoint(ip, x, k*f->GetParameter(1));
2622 g[0]->SetPointError(ip, 0., k*f->GetParError(1));
2623 g[1]->SetPoint(ip, x, k*f->GetParameter(2));
2624 g[1]->SetPointError(ip, 0., k*f->GetParError(2));
2626 g[0]->SetPoint(ip, x, k*h->GetMean());
2627 g[0]->SetPointError(ip, 0., k*h->GetMeanError());
2628 g[1]->SetPoint(ip, x, k*h->GetRMS());
2629 g[1]->SetPointError(ip, 0., k*h->GetRMSError());*/
2635 //________________________________________________________
2636 Bool_t AliTRDresolution::Process2D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k, Int_t gidx)
2639 // Do the processing
2642 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2644 // retrive containers
2647 if(!(h2= (TH2I*)(fContainer->At(plot)))) return kFALSE;
2649 TObjArray *a0(NULL);
2650 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2651 if(!(h2=(TH2I*)a0->At(idx))) return kFALSE;
2653 if(Int_t(h2->GetEntries())){
2654 AliDebug(2, Form("p[%d] idx[%d] : h[%s] %s", plot, idx, h2->GetName(), h2->GetTitle()));
2656 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2661 if(gidx<0) gidx=idx;
2662 if(!(g[0] = gidx<0 ? (TGraphErrors*)fGraphM->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphM->At(plot)))->At(gidx))) return kFALSE;
2664 if(!(g[1] = gidx<0 ? (TGraphErrors*)fGraphS->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphS->At(plot)))->At(gidx))) return kFALSE;
2666 return Process(h2, f, k, g);
2669 //________________________________________________________
2670 Bool_t AliTRDresolution::Process3D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2673 // Do the processing
2676 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2678 // retrive containers
2681 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2683 TObjArray *a0(NULL);
2684 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2685 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2687 if(Int_t(h3->GetEntries())){
2688 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2690 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2695 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2696 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2699 TAxis *az = h3->GetZaxis();
2700 for(Int_t iz(0); iz<gm->GetEntriesFast(); iz++){
2701 if(!(g[0] = (TGraphErrors*)gm->At(iz))) return kFALSE;
2702 if(!(g[1] = (TGraphErrors*)gs->At(iz))) return kFALSE;
2703 az->SetRange(iz+1, iz+1);
2704 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2711 //________________________________________________________
2712 Bool_t AliTRDresolution::Process3Dlinked(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2715 // Do the processing
2718 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2720 // retrive containers
2723 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2725 TObjArray *a0(NULL);
2726 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2727 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2729 if(Int_t(h3->GetEntries())){
2730 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2732 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2737 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2738 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2741 if(!(g[0] = (TGraphErrors*)gm->At(0))) return kFALSE;
2742 if(!(g[1] = (TGraphErrors*)gs->At(0))) return kFALSE;
2743 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2745 if(!(g[0] = (TGraphErrors*)gm->At(1))) return kFALSE;
2746 if(!(g[1] = (TGraphErrors*)gs->At(1))) return kFALSE;
2747 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2753 //________________________________________________________
2754 Bool_t AliTRDresolution::Process3DL(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2757 // Do the processing
2760 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2762 // retrive containers
2763 TH3S *h3 = (TH3S*)((TObjArray*)fContainer->At(plot))->At(idx);
2764 if(!h3) return kFALSE;
2765 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2767 TGraphAsymmErrors *gm;
2769 if(!(gm = (TGraphAsymmErrors*)((TObjArray*)fGraphM->At(plot))->At(0))) return kFALSE;
2770 if(!(gs = (TGraphErrors*)((TObjArray*)fGraphS->At(plot)))) return kFALSE;
2772 Float_t x(0.), r(0.), mpv(0.), xM(0.), xm(0.);
2773 TAxis *ay = h3->GetYaxis();
2774 for(Int_t iy=1; iy<=h3->GetNbinsY(); iy++){
2775 ay->SetRange(iy, iy);
2776 x = ay->GetBinCenter(iy);
2777 TH2F *h2=(TH2F*)h3->Project3D("zx");
2778 TAxis *ax = h2->GetXaxis();
2779 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
2780 r = ax->GetBinCenter(ix);
2781 TH1D *h1 = h2->ProjectionY("py", ix, ix);
2782 if(h1->Integral()<50) continue;
2785 GetLandauMpvFwhm(f, mpv, xm, xM);
2786 Int_t ip = gm->GetN();
2787 gm->SetPoint(ip, x, k*mpv);
2788 gm->SetPointError(ip, 0., 0., k*xm, k*xM);
2789 gs->SetPoint(ip, r, k*(xM-xm)/mpv);
2790 gs->SetPointError(ip, 0., 0.);
2797 //________________________________________________________
2798 Bool_t AliTRDresolution::Process2Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2801 // Do the processing
2804 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2806 // retrive containers
2807 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2808 if(!arr) return kFALSE;
2809 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2812 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2813 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2815 TGraphErrors *g[2]; TH2I *h2(NULL); TObjArray *a0(NULL);
2816 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2817 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2819 if(!(h2 = (TH2I*)a0->At(idx))) return kFALSE;
2820 if(Int_t(h2->GetEntries())){
2821 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h2->GetName(), h2->GetTitle()));
2823 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2827 if(!(g[0] = (TGraphErrors*)gm->At(ia))) return kFALSE;
2828 if(!(g[1] = (TGraphErrors*)gs->At(ia))) return kFALSE;
2829 if(!Process(h2, f, k, g)) return kFALSE;
2835 //________________________________________________________
2836 Bool_t AliTRDresolution::Process3Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2839 // Do the processing
2842 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2843 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2845 // retrive containers
2846 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2847 if(!arr) return kFALSE;
2848 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2851 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2852 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2854 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2856 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2857 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2859 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2860 if(Int_t(h3->GetEntries())){
2861 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2863 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2866 TAxis *az = h3->GetZaxis();
2867 for(Int_t iz=1; iz<=az->GetNbins(); iz++, in++){
2868 if(in >= gm->GetEntriesFast()) break;
2869 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2870 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2871 az->SetRange(iz, iz);
2872 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2875 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2880 //________________________________________________________
2881 Bool_t AliTRDresolution::Process3DlinkedArray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2884 // Do the processing
2887 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2888 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2890 // retrive containers
2891 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2892 if(!arr) return kFALSE;
2893 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2896 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2897 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2899 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2901 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2902 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2903 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2904 if(Int_t(h3->GetEntries())){
2905 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2907 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2910 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2911 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2912 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2915 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2916 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2917 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2920 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2925 //________________________________________________________
2926 Bool_t AliTRDresolution::GetGraph(Float_t *bb, ETRDresolutionPlot ip, Int_t idx, Bool_t kLEG, const Char_t *explain)
2932 if(!fGraphS || !fGraphM) return kFALSE;
2933 // axis titles look up
2935 for(Int_t jp=0; jp<(Int_t)ip; jp++) nref+=fgNproj[jp];
2936 UChar_t jdx = idx<0?0:idx;
2937 for(Int_t jc=0; jc<TMath::Min(jdx,fgNproj[ip]-1); jc++) nref++;
2938 Char_t **at = fAxTitle[nref];
2940 // build legends if requiered
2943 leg=new TLegend(.65, .6, .95, .9);
2944 leg->SetBorderSize(0);
2945 leg->SetFillStyle(0);
2949 h1 = new TH1S(Form("h1TF_%02d", fIdxFrame++), Form("%s %s;%s;%s", at[0], explain?explain:"", at[1], at[2]), 2, bb[0], bb[2]);
2950 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
2951 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
2953 TAxis *ax = h1->GetXaxis();
2954 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
2955 ax = h1->GetYaxis();
2956 ax->SetRangeUser(bb[1], bb[3]);
2957 ax->CenterTitle(); ax->SetTitleOffset(1.4);
2960 TBox *b = new TBox(-.15, bb[1], .15, bb[3]);
2961 b->SetFillStyle(3002);b->SetLineColor(0);
2962 b->SetFillColor(ip<=Int_t(kMCcluster)?kGreen:kBlue);
2965 TGraphErrors *gm = idx<0 ? (TGraphErrors*)fGraphM->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphM->At(ip)))->At(idx);
2966 if(!gm) return kFALSE;
2967 TGraphErrors *gs = idx<0 ? (TGraphErrors*)fGraphS->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphS->At(ip)))->At(idx);
2968 if(!gs) return kFALSE;
2970 Int_t n(0), nPlots(0);
2971 if((n=gm->GetN())) {
2973 gm->Draw("pl"); if(leg) leg->AddEntry(gm, gm->GetTitle(), "pl");
2974 PutTrendValue(Form("%s_%s", fgPerformanceName[ip], at[0]), gm->GetMean(2));
2975 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[ip], at[0]), gm->GetRMS(2));
2980 gs->Draw("pl"); if(leg) leg->AddEntry(gs, gs->GetTitle(), "pl");
2981 gs->Sort(&TGraph::CompareY);
2982 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[ip], at[0]), gs->GetY()[0]);
2983 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[ip], at[0]), gs->GetY()[n-1]);
2984 gs->Sort(&TGraph::CompareX);
2986 if(!nPlots) return kFALSE;
2987 if(leg) leg->Draw();
2991 //________________________________________________________
2992 Bool_t AliTRDresolution::GetGraphArray(Float_t *bb, ETRDresolutionPlot ip, Int_t idx, Bool_t kLEG, Int_t n, Int_t *sel, const Char_t *explain)
2998 if(!fGraphS || !fGraphM) return kFALSE;
3000 // axis titles look up
3002 for(Int_t jp(0); jp<ip; jp++) nref+=fgNproj[jp];
3004 Char_t **at = fAxTitle[nref];
3006 // build legends if requiered
3007 TLegend *legM(NULL), *legS(NULL);
3009 legM=new TLegend(.35, .6, .65, .9);
3010 legM->SetHeader("Mean");
3011 legM->SetBorderSize(0);
3012 legM->SetFillStyle(0);
3013 legS=new TLegend(.65, .6, .95, .9);
3014 legS->SetHeader("Sigma");
3015 legS->SetBorderSize(0);
3016 legS->SetFillStyle(0);
3020 h1 = new TH1S(Form("h1TF_%02d", fIdxFrame++), Form("%s %s;%s;%s", at[0], explain?explain:"", at[1], at[2]), 2, bb[0], bb[2]);
3021 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
3022 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
3024 TAxis *ax = h1->GetXaxis();
3025 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
3026 ax = h1->GetYaxis();
3027 ax->SetRangeUser(bb[1], bb[3]);
3028 ax->CenterTitle(); ax->SetTitleOffset(1.4);
3031 TGraphErrors *gm(NULL), *gs(NULL);
3032 TObjArray *a0(NULL), *a1(NULL);
3033 a0 = (TObjArray*)((TObjArray*)fGraphM->At(ip))->At(idx);
3034 a1 = (TObjArray*)((TObjArray*)fGraphS->At(ip))->At(idx);
3035 if(!n) n=a0->GetEntriesFast();
3036 AliDebug(4, Form("Graph : Ref[%d] Title[%s] Limits{x[%f %f] y[%f %f]} Comp[%d] Selection[%c]", nref, at[0], bb[0], bb[2], bb[1], bb[3], n, sel ? 'y' : 'n'));
3037 Int_t nn(0), nPlots(0);
3038 for(Int_t is(0), is0(0); is<n; is++){
3039 is0 = sel ? sel[is] : is;
3040 if(!(gs = (TGraphErrors*)a1->At(is0))) return kFALSE;
3041 if(!(gm = (TGraphErrors*)a0->At(is0))) return kFALSE;
3043 if((nn=gs->GetN())){
3047 //printf("LegEntry %s [%s]%s\n", at[0], gs->GetName(), gs->GetTitle());
3048 legS->AddEntry(gs, gs->GetTitle(), "pl");
3050 gs->Sort(&TGraph::CompareY);
3051 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[0]);
3052 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[nn-1]);
3053 gs->Sort(&TGraph::CompareX);
3059 //printf("LegEntry %s [%s]%s\n", at[0], gm->GetName(), gm->GetTitle());
3060 legM->AddEntry(gm, gm->GetTitle(), "pl");
3062 PutTrendValue(Form("%s_%s", fgPerformanceName[kMCtrack], at[0]), gm->GetMean(2));
3063 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[kMCtrack], at[0]), gm->GetRMS(2));
3066 if(!nPlots) return kFALSE;
3074 //____________________________________________________________________
3075 Bool_t AliTRDresolution::FitTrack(const Int_t np, AliTrackPoint *points, Float_t param[10])
3078 // Fit track with a staight line using the "np" clusters stored in the array "points".
3079 // The following particularities are stored in the clusters from points:
3080 // 1. pad tilt as cluster charge
3081 // 2. pad row cross or vertex constrain as fake cluster with cluster type 1
3082 // The parameters of the straight line fit are stored in the array "param" in the following order :
3083 // param[0] - x0 reference radial position
3084 // param[1] - y0 reference r-phi position @ x0
3085 // param[2] - z0 reference z position @ x0
3086 // param[3] - slope dy/dx
3087 // param[4] - slope dz/dx
3090 // Function should be used to refit tracks for B=0T
3094 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("D-AliTRDresolution::FitTrack: Not enough clusters to fit a track [%d].\n", np);
3097 TLinearFitter yfitter(2, "pol1"), zfitter(2, "pol1");
3100 for(Int_t ip(0); ip<np; ip++) x0+=points[ip].GetX();
3103 Double_t x, y, z, dx, tilt(0.);
3104 for(Int_t ip(0); ip<np; ip++){
3105 x = points[ip].GetX(); z = points[ip].GetZ();
3107 zfitter.AddPoint(&dx, z, points[ip].GetClusterType()?1.e-3:1.);
3109 if(zfitter.Eval() != 0) return kFALSE;
3111 Double_t z0 = zfitter.GetParameter(0);
3112 Double_t dzdx = zfitter.GetParameter(1);
3113 for(Int_t ip(0); ip<np; ip++){
3114 if(points[ip].GetClusterType()) continue;
3115 x = points[ip].GetX();
3117 y = points[ip].GetY();
3118 z = points[ip].GetZ();
3119 tilt = points[ip].GetCharge();
3120 y -= tilt*(-dzdx*dx + z - z0);
3121 Float_t xyz[3] = {x, y, z}; points[ip].SetXYZ(xyz);
3122 yfitter.AddPoint(&dx, y, 1.);
3124 if(yfitter.Eval() != 0) return kFALSE;
3125 Double_t y0 = yfitter.GetParameter(0);
3126 Double_t dydx = yfitter.GetParameter(1);
3128 param[0] = x0; param[1] = y0; param[2] = z0; param[3] = dydx; param[4] = dzdx;
3129 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>3) printf("D-AliTRDresolution::FitTrack: x0[%f] y0[%f] z0[%f] dydx[%f] dzdx[%f].\n", x0, y0, z0, dydx, dzdx);
3133 //____________________________________________________________________
3134 Bool_t AliTRDresolution::FitTracklet(const Int_t ly, const Int_t np, const AliTrackPoint *points, const Float_t param[10], Float_t par[3])
3137 // Fit tracklet with a staight line using the coresponding subset of clusters out of the total "np" clusters stored in the array "points".
3138 // See function FitTrack for the data stored in the "clusters" array
3140 // The parameters of the straight line fit are stored in the array "param" in the following order :
3141 // par[0] - x0 reference radial position
3142 // par[1] - y0 reference r-phi position @ x0
3143 // par[2] - slope dy/dx
3146 // Function should be used to refit tracks for B=0T
3149 TLinearFitter yfitter(2, "pol1");
3151 // grep data for tracklet
3152 Double_t x0(0.), x[60], y[60], dy[60];
3154 for(Int_t ip(0); ip<np; ip++){
3155 if(points[ip].GetClusterType()) continue;
3156 if(points[ip].GetVolumeID() != ly) continue;
3157 Float_t xt(points[ip].GetX())
3158 ,yt(param[1] + param[3] * (xt - param[0]));
3160 y[nly] = points[ip].GetY();
3166 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("D-AliTRDresolution::FitTracklet: Not enough clusters to fit a tracklet [%d].\n", nly);
3169 // set radial reference for fit
3172 // find tracklet core
3173 Double_t mean(0.), sig(1.e3);
3174 AliMathBase::EvaluateUni(nly, dy, mean, sig, 0);
3176 // simple cluster error parameterization
3177 Float_t kSigCut = TMath::Sqrt(5.e-4 + param[3]*param[3]*0.018);
3179 // fit tracklet core
3180 for(Int_t jly(0); jly<nly; jly++){
3181 if(TMath::Abs(dy[jly]-mean)>kSigCut) continue;
3182 Double_t dx(x[jly]-x0);
3183 yfitter.AddPoint(&dx, y[jly], 1.);
3185 if(yfitter.Eval() != 0) return kFALSE;
3187 par[1] = yfitter.GetParameter(0);
3188 par[2] = yfitter.GetParameter(1);
3192 //____________________________________________________________________
3193 Bool_t AliTRDresolution::UseTrack(const Int_t np, const AliTrackPoint *points, Float_t param[10])
3196 // Global selection mechanism of tracksbased on cluster to fit residuals
3197 // The parameters are the same as used ni function FitTrack().
3199 const Float_t kS(0.6), kM(0.2);
3200 TH1S h("h1", "", 100, -5.*kS, 5.*kS);
3201 Float_t dy, dz, s, m;
3202 for(Int_t ip(0); ip<np; ip++){
3203 if(points[ip].GetClusterType()) continue;
3204 Float_t x0(points[ip].GetX())
3205 ,y0(param[1] + param[3] * (x0 - param[0]))
3206 ,z0(param[2] + param[4] * (x0 - param[0]));
3207 dy=points[ip].GetY() - y0; h.Fill(dy);
3208 dz=points[ip].GetZ() - z0;
3210 TF1 fg("fg", "gaus", -5.*kS, 5.*kS);
3211 fg.SetParameter(1, 0.);
3212 fg.SetParameter(2, 2.e-2);
3214 m=fg.GetParameter(1); s=fg.GetParameter(2);
3215 if(s>kS || TMath::Abs(m)>kM) return kFALSE;
3219 //________________________________________________________
3220 void AliTRDresolution::GetLandauMpvFwhm(TF1 * const f, Float_t &mpv, Float_t &xm, Float_t &xM)
3223 // Get the most probable value and the full width half mean
3224 // of a Landau distribution
3227 const Float_t dx = 1.;
3228 mpv = f->GetParameter(1);
3229 Float_t fx, max = f->Eval(mpv);
3232 while((fx = f->Eval(xm))>.5*max){
3241 while((fx = f->Eval(xM))>.5*max) xM += dx;
3245 //________________________________________________________
3246 void AliTRDresolution::SetSegmentationLevel(Int_t l)
3248 // Setting the segmentation level to "l"
3251 UShort_t const lNcomp[kNprojs] = {
3253 fgkNresYsegm[fSegmentLevel], 2, //2,
3254 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3255 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3256 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3258 fgkNresYsegm[fSegmentLevel], 2, //2,
3259 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3260 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3261 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3262 6*fgkNresYsegm[fSegmentLevel], 6*2, 6*2, 6*2, 6, 6, 6, 6, 6*11, 6*11, 6*11 //11
3264 memcpy(fNcomp, lNcomp, kNprojs*sizeof(UShort_t));
3266 Char_t const *lAxTitle[kNprojs][4] = {
3268 {"Impv", "x [cm]", "I_{mpv}", "x/x_{0}"}
3269 ,{"dI/Impv", "x/x_{0}", "#delta I/I_{mpv}", "x[cm]"}
3270 // Clusters to Kalman
3271 ,{"Cluster2Track residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3272 ,{"Cluster2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3273 // TRD tracklet to Kalman fit
3274 ,{"Tracklet2Track Y residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3275 ,{"Tracklet2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3276 ,{"Tracklet2Track Z residuals", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3277 ,{"Tracklet2Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3278 ,{"Tracklet2Track Phi residuals", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3279 // TRDin 2 first TRD tracklet
3280 ,{"Tracklet2Track Y residuals @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3281 ,{"Tracklet2Track YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3282 ,{"Tracklet2Track Z residuals @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3283 ,{"Tracklet2Track Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3284 ,{"Tracklet2Track Phi residuals @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3285 // TRDout 2 first TRD tracklet
3286 ,{"Tracklet2Track Y residuals @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3287 ,{"Tracklet2Track YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3288 ,{"Tracklet2Track Z residuals @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3289 ,{"Tracklet2Track Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3290 ,{"Tracklet2Track Phi residuals @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3292 ,{"MC Cluster Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3293 ,{"MC Cluster YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3295 ,{"MC Tracklet Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3296 ,{"MC Tracklet YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3297 ,{"MC Tracklet Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3298 ,{"MC Tracklet Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3299 ,{"MC Tracklet Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3301 ,{"MC Y resolution @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3302 ,{"MC YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3303 ,{"MC Z resolution @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3304 ,{"MC Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3305 ,{"MC #Phi resolution @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3306 ,{"MC SNP pulls @ TRDin", "tg(#phi)", "SNP", "#sigma_{snp}"}
3307 ,{"MC #Theta resolution @ TRDin", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3308 ,{"MC TGL pulls @ TRDin", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3309 ,{"MC P_{t} resolution @ TRDin", "p_{t}^{MC} [GeV/c]", "(p_{t}^{REC}-p_{t}^{MC})/p_{t}^{MC} [%]", "MC: #sigma^{TPC}(#Deltap_{t}/p_{t}^{MC}) [%]"}
3310 ,{"MC 1/P_{t} pulls @ TRDin", "1/p_{t}^{MC} [c/GeV]", "1/p_{t}^{REC}-1/p_{t}^{MC}", "MC PULL: #sigma_{1/p_{t}}^{TPC}"}
3311 ,{"MC P resolution @ TRDin", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3313 ,{"MC Y resolution @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3314 ,{"MC YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3315 ,{"MC Z resolution @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3316 ,{"MC Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3317 ,{"MC #Phi resolution @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3318 ,{"MC SNP pulls @ TRDout", "tg(#phi)", "SNP", "#sigma_{snp}"}
3319 ,{"MC #Theta resolution @ TRDout", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3320 ,{"MC TGL pulls @ TRDout", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3321 ,{"MC P_{t} resolution @ TRDout", "p_{t}^{MC} [GeV/c]", "(p_{t}^{REC}-p_{t}^{MC})/p_{t}^{MC} [%]", "MC: #sigma^{TPC}(#Deltap_{t}/p_{t}^{MC}) [%]"}
3322 ,{"MC 1/P_{t} pulls @ TRDout", "1/p_{t}^{MC} [c/GeV]", "1/p_{t}^{REC}-1/p_{t}^{MC}", "MC PULL: #sigma_{1/p_{t}}^{TPC}"}
3323 ,{"MC P resolution @ TRDout", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3325 ,{"MC Track Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3326 ,{"MC Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3327 ,{"MC Track Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3328 ,{"MC Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3329 ,{"MC Track #Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3330 ,{"MC Track SNP pulls", "tg(#phi)", "SNP", "#sigma_{snp}"}
3331 ,{"MC Track #Theta resolution", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3332 ,{"MC Track TGL pulls", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3333 ,{"MC P_{t} resolution", "p_{t} [GeV/c]", "(p_{t}^{REC}-p_{t}^{MC})/p_{t}^{MC} [%]", "#sigma(#Deltap_{t}/p_{t}^{MC}) [%]"}
3334 ,{"MC 1/P_{t} pulls", "1/p_{t}^{MC} [c/GeV]", "1/p_{t}^{REC} - 1/p_{t}^{MC}", "#sigma_{1/p_{t}}"}
3335 ,{"MC P resolution", "p [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "#sigma(#Deltap/p^{MC}) [%]"}
3337 memcpy(fAxTitle, lAxTitle, 4*kNprojs*sizeof(Char_t*));
3341 //________________________________________________________
3342 Bool_t AliTRDresolution::LoadCorrection(const Char_t *file)
3345 AliWarning("Use cluster position as in reconstruction.");
3346 SetLoadCorrection();
3349 TDirectory *cwd(gDirectory);
3351 FILE *filePtr = fopen(file, "rt");
3353 AliError(Form("Couldn't open correction list \"%s\". Use cluster position as in reconstruction.", file));
3354 SetLoadCorrection();
3357 TH2 *h2 = new TH2F("h2", ";time [time bins];detector;dx [#mum]", 30, -0.5, 29.5, AliTRDgeometry::kNdet, -0.5, AliTRDgeometry::kNdet-0.5);
3358 while(fileList.Gets(filePtr)){
3359 if(!TFile::Open(fileList.Data())) {
3360 AliWarning(Form("Couldn't open \"%s\"", fileList.Data()));
3362 } else AliInfo(Form("\"%s\"", fileList.Data()));
3364 TTree *tSys = (TTree*)gFile->Get("tSys");
3365 h2->SetDirectory(gDirectory); h2->Reset("ICE");
3366 tSys->Draw("det:t>>h2", "dx", "goff");
3367 for(Int_t idet(0); idet<AliTRDgeometry::kNdet; idet++){
3368 for(Int_t it(0); it<30; it++) fXcorr[idet][it]+=(1.e-4*h2->GetBinContent(it+1, idet+1));
3370 h2->SetDirectory(cwd);
3375 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>=2){
3376 for(Int_t il(0); il<184; il++) printf("-"); printf("\n");
3377 printf("DET|");for(Int_t it(0); it<30; it++) printf(" tb%02d|", it); printf("\n");
3378 for(Int_t il(0); il<184; il++) printf("-"); printf("\n");
3379 for(Int_t idet(0); idet<AliTRDgeometry::kNdet; idet++){
3380 printf("%03d|", idet);
3381 for(Int_t it(0); it<30; it++) printf("%+5.0f|", 1.e4*fXcorr[idet][it]);
3385 SetLoadCorrection();