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.
246 Double_t t2(tilt*tilt);
247 // exit door until a bug fix is found for AliTRDseedV1::GetCovSqrt
251 cc[0] = cov[0] - 2.*tilt*cov[1] + t2*cov[2];
252 cc[1] = cov[1]*(1.-t2) + tilt*(cov[0] - cov[2]);
253 cc[2] = t2*cov[0] + 2.*tilt*cov[1] + cov[2];
255 Double_t sqr[3]={0., 0., 0.};
256 if(AliTRDseedV1::GetCovSqrt(cc, sqr)) return kFALSE;
257 Double_t invsqr[3]={0., 0., 0.};
258 if(AliTRDseedV1::GetCovInv(sqr, invsqr)<1.e-40) return kFALSE;
259 Double_t tmp(dyz[0]);
260 dyz[0] = invsqr[0]*tmp + invsqr[1]*dyz[1];
261 dyz[1] = invsqr[1]*tmp + invsqr[2]*dyz[1];
266 //________________________________________________________
267 TH1* AliTRDresolution::PlotCharge(const AliTRDtrackV1 *track)
270 // Plots the charge distribution
273 if(track) fkTrack = track;
275 AliDebug(4, "No Track defined.");
278 TObjArray *arr = NULL;
279 if(!fContainer || !(arr = ((TObjArray*)fContainer->At(kCharge)))){
280 AliWarning("No output container defined.");
285 AliTRDseedV1 *fTracklet = NULL;
286 AliTRDcluster *c = NULL;
287 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
288 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
289 if(!fTracklet->IsOK()) continue;
290 Float_t x0 = fTracklet->GetX0();
292 for(Int_t itb=AliTRDseedV1::kNtb; itb--;){
293 if(!(c = fTracklet->GetClusters(itb))){
294 if(!(c = fTracklet->GetClusters(AliTRDseedV1::kNtb+itb))) continue;
296 dqdl = fTracklet->GetdQdl(itb, &dl);
297 if(dqdl<1.e-5) continue;
298 dl /= 0.15; // dl/dl0, dl0 = 1.5 mm for nominal vd
299 (h = (TH3S*)arr->At(0))->Fill(dl, x0-c->GetX(), dqdl);
302 // if(!HasMCdata()) continue;
304 // Float_t pt0, y0, z0, dydx0, dzdx0;
305 // if(!fMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
312 //________________________________________________________
313 TH1* AliTRDresolution::PlotCluster(const AliTRDtrackV1 *track)
316 // Plot the cluster distributions
319 if(track) fkTrack = track;
321 AliDebug(4, "No Track defined.");
324 TObjArray *arr = NULL;
325 if(!fContainer || !(arr = ((TObjArray*)fContainer->At(kCluster)))){
326 AliWarning("No output container defined.");
329 ULong_t status = fkESD ? fkESD->GetStatus():0;
332 Double_t covR[7], cov[3], dy[2], dz[2];
333 Float_t pt, x0, y0, z0, dydx, dzdx, tilt(0.);
334 const AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
335 AliTRDseedV1 *fTracklet(NULL); TObjArray *clInfoArr(NULL);
336 // do LINEAR track refit if asked by the user
337 // it is the user responsibility to check if B=0T
338 Float_t param[10]; memset(param, 0, 10*sizeof(Float_t));
339 Int_t np(0), nrc(0); AliTrackPoint clusters[300];
341 Bool_t kPrimary(kFALSE);
342 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
343 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
344 if(!fTracklet->IsOK()) continue;
345 x0 = fTracklet->GetX0();
346 tilt = fTracklet->GetTilt();
347 AliTRDcluster *c = NULL;
348 fTracklet->ResetClusterIter(kFALSE);
349 while((c = fTracklet->PrevCluster())){
350 Float_t xyz[3] = {c->GetX()+fXcorr[c->GetDetector()][c->GetLocalTimeBin()], c->GetY(), c->GetZ()};
351 clusters[np].SetCharge(tilt);
352 clusters[np].SetClusterType(0);
353 clusters[np].SetVolumeID(ily);
354 clusters[np].SetXYZ(xyz);
357 if(fTracklet->IsRowCross()){
358 Float_t xcross(0.), zcross(0.);
359 if(fTracklet->GetEstimatedCrossPoint(xcross, zcross)){
360 clusters[np].SetCharge(tilt);
361 clusters[np].SetClusterType(1);
362 clusters[np].SetVolumeID(ily);
363 clusters[np].SetXYZ(xcross, 0., zcross);
368 if(fTracklet->IsPrimary()) kPrimary = kTRUE;
371 clusters[np].SetCharge(tilt);
372 clusters[np].SetClusterType(1);
373 clusters[np].SetVolumeID(-1);
374 clusters[np].SetXYZ(0., 0., 0.);
377 if(!FitTrack(np, clusters, param)) {
378 AliDebug(1, "Linear track Fit failed.");
381 if(HasTrackSelection()){
382 Bool_t kReject(kFALSE);
383 if(fkTrack->GetNumberOfTracklets() != AliTRDgeometry::kNlayer) kReject = kTRUE;
384 if(!kReject && !UseTrack(np, clusters, param)) kReject = kTRUE;
386 AliDebug(1, "Reject track for residuals analysis.");
391 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
392 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
393 if(!fTracklet->IsOK()) continue;
394 x0 = fTracklet->GetX0();
395 pt = fTracklet->GetPt();
396 sgm[2] = fTracklet->GetDetector();
397 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
398 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
400 // retrive the track angle with the chamber
403 if(!FitTracklet(ily, np, clusters, param, par)) continue;
404 dydx = par[2];//param[3];
406 y0 = par[1] + dydx * (x0 - par[0]);//param[1] + dydx * (x0 - param[0]);
407 z0 = param[2] + dzdx * (x0 - param[0]);
409 y0 = fTracklet->GetYfit(0);//fTracklet->GetYref(0);
410 z0 = fTracklet->GetZref(0);
411 dydx = fTracklet->GetYfit(1);//fTracklet->GetYref(1);
412 dzdx = fTracklet->GetZref(1);
414 /*printf("RC[%c] Primary[%c]\n"
415 " Fit : y0[%f] z0[%f] dydx[%f] dzdx[%f]\n"
416 " Ref: y0[%f] z0[%f] dydx[%f] dzdx[%f]\n", fTracklet->IsRowCross()?'y':'n', fTracklet->IsPrimary()?'y':'n', y0, z0, dydx, dzdx
417 ,fTracklet->GetYref(0),fTracklet->GetZref(0),fTracklet->GetYref(1),fTracklet->GetZref(1));*/
418 tilt = fTracklet->GetTilt();
419 fTracklet->GetCovRef(covR);
420 Double_t t2(tilt*tilt)
422 ,cost(TMath::Sqrt(corr));
423 AliTRDcluster *c = NULL;
424 fTracklet->ResetClusterIter(kFALSE);
425 while((c = fTracklet->PrevCluster())){
426 Float_t xc = c->GetX()+fXcorr[c->GetDetector()][c->GetLocalTimeBin()];
427 Float_t yc = c->GetY();
428 Float_t zc = c->GetZ();
429 Float_t dx = x0 - xc;
430 Float_t yt = y0 - dx*dydx;
431 Float_t zt = z0 - dx*dzdx;
432 dy[0] = yc-yt; dz[0]= zc-zt;
435 dy[1] = cost*(dy[0] - dz[0]*tilt);
436 dz[1] = cost*(dz[0] + dy[0]*tilt);
437 if(pt>fPtThreshold && c->IsInChamber()) ((TH3S*)arr->At(0))->Fill(fTracklet->GetYref(1), dy[0], sgm[fSegmentLevel]);
439 // tilt rotation of covariance for clusters
440 Double_t sy2(c->GetSigmaY2()), sz2(c->GetSigmaZ2());
441 cov[0] = (sy2+t2*sz2)*corr;
442 cov[1] = tilt*(sz2 - sy2)*corr;
443 cov[2] = (t2*sy2+sz2)*corr;
444 // sum with track covariance
445 cov[0]+=covR[0]; cov[1]+=covR[1]; cov[2]+=covR[2];
446 Double_t dyz[2]= {dy[1], dz[1]};
447 Pulls(dyz, cov, tilt);
448 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
450 // Get z-position with respect to anode wire
451 Int_t istk = geo->GetStack(c->GetDetector());
452 AliTRDpadPlane *pp = geo->GetPadPlane(ily, istk);
453 Float_t row0 = pp->GetRow0();
454 Float_t d = row0 - zt + pp->GetAnodeWireOffset();
455 d -= ((Int_t)(2 * d)) / 2.0;
456 if (d > 0.25) d = 0.5 - d;
458 AliTRDclusterInfo *clInfo(NULL);
459 clInfo = new AliTRDclusterInfo;
460 clInfo->SetCluster(c);
461 Float_t covF[] = {cov[0], cov[1], cov[2]};
462 clInfo->SetGlobalPosition(yt, zt, dydx, dzdx, covF);
463 clInfo->SetResolution(dy[1]);
464 clInfo->SetAnisochronity(d);
465 clInfo->SetDriftLength(dx);
466 clInfo->SetTilt(tilt);
467 if(fCl) fCl->Add(clInfo);
468 else AliDebug(1, "Cl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
472 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
473 clInfoArr->SetOwner(kFALSE);
475 clInfoArr->Add(clInfo);
478 if(DebugLevel()>=1 && clInfoArr){
479 (*DebugStream()) << "cluster"
480 <<"status=" << status
481 <<"clInfo.=" << clInfoArr
486 if(clInfoArr) delete clInfoArr;
488 return (TH3S*)arr->At(0);
492 //________________________________________________________
493 TH1* AliTRDresolution::PlotTracklet(const AliTRDtrackV1 *track)
495 // Plot normalized residuals for tracklets to track.
497 // We start from the result that if X=N(|m|, |Cov|)
499 // (Cov^{-1})^{1/2}X = N((Cov^{-1})^{1/2}*|m|, |1|)
501 // in our case X=(y_trklt - y_trk z_trklt - z_trk) and |Cov| = |Cov_trklt| + |Cov_trk| at the radial
502 // reference position.
503 if(track) fkTrack = track;
505 AliDebug(4, "No Track defined.");
508 TObjArray *arr = NULL;
509 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrack ))){
510 AliWarning("No output container defined.");
515 Double_t cov[3], covR[7]/*, sqr[3], inv[3]*/;
516 Double_t pt, phi, tht, x, y, z, dx, dy[2], dz[2];
517 AliTRDseedV1 *fTracklet(NULL);
518 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++){
519 if(!(fTracklet = fkTrack->GetTracklet(il))) continue;
520 if(!fTracklet->IsOK()) continue;
521 sgm[2] = fTracklet->GetDetector();
522 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
523 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
524 x = fTracklet->GetX();
525 y = fTracklet->GetY();
526 z = fTracklet->GetZ();
527 dx = fTracklet->GetX0() - x;
528 pt = fTracklet->GetPt();
529 phi = fTracklet->GetYref(1);
530 tht = fTracklet->GetZref(1);
532 dy[0]= fTracklet->GetYref(0)-dx*fTracklet->GetYref(1) - y;
533 dz[0]= fTracklet->GetZref(0)-dx*fTracklet->GetZref(1) - z;
534 Double_t tilt(fTracklet->GetTilt())
537 ,cost(TMath::Sqrt(corr));
538 Bool_t rc(fTracklet->IsRowCross());
540 // calculate residuals using tilt rotation
541 dy[1]= cost*(dy[0] - dz[0]*tilt);
542 dz[1]= cost*(dz[0] + dy[0]*tilt);
543 ((TH3S*)arr->At(0))->Fill(phi, dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
544 if(rc) ((TH2S*)arr->At(2))->Fill(tht, dz[1]);
546 // compute covariance matrix
547 fTracklet->GetCovAt(x, cov);
548 fTracklet->GetCovRef(covR);
549 cov[0] += covR[0]; cov[1] += covR[1]; cov[2] += covR[2];
550 Double_t dyz[2]= {dy[1], dz[1]};
551 Pulls(dyz, cov, tilt);
552 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
553 ((TH3S*)arr->At(3))->Fill(tht, dyz[1], rc);
555 // calculate angular residuals and correct for tilt
556 Double_t phiTrklt = fTracklet->GetYfit(1);
557 phiTrklt += tilt*tht;
558 Double_t dphi((phi-phiTrklt)/(1-phi*phiTrklt));
559 Double_t dtht((tht-fTracklet->GetZfit(1))/(1-tht*fTracklet->GetZfit(1)));
560 ((TH3S*)arr->At(4))->Fill(phi, TMath::ATan(dphi), sgm[fSegmentLevel]);
563 UChar_t err(fTracklet->GetErrorMsg());
564 Double_t yt = fTracklet->GetYref(0),
565 ytx= fTracklet->GetYref(0)-dx*fTracklet->GetYref(1);
566 Int_t ncl = fTracklet->GetN();
567 (*DebugStream()) << "tracklet"
592 return (TH2I*)arr->At(0);
596 //________________________________________________________
597 TH1* AliTRDresolution::PlotTrackIn(const AliTRDtrackV1 *track)
599 // Store resolution/pulls of Kalman before updating with the TRD information
600 // at the radial position of the first tracklet. The following points are used
602 // - the (y,z,snp) of the first TRD tracklet
603 // - the (y, z, snp, tgl, pt) of the MC track reference
605 // Additionally the momentum resolution/pulls are calculated for usage in the
608 if(track) fkTrack = track;
610 AliDebug(4, "No Track defined.");
613 TObjArray *arr = NULL;
614 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackIn))){
615 AliWarning("No output container defined.");
618 AliExternalTrackParam *tin = NULL;
619 if(!(tin = fkTrack->GetTrackIn())){
620 AliWarning("Track did not entered TRD fiducial volume.");
625 Double_t x = tin->GetX();
626 AliTRDseedV1 *fTracklet = NULL;
627 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
628 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
631 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
632 AliDebug(1, "Tracklet did not match Track.");
636 sgm[2] = fTracklet->GetDetector();
637 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
638 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
639 Double_t tilt(fTracklet->GetTilt())
642 ,cost(TMath::Sqrt(corr));
643 Bool_t rc(fTracklet->IsRowCross());
645 const Int_t kNPAR(5);
646 Double_t parR[kNPAR]; memcpy(parR, tin->GetParameter(), kNPAR*sizeof(Double_t));
647 Double_t covR[3*kNPAR]; memcpy(covR, tin->GetCovariance(), 3*kNPAR*sizeof(Double_t));
648 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
650 // define sum covariances
651 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
652 Double_t *pc = &covR[0], *pp = &parR[0];
653 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
655 for(Int_t ic = 0; ic<=ir; ic++,pc++){
656 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
659 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
660 //COV.Print(); PAR.Print();
662 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
663 Double_t dy[2]={parR[0] - fTracklet->GetY(), 0.}
664 ,dz[2]={parR[1] - fTracklet->GetZ(), 0.}
665 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
666 // calculate residuals using tilt rotation
667 dy[1] = cost*(dy[0] - dz[0]*tilt);
668 dz[1] = cost*(dz[0] + dy[0]*tilt);
670 if(1./PAR[4]>fPtThreshold) ((TH3S*)arr->At(0))->Fill(fTracklet->GetYref(1), dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
671 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
672 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
674 Double_t dyz[2] = {dy[1], dz[1]};
675 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
676 Pulls(dyz, cc, tilt);
677 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
678 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
682 // register reference histo for mini-task
683 h = (TH2I*)arr->At(0);
686 (*DebugStream()) << "trackIn"
692 Double_t y = fTracklet->GetY();
693 Double_t z = fTracklet->GetZ();
694 (*DebugStream()) << "trackletIn"
704 if(!HasMCdata()) return h;
706 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
707 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
708 Int_t pdg = fkMC->GetPDG(),
709 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
711 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
712 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
713 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
715 // translate to reference radial position
716 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
717 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
719 TVectorD PARMC(kNPAR);
720 PARMC[0]=y0; PARMC[1]=z0;
721 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
724 // TMatrixDSymEigen eigen(COV);
725 // TVectorD evals = eigen.GetEigenValues();
726 // TMatrixDSym evalsm(kNPAR);
727 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
728 // TMatrixD evecs = eigen.GetEigenVectors();
729 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
732 if(!(arr = (TObjArray*)fContainer->At(kMCtrackIn))) {
733 AliWarning("No MC container defined.");
737 // y resolution/pulls
738 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
739 ((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)));
740 // z resolution/pulls
741 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
742 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
743 // phi resolution/snp pulls
744 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
745 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
746 // theta resolution/tgl pulls
747 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
748 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
749 // pt resolution\\1/pt pulls\\p resolution/pull
750 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
751 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
753 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
754 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
755 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
757 // p*p*PAR[4]*PAR[4]*COV(4,4)
758 // +2.*PAR[3]*COV(3,4)/PAR[4]
759 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
760 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
764 (*DebugStream()) << "trackInMC"
771 //________________________________________________________
772 TH1* AliTRDresolution::PlotTrackOut(const AliTRDtrackV1 *track)
774 // Store resolution/pulls of Kalman after last update with the TRD information
775 // at the radial position of the first tracklet. The following points are used
777 // - the (y,z,snp) of the first TRD tracklet
778 // - the (y, z, snp, tgl, pt) of the MC track reference
780 // Additionally the momentum resolution/pulls are calculated for usage in the
783 if(track) fkTrack = track;
787 AliDebug(4, "No Track defined.");
790 TObjArray *arr = NULL;
791 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackOut))){
792 AliWarning("No output container defined.");
795 AliExternalTrackParam *tout = NULL;
796 if(!(tout = fkTrack->GetTrackOut())){
797 AliDebug(2, "Track did not exit TRD.");
802 Double_t x = tout->GetX();
803 AliTRDseedV1 *fTracklet(NULL);
804 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
805 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
808 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
809 AliDebug(1, "Tracklet did not match Track position.");
813 sgm[2] = fTracklet->GetDetector();
814 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
815 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
816 Double_t tilt(fTracklet->GetTilt())
819 ,cost(TMath::Sqrt(corr));
820 Bool_t rc(fTracklet->IsRowCross());
822 const Int_t kNPAR(5);
823 Double_t parR[kNPAR]; memcpy(parR, tout->GetParameter(), kNPAR*sizeof(Double_t));
824 Double_t covR[3*kNPAR]; memcpy(covR, tout->GetCovariance(), 3*kNPAR*sizeof(Double_t));
825 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
827 // define sum covariances
828 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
829 Double_t *pc = &covR[0], *pp = &parR[0];
830 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
832 for(Int_t ic = 0; ic<=ir; ic++,pc++){
833 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
836 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
837 //COV.Print(); PAR.Print();
839 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
840 Double_t dy[3]={parR[0] - fTracklet->GetY(), 0., 0.}
841 ,dz[3]={parR[1] - fTracklet->GetZ(), 0., 0.}
842 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
843 // calculate residuals using tilt rotation
844 dy[1] = cost*(dy[0] - dz[0]*tilt);
845 dz[1] = cost*(dz[0] + dy[0]*tilt);
847 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 !!!
848 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
849 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
851 Double_t dyz[2] = {dy[1], dz[1]};
852 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
853 Pulls(dyz, cc, tilt);
854 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
855 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
857 // register reference histo for mini-task
858 h = (TH2I*)arr->At(0);
861 (*DebugStream()) << "trackOut"
867 Double_t y = fTracklet->GetY();
868 Double_t z = fTracklet->GetZ();
869 (*DebugStream()) << "trackletOut"
879 if(!HasMCdata()) return h;
881 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
882 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
883 Int_t pdg = fkMC->GetPDG(),
884 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
886 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
887 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
888 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
890 // translate to reference radial position
891 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
892 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
894 TVectorD PARMC(kNPAR);
895 PARMC[0]=y0; PARMC[1]=z0;
896 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
899 // TMatrixDSymEigen eigen(COV);
900 // TVectorD evals = eigen.GetEigenValues();
901 // TMatrixDSym evalsm(kNPAR);
902 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
903 // TMatrixD evecs = eigen.GetEigenVectors();
904 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
907 if(!(arr = (TObjArray*)fContainer->At(kMCtrackOut))){
908 AliWarning("No MC container defined.");
911 // y resolution/pulls
912 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
913 ((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)));
914 // z resolution/pulls
915 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
916 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
917 // phi resolution/snp pulls
918 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
919 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
920 // theta resolution/tgl pulls
921 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
922 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
923 // pt resolution\\1/pt pulls\\p resolution/pull
924 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
925 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
927 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
928 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
929 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
931 // p*p*PAR[4]*PAR[4]*COV(4,4)
932 // +2.*PAR[3]*COV(3,4)/PAR[4]
933 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
934 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
938 (*DebugStream()) << "trackOutMC"
946 //________________________________________________________
947 TH1* AliTRDresolution::PlotMC(const AliTRDtrackV1 *track)
950 // Plot MC distributions
954 AliDebug(2, "No MC defined. Results will not be available.");
957 if(track) fkTrack = track;
959 AliDebug(4, "No Track defined.");
963 AliWarning("No output container defined.");
966 // retriev track characteristics
967 Int_t pdg = fkMC->GetPDG(),
968 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
971 label(fkMC->GetLabel());
972 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
973 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
974 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
976 TObjArray *arr(NULL);TH1 *h(NULL);
978 Double_t xAnode, x, y, z, pt, dydx, dzdx, dzdl;
979 Float_t pt0, x0, y0, z0, dx, dy, dz, dydx0, dzdx0;
980 Double_t covR[7]/*, cov[3]*/;
983 TVectorD dX(12), dY(12), dZ(12), vPt(12), dPt(12), cCOV(12*15);
984 fkMC->PropagateKalman(&dX, &dY, &dZ, &vPt, &dPt, &cCOV);
985 (*DebugStream()) << "MCkalman"
995 AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
996 AliTRDseedV1 *fTracklet(NULL); TObjArray *clInfoArr(NULL);
997 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
998 if(!(fTracklet = fkTrack->GetTracklet(ily)))/* ||
999 !fTracklet->IsOK())*/ continue;
1001 sgm[2] = fTracklet->GetDetector();
1002 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
1003 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
1004 Double_t tilt(fTracklet->GetTilt())
1007 ,cost(TMath::Sqrt(corr));
1008 x0 = fTracklet->GetX0();
1009 //radial shift with respect to the MC reference (radial position of the pad plane)
1010 x= fTracklet->GetX();
1011 Bool_t rc(fTracklet->IsRowCross());
1012 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
1013 xAnode = fTracklet->GetX0();
1015 // MC track position at reference radial position
1017 if(DebugLevel()>=4){
1018 (*DebugStream()) << "MC"
1030 Float_t ymc = y0 - dx*dydx0;
1031 Float_t zmc = z0 - dx*dzdx0;
1032 //p = pt0*TMath::Sqrt(1.+dzdx0*dzdx0); // pt -> p
1034 // Kalman position at reference radial position
1036 dydx = fTracklet->GetYref(1);
1037 dzdx = fTracklet->GetZref(1);
1038 dzdl = fTracklet->GetTgl();
1039 y = fTracklet->GetYref(0) - dx*dydx;
1041 z = fTracklet->GetZref(0) - dx*dzdx;
1043 pt = TMath::Abs(fTracklet->GetPt());
1044 fTracklet->GetCovRef(covR);
1046 arr = (TObjArray*)((TObjArray*)fContainer->At(kMCtrack))->At(ily);
1047 // y resolution/pulls
1048 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1049 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(covR[0]), dz/TMath::Sqrt(covR[2]));
1050 // z resolution/pulls
1051 ((TH3S*)arr->At(2))->Fill(dzdx0, dz, 0);
1052 ((TH3S*)arr->At(3))->Fill(dzdx0, dz/TMath::Sqrt(covR[2]), 0);
1053 // phi resolution/ snp pulls
1054 Double_t dtgp = (dydx - dydx0)/(1.- dydx*dydx0);
1055 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dtgp));
1056 Double_t dsnp = dydx/TMath::Sqrt(1.+dydx*dydx) - dydx0/TMath::Sqrt(1.+dydx0*dydx0);
1057 ((TH2I*)arr->At(5))->Fill(dydx0, dsnp/TMath::Sqrt(covR[3]));
1058 // theta resolution/ tgl pulls
1059 Double_t dzdl0 = dzdx0/TMath::Sqrt(1.+dydx0*dydx0),
1060 dtgl = (dzdl - dzdl0)/(1.- dzdl*dzdl0);
1061 ((TH2I*)arr->At(6))->Fill(dzdl0,
1063 ((TH2I*)arr->At(7))->Fill(dzdl0, (dzdl - dzdl0)/TMath::Sqrt(covR[4]));
1064 // pt resolution \\ 1/pt pulls \\ p resolution for PID
1065 Double_t p0 = TMath::Sqrt(1.+ dzdl0*dzdl0)*pt0,
1066 p = TMath::Sqrt(1.+ dzdl*dzdl)*pt;
1067 ((TH3S*)((TObjArray*)arr->At(8)))->Fill(pt0, pt/pt0-1., sign*sIdx);
1068 ((TH3S*)((TObjArray*)arr->At(9)))->Fill(1./pt0, (1./pt-1./pt0)/TMath::Sqrt(covR[6]), sign*sIdx);
1069 ((TH3S*)((TObjArray*)arr->At(10)))->Fill(p0, p/p0-1., sign*sIdx);
1071 // Fill Debug stream for Kalman track
1072 if(DebugLevel()>=4){
1073 (*DebugStream()) << "MCtrack"
1080 << "s2y=" << covR[0]
1081 << "s2z=" << covR[2]
1085 // recalculate tracklet based on the MC info
1086 AliTRDseedV1 tt(*fTracklet);
1087 tt.SetZref(0, z0 - (x0-xAnode)*dzdx0);
1088 tt.SetZref(1, dzdx0);
1089 tt.SetReconstructor(AliTRDinfoGen::Reconstructor());
1091 x= tt.GetX();y= tt.GetY();z= tt.GetZ();
1092 dydx = tt.GetYfit(1);
1094 ymc = y0 - dx*dydx0;
1095 zmc = z0 - dx*dzdx0;
1098 Float_t dphi = (dydx - dydx0);
1099 dphi /= (1.- dydx*dydx0);
1101 // add tracklet residuals for y and dydx
1102 arr = (TObjArray*)fContainer->At(kMCtracklet);
1104 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1105 if(tt.GetS2Y()>0. && tt.GetS2Z()>0.) ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(tt.GetS2Y()), dz/TMath::Sqrt(tt.GetS2Z()));
1106 ((TH3S*)arr->At(2))->Fill(dzdl0, dz, rc);
1107 if(tt.GetS2Z()>0.) ((TH3S*)arr->At(3))->Fill(dzdl0, dz/TMath::Sqrt(tt.GetS2Z()), rc);
1108 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dphi));
1110 // Fill Debug stream for tracklet
1111 if(DebugLevel()>=4){
1112 Float_t s2y = tt.GetS2Y();
1113 Float_t s2z = tt.GetS2Z();
1114 (*DebugStream()) << "MCtracklet"
1125 AliTRDpadPlane *pp = geo->GetPadPlane(ily, AliTRDgeometry::GetStack(sgm[2]));
1126 Float_t zr0 = pp->GetRow0() + pp->GetAnodeWireOffset();
1127 //Double_t exb = AliTRDCommonParam::Instance()->GetOmegaTau(1.5);
1129 arr = (TObjArray*)fContainer->At(kMCcluster);
1130 AliTRDcluster *c = NULL;
1131 tt.ResetClusterIter(kFALSE);
1132 while((c = tt.PrevCluster())){
1133 Float_t q = TMath::Abs(c->GetQ());
1134 x = c->GetX()+fXcorr[c->GetDetector()][c->GetLocalTimeBin()]; y = c->GetY();z = c->GetZ();
1138 dy = cost*(y - ymc - tilt*(z-zmc));
1139 dz = cost*(z - zmc + tilt*(y-ymc));
1142 if(q>20. && q<250. && pt0>fPtThreshold && c->IsInChamber()){
1143 ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1144 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(c->GetSigmaY2()), dz/TMath::Sqrt(c->GetSigmaZ2()));
1147 // Fill calibration container
1148 Float_t d = zr0 - zmc;
1149 d -= ((Int_t)(2 * d)) / 2.0;
1150 if (d > 0.25) d = 0.5 - d;
1151 AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
1152 clInfo->SetCluster(c);
1153 clInfo->SetMC(pdg, label);
1154 clInfo->SetGlobalPosition(ymc, zmc, dydx0, dzdx0);
1155 clInfo->SetResolution(dy);
1156 clInfo->SetAnisochronity(d);
1157 clInfo->SetDriftLength(dx);
1158 clInfo->SetTilt(tilt);
1159 if(fMCcl) fMCcl->Add(clInfo);
1160 else AliDebug(1, "MCcl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
1161 if(DebugLevel()>=5){
1163 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
1164 clInfoArr->SetOwner(kFALSE);
1166 clInfoArr->Add(clInfo);
1170 if(DebugLevel()>=5 && clInfoArr){
1171 (*DebugStream()) << "MCcluster"
1172 <<"clInfo.=" << clInfoArr
1177 if(clInfoArr) delete clInfoArr;
1182 //________________________________________________________
1183 Bool_t AliTRDresolution::GetRefFigure(Int_t ifig)
1186 // Get the reference figures
1189 Float_t xy[4] = {0., 0., 0., 0.};
1191 AliWarning("Please provide a canvas to draw results.");
1194 Int_t selection[100], n(0), selStart(0); //
1195 Int_t ly0(0), dly(5);
1196 //Int_t ly0(1), dly(2); // used for SA
1197 TList *l(NULL); TVirtualPad *pad(NULL);
1198 TGraphErrors *g(NULL);TGraphAsymmErrors *ga(NULL);
1200 case 0: // charge resolution
1201 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1202 ((TVirtualPad*)l->At(0))->cd();
1203 ga=((TGraphAsymmErrors*)((TObjArray*)fGraphM->At(kCharge))->At(0));
1204 if(ga->GetN()) ga->Draw("apl");
1205 ((TVirtualPad*)l->At(1))->cd();
1206 g = ((TGraphErrors*)((TObjArray*)fGraphS->At(kCharge))->At(0));
1207 if(g->GetN()) g->Draw("apl");
1209 case 1: // cluster2track residuals
1210 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1211 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1212 pad = (TVirtualPad*)l->At(0); pad->cd();
1213 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1214 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1215 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1216 pad=(TVirtualPad*)l->At(1); pad->cd();
1217 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1218 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1219 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1221 case 2: // cluster2track residuals
1222 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1223 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1224 pad = (TVirtualPad*)l->At(0); pad->cd();
1225 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1226 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1227 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1228 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-0.5; xy[3] = 2.5;
1229 pad=(TVirtualPad*)l->At(1); pad->cd();
1230 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1231 if(!GetGraphArray(xy, kCluster, 1, 1)) break;
1234 gPad->Divide(3, 2, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1235 xy[0] = -.3; xy[1] = -20.; xy[2] = .3; xy[3] = 100.;
1236 ((TVirtualPad*)l->At(0))->cd();
1237 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1238 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1240 ((TVirtualPad*)l->At(1))->cd();
1241 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1242 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1244 ((TVirtualPad*)l->At(2))->cd();
1245 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1246 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1248 ((TVirtualPad*)l->At(3))->cd();
1249 selStart=fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1250 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1252 ((TVirtualPad*)l->At(4))->cd();
1253 selStart=fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1254 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1256 ((TVirtualPad*)l->At(5))->cd();
1257 selStart=2*fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1258 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1261 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1263 xy[0] = -1.; xy[1] = -150.; xy[2] = 1.; xy[3] = 1000.;
1264 ((TVirtualPad*)l->At(0))->cd();
1266 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1268 xy[0] = -1.; xy[1] = -1500.; xy[2] = 1.; xy[3] = 10000.;
1269 ((TVirtualPad*)l->At(1))->cd();
1271 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1274 case 5: // kTrack pulls
1275 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1277 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1278 ((TVirtualPad*)l->At(0))->cd();
1279 if(!GetGraphArray(xy, kTrack, 1, 1)) break;
1281 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1282 ((TVirtualPad*)l->At(1))->cd();
1283 if(!GetGraphArray(xy, kTrack, 3, 1)) break;
1285 case 6: // kTrack phi
1286 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1287 if(GetGraph(&xy[0], kTrack , 4)) return kTRUE;
1289 case 7: // kTrackIn y
1290 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1291 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1292 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1293 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1294 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1295 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1296 pad=((TVirtualPad*)l->At(1)); pad->cd();
1297 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1298 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1299 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1301 case 8: // kTrackIn y
1302 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1303 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1304 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1305 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1306 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1307 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1308 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1309 pad=((TVirtualPad*)l->At(1)); pad->cd();
1310 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1311 if(!GetGraphArray(xy, kTrackIn, 1, 1)) break;
1313 case 9: // kTrackIn z
1314 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1315 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1316 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1317 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1319 if(!GetGraphArray(xy, kTrackIn, 2, 1, 1, selection)) break;
1320 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1321 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1322 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1323 if(!GetGraphArray(xy, kTrackIn, 3, 1)) break;
1325 case 10: // kTrackIn phi
1326 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1327 if(GetGraph(&xy[0], kTrackIn, 4)) return kTRUE;
1329 case 11: // kTrackOut y
1330 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1331 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1332 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1333 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1334 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1335 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1336 pad=((TVirtualPad*)l->At(1)); pad->cd();
1337 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1338 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1339 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1341 case 12: // kTrackOut y
1342 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1343 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1344 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1345 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1346 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1347 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1348 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1349 pad=((TVirtualPad*)l->At(1)); pad->cd();
1350 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1351 if(!GetGraphArray(xy, kTrackOut, 1, 1)) break;
1353 case 13: // kTrackOut z
1354 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1355 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1356 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1357 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1358 if(!GetGraphArray(xy, kTrackOut, 2, 1)) break;
1359 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1360 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1361 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1362 if(!GetGraphArray(xy, kTrackOut, 3, 1)) break;
1364 case 14: // kTrackOut phi
1365 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1366 if(GetGraph(&xy[0], kTrackOut, 4)) return kTRUE;
1368 case 15: // kMCcluster
1369 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1370 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1371 ((TVirtualPad*)l->At(0))->cd();
1372 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1373 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1374 ((TVirtualPad*)l->At(1))->cd();
1375 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1376 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1378 case 16: // kMCcluster
1379 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1380 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1381 ((TVirtualPad*)l->At(0))->cd();
1382 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1383 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1384 ((TVirtualPad*)l->At(1))->cd();
1385 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1386 if(!GetGraphArray(xy, kMCcluster, 1, 1)) break;
1388 case 17: //kMCtracklet [y]
1389 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1390 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1391 ((TVirtualPad*)l->At(0))->cd();
1392 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1393 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1394 ((TVirtualPad*)l->At(1))->cd();
1395 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1396 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1398 case 18: //kMCtracklet [y]
1399 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1400 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1401 ((TVirtualPad*)l->At(0))->cd();
1402 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1403 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1404 ((TVirtualPad*)l->At(1))->cd();
1405 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1406 if(!GetGraphArray(xy, kMCtracklet, 1, 1)) break;
1408 case 19: //kMCtracklet [z]
1409 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1410 xy[0]=-1.; xy[1]=-100.; xy[2]=1.; xy[3] =2500.;
1411 ((TVirtualPad*)l->At(0))->cd();
1412 if(!GetGraphArray(xy, kMCtracklet, 2)) break;
1413 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1414 ((TVirtualPad*)l->At(1))->cd();
1415 if(!GetGraphArray(xy, kMCtracklet, 3)) break;
1417 case 20: //kMCtracklet [phi]
1418 xy[0]=-.3; xy[1]=-3.; xy[2]=.3; xy[3] =25.;
1419 if(!GetGraph(&xy[0], kMCtracklet, 4)) break;
1421 case 21: //kMCtrack [y] ly [0]
1422 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1423 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1424 ((TVirtualPad*)l->At(0))->cd();
1425 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1426 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1427 ((TVirtualPad*)l->At(1))->cd();
1428 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1429 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1431 case 22: //kMCtrack [y] ly [1]
1432 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1433 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1434 ((TVirtualPad*)l->At(0))->cd();
1435 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1436 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1437 ((TVirtualPad*)l->At(1))->cd();
1438 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1439 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1441 case 23: //kMCtrack [y] ly [2]
1442 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1443 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1444 ((TVirtualPad*)l->At(0))->cd();
1445 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1446 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1447 ((TVirtualPad*)l->At(1))->cd();
1448 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1449 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1451 case 24: //kMCtrack [y] ly [3]
1452 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1453 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1454 ((TVirtualPad*)l->At(0))->cd();
1455 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1456 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1457 ((TVirtualPad*)l->At(1))->cd();
1458 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1459 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1461 case 25: //kMCtrack [y] ly [4]
1462 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1463 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1464 ((TVirtualPad*)l->At(0))->cd();
1465 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1466 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1467 ((TVirtualPad*)l->At(1))->cd();
1468 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1469 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1471 case 26: //kMCtrack [y] ly [5]
1472 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1473 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1474 ((TVirtualPad*)l->At(0))->cd();
1475 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1476 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1477 ((TVirtualPad*)l->At(1))->cd();
1478 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1479 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1481 case 27: //kMCtrack [y pulls]
1482 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1483 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 5.5;
1484 ((TVirtualPad*)l->At(0))->cd();
1485 selStart=0; for(n=0; n<6; n++) selection[n]=selStart+n;
1486 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1487 ((TVirtualPad*)l->At(1))->cd();
1488 selStart=6; for(n=0; n<6; n++) selection[n]=selStart+n;
1489 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1491 case 28: //kMCtrack [z]
1492 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1493 xy[0]=-1.; xy[1]=-1500.; xy[2]=1.; xy[3] =6000.;
1494 ((TVirtualPad*)l->At(0))->cd();
1495 if(!GetGraphArray(xy, kMCtrack, 2)) break;
1496 xy[0] = -1.; xy[1] = -1.5; xy[2] = 1.; xy[3] = 5.;
1497 ((TVirtualPad*)l->At(1))->cd();
1498 if(!GetGraphArray(xy, kMCtrack, 3)) break;
1500 case 29: //kMCtrack [phi/snp]
1501 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1502 xy[0]=-.2; xy[1]=-0.5; xy[2]=.2; xy[3] =10.;
1503 ((TVirtualPad*)l->At(0))->cd();
1504 if(!GetGraphArray(xy, kMCtrack, 4)) break;
1505 xy[0] = -.2; xy[1] = -1.5; xy[2] = .2; xy[3] = 5.;
1506 ((TVirtualPad*)l->At(1))->cd();
1507 if(!GetGraphArray(xy, kMCtrack, 5)) break;
1509 case 30: //kMCtrack [theta/tgl]
1510 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1511 xy[0]=-1.; xy[1]=-0.5; xy[2]=1.; xy[3] =5.;
1512 ((TVirtualPad*)l->At(0))->cd();
1513 if(!GetGraphArray(xy, kMCtrack, 6)) break;
1514 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
1515 ((TVirtualPad*)l->At(1))->cd();
1516 if(!GetGraphArray(xy, kMCtrack, 7)) break;
1518 case 31: //kMCtrack [pt]
1519 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1520 pad = (TVirtualPad*)l->At(0); pad->cd();
1521 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1524 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1525 selection[n++] = il*11 + 2; // pi-
1526 selection[n++] = il*11 + 8; // pi+
1528 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1529 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1530 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#pi#pm")) break;
1531 pad->Modified(); pad->Update(); pad->SetLogx();
1532 pad = (TVirtualPad*)l->At(1); pad->cd();
1533 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1536 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1537 selection[n++] = il*11 + 3; // mu-
1538 selection[n++] = il*11 + 7; // mu+
1540 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#mu#pm")) break;
1541 pad->Modified(); pad->Update(); pad->SetLogx();
1543 case 32: //kMCtrack [pt]
1544 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1545 pad = (TVirtualPad*)l->At(0); pad->cd();
1546 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1549 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1550 selection[n++] = il*11 + 0; // p bar
1551 selection[n++] = il*11 + 10; // p
1553 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1554 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1555 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "p&p bar")) break;
1556 pad->Modified(); pad->Update(); pad->SetLogx();
1557 pad = (TVirtualPad*)l->At(1); pad->cd();
1558 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1561 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1562 selection[n++] = il*11 + 4; // e-
1563 selection[n++] = il*11 + 6; // e+
1565 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1566 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1567 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "e#pm")) break;
1568 pad->Modified(); pad->Update(); pad->SetLogx();
1570 case 33: //kMCtrack [1/pt] pulls
1571 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1572 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 4.5; // SA
1573 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1574 pad = (TVirtualPad*)l->At(0); pad->cd();
1575 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1578 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1579 selection[n++] = il*11 + 2; // pi-
1580 selection[n++] = il*11 + 8; // pi+
1582 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#pi#pm")) break;
1583 pad = (TVirtualPad*)l->At(1); pad->cd();
1584 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1587 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1588 selection[n++] = il*11 + 3; // mu-
1589 selection[n++] = il*11 + 7; // mu+
1591 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#mu#pm")) break;
1593 case 34: //kMCtrack [1/pt] pulls
1594 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1595 pad = (TVirtualPad*)l->At(0); pad->cd();
1596 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1599 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1600 selection[n++] = il*11 + 0; // p bar
1601 selection[n++] = il*11 + 10; // p
1603 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1604 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 6.; // SA
1605 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "p & p bar")) break;
1606 pad = (TVirtualPad*)l->At(1); pad->cd();
1607 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1610 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1611 selection[n++] = il*11 + 4; // e-
1612 selection[n++] = il*11 + 6; // e+
1614 xy[0] = 0.; xy[1] = -2.; xy[2] = 2.; xy[3] = 4.5;
1615 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "e#pm")) break;
1617 case 35: //kMCtrack [p]
1618 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1619 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1620 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1621 pad = (TVirtualPad*)l->At(0); pad->cd();
1622 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1625 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1626 selection[n++] = il*11 + 2; // pi-
1627 selection[n++] = il*11 + 8; // pi+
1629 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#pi#pm")) break;
1630 pad->Modified(); pad->Update(); pad->SetLogx();
1631 pad = (TVirtualPad*)l->At(1); pad->cd();
1632 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1635 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1636 selection[n++] = il*11 + 3; // mu-
1637 selection[n++] = il*11 + 7; // mu+
1639 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#mu#pm")) break;
1640 pad->Modified(); pad->Update(); pad->SetLogx();
1642 case 36: //kMCtrack [p]
1643 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1644 pad = (TVirtualPad*)l->At(0); pad->cd();
1645 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1648 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1649 selection[n++] = il*11 + 0; // p bar
1650 selection[n++] = il*11 + 10; // p
1652 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1653 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.; // SA
1654 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "p & p bar")) break;
1655 pad->Modified(); pad->Update(); pad->SetLogx();
1656 pad = (TVirtualPad*)l->At(1); pad->cd();
1657 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1660 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1661 selection[n++] = il*11 + 4; // e-
1662 selection[n++] = il*11 + 6; // e+
1664 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1665 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1666 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "e#pm")) break;
1667 pad->Modified(); pad->Update(); pad->SetLogx();
1669 case 37: // kMCtrackIn [y]
1670 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1671 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1672 ((TVirtualPad*)l->At(0))->cd();
1673 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1674 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1675 ((TVirtualPad*)l->At(1))->cd();
1676 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1677 if(!GetGraphArray(&xy[0], kMCtrackIn, 0, 1, n, selection)) break;
1679 case 38: // kMCtrackIn [y]
1680 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1681 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1682 ((TVirtualPad*)l->At(0))->cd();
1683 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1684 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1685 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1686 ((TVirtualPad*)l->At(1))->cd();
1687 if(!GetGraphArray(xy, kMCtrackIn, 1, 1)) break;
1689 case 39: // kMCtrackIn [z]
1690 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1691 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =800.;
1692 ((TVirtualPad*)l->At(0))->cd();
1693 if(!GetGraphArray(xy, kMCtrackIn, 2, 1)) break;
1694 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1695 ((TVirtualPad*)l->At(1))->cd();
1696 if(!GetGraphArray(xy, kMCtrackIn, 3, 1)) break;
1698 case 40: // kMCtrackIn [phi|snp]
1699 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1700 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1701 ((TVirtualPad*)l->At(0))->cd();
1702 if(!GetGraph(&xy[0], kMCtrackIn, 4)) break;
1703 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1704 ((TVirtualPad*)l->At(1))->cd();
1705 if(!GetGraph(&xy[0], kMCtrackIn, 5)) break;
1707 case 41: // kMCtrackIn [theta|tgl]
1708 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1709 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1710 ((TVirtualPad*)l->At(0))->cd();
1711 if(!GetGraph(&xy[0], kMCtrackIn, 6)) break;
1712 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 1.5;
1713 ((TVirtualPad*)l->At(1))->cd();
1714 if(!GetGraph(&xy[0], kMCtrackIn, 7)) break;
1716 case 42: // kMCtrackIn [pt]
1717 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1718 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1719 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.; // SA
1720 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1721 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1722 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1723 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1724 pad = (TVirtualPad*)l->At(1); pad->cd(); pad->SetLogx();
1725 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1726 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1727 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1729 case 43: //kMCtrackIn [1/pt] pulls
1730 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1731 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1732 pad = (TVirtualPad*)l->At(0); pad->cd();
1733 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1734 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1735 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1736 pad = (TVirtualPad*)l->At(1); pad->cd();
1737 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1738 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1739 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1741 case 44: // kMCtrackIn [p]
1742 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1743 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1744 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1745 pad = ((TVirtualPad*)l->At(0));pad->cd();pad->SetLogx();
1746 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1747 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1748 if(!GetGraphArray(xy, kMCtrackIn, 10, 1, n, selection)) break;
1749 pad = ((TVirtualPad*)l->At(1)); pad->cd();pad->SetLogx();
1750 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1751 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1752 if(!GetGraphArray(xy, kMCtrackIn, 10, 1, n, selection)) break;
1754 case 45: // kMCtrackOut [y]
1755 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1756 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1757 ((TVirtualPad*)l->At(0))->cd();
1758 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1759 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1760 ((TVirtualPad*)l->At(1))->cd();
1761 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1762 if(!GetGraphArray(&xy[0], kMCtrackOut, 0, 1, n, selection)) break;
1764 case 46: // kMCtrackOut [y]
1765 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1766 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1767 ((TVirtualPad*)l->At(0))->cd();
1768 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1769 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1770 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1771 ((TVirtualPad*)l->At(1))->cd();
1772 if(!GetGraphArray(xy, kMCtrackOut, 1, 1)) break;
1774 case 47: // kMCtrackOut [z]
1775 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1776 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =1500.;
1777 ((TVirtualPad*)l->At(0))->cd();
1778 if(!GetGraphArray(xy, kMCtrackOut, 2, 1)) break;
1779 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1780 ((TVirtualPad*)l->At(1))->cd();
1781 if(!GetGraphArray(xy, kMCtrackOut, 3, 1)) break;
1783 case 48: // kMCtrackOut [phi|snp]
1784 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1785 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1786 ((TVirtualPad*)l->At(0))->cd();
1787 if(!GetGraph(&xy[0], kMCtrackOut, 4)) break;
1788 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1789 ((TVirtualPad*)l->At(1))->cd();
1790 if(!GetGraph(&xy[0], kMCtrackOut, 5)) break;
1792 case 49: // kMCtrackOut [theta|tgl]
1793 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1794 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1795 ((TVirtualPad*)l->At(0))->cd();
1796 if(!GetGraph(&xy[0], kMCtrackOut, 6)) break;
1797 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 15.;
1798 ((TVirtualPad*)l->At(1))->cd();
1799 if(!GetGraph(&xy[0], kMCtrackOut, 7)) break;
1801 case 50: // kMCtrackOut [pt]
1802 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1803 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1804 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1805 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1806 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1807 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1808 pad = (TVirtualPad*)l->At(1); pad->cd();pad->SetLogx();
1809 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1810 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1811 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1813 case 51: //kMCtrackOut [1/pt] pulls
1814 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1815 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1816 pad = (TVirtualPad*)l->At(0); pad->cd();
1817 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1818 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1819 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1820 pad = (TVirtualPad*)l->At(1); pad->cd();
1821 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1822 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1823 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1825 case 52: // kMCtrackOut [p]
1826 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1827 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1828 pad = ((TVirtualPad*)l->At(0));pad->cd();pad->SetLogx();
1829 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1830 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1831 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1832 pad = ((TVirtualPad*)l->At(1)); pad->cd();pad->SetLogx();
1833 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1834 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1835 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1838 AliWarning(Form("Reference plot [%d] missing result", ifig));
1842 //________________________________________________________
1843 void AliTRDresolution::MakeSummary()
1845 // Build summary plots
1847 if(!fGraphS || !fGraphM){
1848 AliError("Missing results");
1851 Float_t xy[4] = {0., 0., 0., 0.};
1853 TH2 *h2 = new TH2I("h2SF", "", 20, -.2, .2, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5);
1854 h2->GetXaxis()->CenterTitle();
1855 h2->GetYaxis()->CenterTitle();
1856 h2->GetZaxis()->CenterTitle();h2->GetZaxis()->SetTitleOffset(1.4);
1858 Int_t ih2(0), iSumPlot(0);
1859 TCanvas *cOut = new TCanvas(Form("TRDsummary%s_%d", GetName(), iSumPlot++), "Cluster & Tracklet Resolution", 1024, 768);
1860 cOut->Divide(3,2, 2.e-3, 2.e-3, kYellow-7);
1861 TVirtualPad *p(NULL);
1864 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1865 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1866 h2->SetTitle(Form("Cluster-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1867 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kCluster))->At(0), h2);
1868 GetRange(h2, 1, range);
1869 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1874 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1875 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1876 h2->SetTitle(Form("Cluster-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1877 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kCluster))->At(0), h2);
1878 GetRange(h2, 0, range);
1879 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1884 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1885 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1886 if(!GetGraphArray(xy, kCluster, 1, 1)) return;
1889 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1890 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1891 h2->SetTitle(Form("Tracklet-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1892 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kTrack))->At(0), h2);
1893 GetRange(h2, 1, range);
1894 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1899 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1900 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1901 h2->SetTitle(Form("Tracklet-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1902 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kTrack))->At(0), h2);
1903 GetRange(h2, 0, range);
1904 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1909 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1910 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1911 if(!GetGraphArray(xy, kTrack, 1, 1)) return;
1913 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1916 (!fGraphS->At(kMCcluster) || !fGraphM->At(kMCcluster) ||
1917 !fGraphS->At(kMCtracklet) || !fGraphM->At(kMCtracklet))){
1921 cOut->Clear(); cOut->SetName(Form("TRDsummary%s_%d", GetName(), iSumPlot++));
1922 cOut->Divide(3, 2, 2.e-3, 2.e-3, kBlue-10);
1925 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1926 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1927 h2->SetTitle(Form("Cluster-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1928 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCcluster))->At(0), h2);
1929 GetRange(h2, 1, range);
1930 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1935 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1936 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1938 h2->SetTitle(Form("Cluster-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1939 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCcluster))->At(0), h2);
1940 GetRange(h2, 0, range);
1941 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1946 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1947 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1948 if(!GetGraphArray(xy, kMCcluster, 1, 1)) AliWarning("Missing MC cluster plot.");
1951 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1952 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1954 h2->SetTitle(Form("Tracklet-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1955 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCtracklet))->At(0), h2);
1956 GetRange(h2, 1, range);
1957 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1962 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1963 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1965 h2->SetTitle(Form("Tracklet-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1966 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCtracklet))->At(0), h2);
1967 GetRange(h2, 0, range);
1968 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1973 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1974 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1975 if(!GetGraphArray(xy, kMCtracklet, 1, 1)){
1976 AliWarning("Failed retrieve tracklet resolution plot.");
1979 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1983 //________________________________________________________
1984 void AliTRDresolution::GetRange(TH2 *h2, Char_t mod, Float_t *range)
1986 // Returns the range of the bulk of data in histogram h2. Removes outliers.
1987 // The "range" vector should be initialized with 2 elements
1988 // Option "mod" can be any of
1989 // - 0 : gaussian like distribution
1990 // - 1 : tailed distribution
1992 Int_t nx(h2->GetNbinsX())
1993 , ny(h2->GetNbinsY())
1995 Double_t *data=new Double_t[n];
1996 for(Int_t ix(1), in(0); ix<=nx; ix++){
1997 for(Int_t iy(1); iy<=ny; iy++)
1998 data[in++] = h2->GetBinContent(ix, iy);
2000 Double_t mean, sigm;
2001 AliMathBase::EvaluateUni(n, data, mean, sigm, Int_t(n*.8));
2003 range[0]=mean-3.*sigm; range[1]=mean+3.*sigm;
2004 if(mod==1) range[0]=TMath::Max(Float_t(1.e-3), range[0]);
2005 AliDebug(2, Form("h[%s] range0[%f %f]", h2->GetName(), range[0], range[1]));
2006 TH1S h1("h1SF0", "", 100, range[0], range[1]);
2011 case 0:// gaussian distribution
2013 TF1 fg("fg", "gaus", mean-3.*sigm, mean+3.*sigm);
2015 mean=fg.GetParameter(1); sigm=fg.GetParameter(2);
2016 range[0] = mean-2.5*sigm;range[1] = mean+2.5*sigm;
2017 AliDebug(2, Form(" rangeG[%f %f]", range[0], range[1]));
2020 case 1:// tailed distribution
2022 Int_t bmax(h1.GetMaximumBin());
2023 Int_t jBinMin(1), jBinMax(100);
2024 for(Int_t ibin(bmax); ibin--;){
2025 if(h1.GetBinContent(ibin)<1.){
2026 jBinMin=ibin; break;
2029 for(Int_t ibin(bmax); ibin++;){
2030 if(h1.GetBinContent(ibin)<1.){
2031 jBinMax=ibin; break;
2034 range[0]=h1.GetBinCenter(jBinMin); range[1]=h1.GetBinCenter(jBinMax);
2035 AliDebug(2, Form(" rangeT[%f %f]", range[0], range[1]));
2043 //________________________________________________________
2044 void AliTRDresolution::MakeSummaryPlot(TObjArray *a, TH2 *h2)
2046 // Core functionality for MakeSummary function.
2050 TGraphErrors *g(NULL); TAxis *ax(h2->GetXaxis());
2051 for(Int_t iseg(0); iseg<fgkNresYsegm[fSegmentLevel]; iseg++){
2052 g=(TGraphErrors*)a->At(iseg);
2053 for(Int_t in(0); in<g->GetN(); in++){
2054 g->GetPoint(in, x, y);
2055 h2->SetBinContent(ax->FindBin(x), iseg+1, y);
2061 //________________________________________________________
2062 Bool_t AliTRDresolution::PostProcess()
2064 // Fit, Project, Combine, Extract values from the containers filled during execution
2066 /*fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));*/
2068 AliError("ERROR: list not available");
2072 // define general behavior parameters
2073 const Color_t fgColorS[11]={
2074 kOrange, kOrange-3, kMagenta+1, kViolet, kRed,
2076 kRed, kViolet, kMagenta+1, kOrange-3, kOrange
2078 const Color_t fgColorM[11]={
2079 kCyan-5, kAzure-4, kBlue-7, kBlue+2, kViolet+10,
2081 kViolet+10, kBlue+2, kBlue-7, kAzure-4, kCyan-5
2083 const Marker_t fgMarker[11]={
2089 TGraph *gm= NULL, *gs= NULL;
2090 if(!fGraphS && !fGraphM){
2091 TObjArray *aM(NULL), *aS(NULL);
2092 Int_t n = fContainer->GetEntriesFast();
2093 fGraphS = new TObjArray(n); fGraphS->SetOwner();
2094 fGraphM = new TObjArray(n); fGraphM->SetOwner();
2095 for(Int_t ig(0), nc(0); ig<n; ig++){
2096 fGraphM->AddAt(aM = new TObjArray(fgNproj[ig]), ig);
2097 fGraphS->AddAt(aS = new TObjArray(fgNproj[ig]), ig);
2099 for(Int_t ic=0; ic<fgNproj[ig]; ic++, nc++){
2100 AliDebug(2, Form("building G[%d] P[%d] N[%d]", ig, ic, fNcomp[nc]));
2102 TObjArray *agS(NULL), *agM(NULL);
2103 aS->AddAt(agS = new TObjArray(fNcomp[nc]), ic);
2104 aM->AddAt(agM = new TObjArray(fNcomp[nc]), ic);
2105 for(Int_t is=fNcomp[nc]; is--;){
2106 agS->AddAt(gs = new TGraphErrors(), is);
2107 Int_t is0(is%11), il0(is/11);
2108 gs->SetMarkerStyle(fgMarker[is0]);
2109 gs->SetMarkerColor(fgColorS[is0]);
2110 gs->SetLineColor(fgColorS[is0]);
2111 gs->SetLineStyle(il0);gs->SetLineWidth(2);
2112 gs->SetName(Form("s_%d_%02d_%02d", ig, ic, is));
2114 agM->AddAt(gm = new TGraphErrors(), is);
2115 gm->SetMarkerStyle(fgMarker[is0]);
2116 gm->SetMarkerColor(fgColorM[is0]);
2117 gm->SetLineColor(fgColorM[is0]);
2118 gm->SetLineStyle(il0);gm->SetLineWidth(2);
2119 gm->SetName(Form("m_%d_%02d_%02d", ig, ic, is));
2120 // this is important for labels in the legend
2122 gs->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2123 gm->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2125 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"z":"y", is/2));
2126 gm->SetTitle(Form("%s Ly[%d]", is%2?"z":"y", is/2));
2127 } else if(ic==2||ic==3) {
2128 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"RC":"no RC", is/2));
2129 gm->SetTitle(Form("%s Ly[%d]", is%2?"RC":"no RC", is/2));
2131 gs->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2132 gm->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2134 gs->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2135 gm->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2139 aS->AddAt(gs = new TGraphErrors(), ic);
2140 gs->SetMarkerStyle(23);
2141 gs->SetMarkerColor(kRed);
2142 gs->SetLineColor(kRed);
2143 gs->SetNameTitle(Form("s_%d_%02d", ig, ic), "sigma");
2145 aM->AddAt(gm = ig ? (TGraph*)new TGraphErrors() : (TGraph*)new TGraphAsymmErrors(), ic);
2146 gm->SetLineColor(kBlack);
2147 gm->SetMarkerStyle(7);
2148 gm->SetMarkerColor(kBlack);
2149 gm->SetNameTitle(Form("m_%d_%02d", ig, ic), "mean");
2155 /* printf("\n\n\n"); fGraphS->ls();
2156 printf("\n\n\n"); fGraphM->ls();*/
2161 TF1 fg("fGauss", "gaus", -.5, .5);
2162 // Landau for charge resolution
2163 TF1 fch("fClCh", "landau", 0., 1000.);
2164 // Landau for e+- pt resolution
2165 TF1 fpt("fPt", "landau", -0.1, 0.2);
2167 //PROCESS EXPERIMENTAL DISTRIBUTIONS
2168 // Charge resolution
2169 //Process3DL(kCharge, 0, &fl);
2170 // Clusters residuals
2171 Process3D(kCluster, 0, &fg, 1.e4);
2172 Process3Dlinked(kCluster, 1, &fg);
2174 // Tracklet residual/pulls
2175 Process3D(kTrack , 0, &fg, 1.e4);
2176 Process3Dlinked(kTrack , 1, &fg);
2177 Process3D(kTrack , 2, &fg, 1.e4);
2178 Process3D(kTrack , 3, &fg);
2179 Process2D(kTrack , 4, &fg, 1.e3);
2181 // TRDin residual/pulls
2182 Process3D(kTrackIn, 0, &fg, 1.e4);
2183 Process3Dlinked(kTrackIn, 1, &fg);
2184 Process3D(kTrackIn, 2, &fg, 1.e4);
2185 Process3D(kTrackIn, 3, &fg);
2186 Process2D(kTrackIn, 4, &fg, 1.e3);
2188 // TRDout residual/pulls
2189 Process3D(kTrackOut, 0, &fg, 1.e3); // scale to fit - see PlotTrackOut
2190 Process3Dlinked(kTrackOut, 1, &fg);
2191 Process3D(kTrackOut, 2, &fg, 1.e4);
2192 Process3D(kTrackOut, 3, &fg);
2193 Process2D(kTrackOut, 4, &fg, 1.e3);
2196 if(!HasMCdata()) return kTRUE;
2199 //PROCESS MC RESIDUAL DISTRIBUTIONS
2201 // CLUSTER Y RESOLUTION/PULLS
2202 Process3D(kMCcluster, 0, &fg, 1.e4);
2203 Process3Dlinked(kMCcluster, 1, &fg, 1.);
2206 // TRACKLET RESOLUTION/PULLS
2207 Process3D(kMCtracklet, 0, &fg, 1.e4); // y
2208 Process3Dlinked(kMCtracklet, 1, &fg, 1.); // y pulls
2209 Process3D(kMCtracklet, 2, &fg, 1.e4); // z
2210 Process3D(kMCtracklet, 3, &fg, 1.); // z pulls
2211 Process2D(kMCtracklet, 4, &fg, 1.e3); // phi
2214 // TRACK RESOLUTION/PULLS
2215 Process3Darray(kMCtrack, 0, &fg, 1.e4); // y
2216 Process3DlinkedArray(kMCtrack, 1, &fg); // y PULL
2217 Process3Darray(kMCtrack, 2, &fg, 1.e4); // z
2218 Process3Darray(kMCtrack, 3, &fg); // z PULL
2219 Process2Darray(kMCtrack, 4, &fg, 1.e3); // phi
2220 Process2Darray(kMCtrack, 5, &fg); // snp PULL
2221 Process2Darray(kMCtrack, 6, &fg, 1.e3); // theta
2222 Process2Darray(kMCtrack, 7, &fg); // tgl PULL
2223 Process3Darray(kMCtrack, 8, &fg, 1.e2); // pt resolution
2224 Process3Darray(kMCtrack, 9, &fg); // 1/pt pulls
2225 Process3Darray(kMCtrack, 10, &fg, 1.e2); // p resolution
2228 // TRACK TRDin RESOLUTION/PULLS
2229 Process3D(kMCtrackIn, 0, &fg, 1.e4);// y resolution
2230 Process3Dlinked(kMCtrackIn, 1, &fg); // y pulls
2231 Process3D(kMCtrackIn, 2, &fg, 1.e4);// z resolution
2232 Process3D(kMCtrackIn, 3, &fg); // z pulls
2233 Process2D(kMCtrackIn, 4, &fg, 1.e3);// phi resolution
2234 Process2D(kMCtrackIn, 5, &fg); // snp pulls
2235 Process2D(kMCtrackIn, 6, &fg, 1.e3);// theta resolution
2236 Process2D(kMCtrackIn, 7, &fg); // tgl pulls
2237 Process3D(kMCtrackIn, 8, &fg, 1.e2);// pt resolution
2238 Process3D(kMCtrackIn, 9, &fg); // 1/pt pulls
2239 Process3D(kMCtrackIn, 10, &fg, 1.e2);// p resolution
2242 // TRACK TRDout RESOLUTION/PULLS
2243 Process3D(kMCtrackOut, 0, &fg, 1.e4);// y resolution
2244 Process3Dlinked(kMCtrackOut, 1, &fg); // y pulls
2245 Process3D(kMCtrackOut, 2, &fg, 1.e4);// z resolution
2246 Process3D(kMCtrackOut, 3, &fg); // z pulls
2247 Process2D(kMCtrackOut, 4, &fg, 1.e3);// phi resolution
2248 Process2D(kMCtrackOut, 5, &fg); // snp pulls
2249 Process2D(kMCtrackOut, 6, &fg, 1.e3);// theta resolution
2250 Process2D(kMCtrackOut, 7, &fg); // tgl pulls
2251 Process3D(kMCtrackOut, 8, &fg, 1.e2);// pt resolution
2252 Process3D(kMCtrackOut, 9, &fg); // 1/pt pulls
2253 Process3D(kMCtrackOut, 10, &fg, 1.e2);// p resolution
2260 //________________________________________________________
2261 void AliTRDresolution::Terminate(Option_t *opt)
2263 AliTRDrecoTask::Terminate(opt);
2264 if(HasPostProcess()) PostProcess();
2267 //________________________________________________________
2268 void AliTRDresolution::AdjustF1(TH1 *h, TF1 *f)
2270 // Helper function to avoid duplication of code
2271 // Make first guesses on the fit parameters
2273 // find the intial parameters of the fit !! (thanks George)
2274 Int_t nbinsy = Int_t(.5*h->GetNbinsX());
2276 for(Int_t jbin=nbinsy-4; jbin<=nbinsy+4; jbin++) sum+=h->GetBinContent(jbin); sum/=9.;
2277 f->SetParLimits(0, 0., 3.*sum);
2278 f->SetParameter(0, .9*sum);
2279 Double_t rms = h->GetRMS();
2280 f->SetParLimits(1, -rms, rms);
2281 f->SetParameter(1, h->GetMean());
2283 f->SetParLimits(2, 0., 2.*rms);
2284 f->SetParameter(2, rms);
2285 if(f->GetNpar() <= 4) return;
2287 f->SetParLimits(3, 0., sum);
2288 f->SetParameter(3, .1*sum);
2290 f->SetParLimits(4, -.3, .3);
2291 f->SetParameter(4, 0.);
2293 f->SetParLimits(5, 0., 1.e2);
2294 f->SetParameter(5, 2.e-1);
2297 //________________________________________________________
2298 TObjArray* AliTRDresolution::BuildMonitorContainerCluster(const char* name, Bool_t expand, Float_t range)
2300 // Build performance histograms for AliTRDcluster.vs TRD track or MC
2301 // - y reziduals/pulls
2303 TObjArray *arr = new TObjArray(2);
2304 arr->SetName(name); arr->SetOwner();
2305 TH1 *h(NULL); char hname[100], htitle[300];
2307 // tracklet resolution/pull in y direction
2308 snprintf(hname, 100, "%s_%s_Y", GetNameId(), name);
2309 snprintf(htitle, 300, "Y res for \"%s\" @ %s;tg(#phi);#Delta y [cm];%s", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2310 Float_t rr = range<0.?fDyRange:range;
2311 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2312 Int_t nybins=fgkNresYsegm[fSegmentLevel];
2313 if(expand) nybins*=2;
2314 h = new TH3S(hname, htitle,
2315 48, -.48, .48, // phi
2317 nybins, -0.5, nybins-0.5);// segment
2320 snprintf(hname, 100, "%s_%s_YZpull", GetNameId(), name);
2321 snprintf(htitle, 300, "YZ pull for \"%s\" @ %s;%s;#Delta y / #sigma_{y};#Delta z / #sigma_{z}", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2322 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2323 h = new TH3S(hname, htitle, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5, 100, -4.5, 4.5, 100, -4.5, 4.5);
2330 //________________________________________________________
2331 TObjArray* AliTRDresolution::BuildMonitorContainerTracklet(const char* name, Bool_t expand)
2333 // Build performance histograms for AliExternalTrackParam.vs TRD tracklet
2334 // - y reziduals/pulls
2335 // - z reziduals/pulls
2337 TObjArray *arr = BuildMonitorContainerCluster(name, expand, 0.05);
2339 TH1 *h(NULL); char hname[100], htitle[300];
2341 // tracklet resolution/pull in z direction
2342 snprintf(hname, 100, "%s_%s_Z", GetNameId(), name);
2343 snprintf(htitle, 300, "Z res for \"%s\" @ %s;tg(#theta);#Delta z [cm]", GetNameId(), name);
2344 if(!(h = (TH2S*)gROOT->FindObject(hname))){
2345 h = new TH2S(hname, htitle, 50, -1., 1., 100, -.05, .05);
2348 snprintf(hname, 100, "%s_%s_Zpull", GetNameId(), name);
2349 snprintf(htitle, 300, "Z pull for \"%s\" @ %s;tg(#theta);#Delta z / #sigma_{z};row cross", GetNameId(), name);
2350 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2351 h = new TH3S(hname, htitle, 50, -1., 1., 100, -5.5, 5.5, 2, -0.5, 1.5);
2352 h->GetZaxis()->SetBinLabel(1, "no RC");
2353 h->GetZaxis()->SetBinLabel(2, "RC");
2357 // tracklet to track phi resolution
2358 snprintf(hname, 100, "%s_%s_PHI", GetNameId(), name);
2359 snprintf(htitle, 300, "#Phi res for \"%s\" @ %s;tg(#phi);#Delta #phi [rad];%s", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2360 Int_t nsgms=fgkNresYsegm[fSegmentLevel];
2361 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2362 h = new TH3S(hname, htitle, 48, -.48, .48, 100, -.5, .5, nsgms, -0.5, nsgms-0.5);
2369 //________________________________________________________
2370 TObjArray* AliTRDresolution::BuildMonitorContainerTrack(const char* name)
2372 // Build performance histograms for AliExternalTrackParam.vs MC
2373 // - y resolution/pulls
2374 // - z resolution/pulls
2375 // - phi resolution, snp pulls
2376 // - theta resolution, tgl pulls
2377 // - pt resolution, 1/pt pulls, p resolution
2379 TObjArray *arr = BuildMonitorContainerTracklet(name);
2381 TH1 *h(NULL); char hname[100], htitle[300];
2385 snprintf(hname, 100, "%s_%s_SNPpull", GetNameId(), name);
2386 snprintf(htitle, 300, "SNP pull for \"%s\" @ %s;tg(#phi);#Delta snp / #sigma_{snp};entries", GetNameId(), name);
2387 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2388 h = new TH2I(hname, htitle, 60, -.3, .3, 100, -4.5, 4.5);
2393 snprintf(hname, 100, "%s_%s_THT", GetNameId(), name);
2394 snprintf(htitle, 300, "#Theta res for \"%s\" @ %s;tg(#theta);#Delta #theta [rad];entries", GetNameId(), name);
2395 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2396 h = new TH2I(hname, htitle, 100, -1., 1., 100, -5e-3, 5e-3);
2400 snprintf(hname, 100, "%s_%s_TGLpull", GetNameId(), name);
2401 snprintf(htitle, 300, "TGL pull for \"%s\" @ %s;tg(#theta);#Delta tgl / #sigma_{tgl};entries", GetNameId(), name);
2402 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2403 h = new TH2I(hname, htitle, 100, -1., 1., 100, -4.5, 4.5);
2407 const Int_t kNpt(14);
2408 const Int_t kNdpt(150);
2409 const Int_t kNspc = 2*AliPID::kSPECIES+1;
2410 Float_t lPt=0.1, lDPt=-.1, lSpc=-5.5;
2411 Float_t binsPt[kNpt+1], binsSpc[kNspc+1], binsDPt[kNdpt+1];
2412 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2413 for(Int_t i=0; i<kNspc+1; i++,lSpc+=1.) binsSpc[i]=lSpc;
2414 for(Int_t i=0; i<kNdpt+1; i++,lDPt+=2.e-3) binsDPt[i]=lDPt;
2417 snprintf(hname, 100, "%s_%s_Pt", GetNameId(), name);
2418 snprintf(htitle, 300, "#splitline{P_{t} res for}{\"%s\" @ %s};p_{t} [GeV/c];#Delta p_{t}/p_{t}^{MC};SPECIES", GetNameId(), name);
2419 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2420 h = new TH3S(hname, htitle,
2421 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2423 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2427 snprintf(hname, 100, "%s_%s_1Pt", GetNameId(), name);
2428 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);
2429 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2430 h = new TH3S(hname, htitle,
2431 kNpt, 0., 2., 100, -4., 4., kNspc, -5.5, 5.5);
2433 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2437 snprintf(hname, 100, "%s_%s_P", GetNameId(), name);
2438 snprintf(htitle, 300, "P res for \"%s\" @ %s;p [GeV/c];#Delta p/p^{MC};SPECIES", GetNameId(), name);
2439 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2440 h = new TH3S(hname, htitle,
2441 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2443 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2451 //________________________________________________________
2452 TObjArray* AliTRDresolution::Histos()
2455 // Define histograms
2458 if(fContainer) return fContainer;
2460 fContainer = new TObjArray(kNviews);
2461 fContainer->SetOwner(kTRUE);
2463 TObjArray *arr(NULL);
2465 // binnings for plots containing momentum or pt
2466 const Int_t kNpt(14), kNphi(48), kNdy(60);
2467 Float_t lPhi=-.48, lDy=-.3, lPt=0.1;
2468 Float_t binsPhi[kNphi+1], binsDy[kNdy+1], binsPt[kNpt+1];
2469 for(Int_t i=0; i<kNphi+1; i++,lPhi+=.02) binsPhi[i]=lPhi;
2470 for(Int_t i=0; i<kNdy+1; i++,lDy+=.01) binsDy[i]=lDy;
2471 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2473 // cluster to track residuals/pulls
2474 fContainer->AddAt(arr = new TObjArray(2), kCharge);
2475 arr->SetName("Charge");
2476 if(!(h = (TH3S*)gROOT->FindObject("hCharge"))){
2477 h = new TH3S("hCharge", "Charge Resolution", 20, 1., 2., 24, 0., 3.6, 100, 0., 500.);
2478 h->GetXaxis()->SetTitle("dx/dx_{0}");
2479 h->GetYaxis()->SetTitle("x_{d} [cm]");
2480 h->GetZaxis()->SetTitle("dq/dx [ADC/cm]");
2484 // cluster to track residuals/pulls
2485 fContainer->AddAt(BuildMonitorContainerCluster("Cl"), kCluster);
2486 // tracklet to TRD track
2487 fContainer->AddAt(BuildMonitorContainerTracklet("Trk", kTRUE), kTrack);
2488 // tracklet to TRDin
2489 fContainer->AddAt(BuildMonitorContainerTracklet("TrkIN", kTRUE), kTrackIn);
2490 // tracklet to TRDout
2491 fContainer->AddAt(BuildMonitorContainerTracklet("TrkOUT"), kTrackOut);
2494 // Resolution histos
2495 if(!HasMCdata()) return fContainer;
2497 // cluster resolution
2498 fContainer->AddAt(BuildMonitorContainerCluster("MCcl"), kMCcluster);
2500 // tracklet resolution
2501 fContainer->AddAt(BuildMonitorContainerTracklet("MCtracklet"), kMCtracklet);
2504 fContainer->AddAt(arr = new TObjArray(AliTRDgeometry::kNlayer), kMCtrack);
2505 arr->SetName("MCtrk");
2506 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++) arr->AddAt(BuildMonitorContainerTrack(Form("MCtrk_Ly%d", il)), il);
2508 // TRDin TRACK RESOLUTION
2509 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkIN"), kMCtrackIn);
2511 // TRDout TRACK RESOLUTION
2512 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkOUT"), kMCtrackOut);
2517 //________________________________________________________
2518 Bool_t AliTRDresolution::Load(const Char_t *file, const Char_t *dir)
2520 // Custom load function. Used to guess the segmentation level of the data.
2522 if(!AliTRDrecoTask::Load(file, dir)) return kFALSE;
2524 // look for cluster residual plot - always available
2525 TH3S* h3((TH3S*)((TObjArray*)fContainer->At(kClToTrk))->At(0));
2526 Int_t segmentation(h3->GetNbinsZ()/2);
2527 if(segmentation==fgkNresYsegm[0]){ // default segmentation. Nothing to do
2529 } else if(segmentation==fgkNresYsegm[1]){ // stack segmentation.
2530 SetSegmentationLevel(1);
2531 } else if(segmentation==fgkNresYsegm[2]){ // detector segmentation.
2532 SetSegmentationLevel(2);
2534 AliError(Form("Unknown segmentation [%d].", h3->GetNbinsZ()));
2538 AliDebug(2, Form("Segmentation set to level \"%s\"", fgkResYsegmName[fSegmentLevel]));
2542 //________________________________________________________
2543 Bool_t AliTRDresolution::Process(TH2* const h2, TGraphErrors **g, Int_t stat)
2545 // Robust function to process sigma/mean for 2D plot dy(x)
2546 // For each x bin a gauss fit is performed on the y projection and the range
2547 // with the minimum chi2/ndf is choosen
2550 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>0) printf("D-AliTRDresolution::Process() : NULL pointer input container.\n");
2553 if(!Int_t(h2->GetEntries())){
2554 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>0) printf("D-AliTRDresolution::Process() : Empty h[%s - %s].\n", h2->GetName(), h2->GetTitle());
2557 if(!g || !g[0]|| !g[1]) {
2558 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>0) printf("D-AliTRDresolution::Process() : NULL pointer output container.\n");
2562 TAxis *ax(h2->GetXaxis()), *ay(h2->GetYaxis());
2563 Float_t ymin(ay->GetXmin()), ymax(ay->GetXmax()), dy(ay->GetBinWidth(1)), y0(0.), y1(0.);
2564 TF1 f("f", "gaus", ymin, ymax);
2566 if((n=g[0]->GetN())) for(;n--;) g[0]->RemovePoint(n);
2567 if((n=g[1]->GetN())) for(;n--;) g[1]->RemovePoint(n);
2569 if((h=(TH1D*)gROOT->FindObject("py"))) delete h;
2570 Double_t x(0.), y(0.), ex(0.), ey(0.), sy(0.), esy(0.);
2574 Float_t chi2OverNdf(0.);
2575 for(Int_t ix = 1, np=0; ix<=ax->GetNbins(); ix++){
2576 x = ax->GetBinCenter(ix); ex= ax->GetBinWidth(ix)*0.288; // w/sqrt(12)
2577 ymin = ay->GetXmin(); ymax = ay->GetXmax();
2579 h = h2->ProjectionY("py", ix, ix);
2580 if((n=(Int_t)h->GetEntries())<stat){
2581 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("I-AliTRDresolution::Process() : Low statistics @ x[%f] stat[%d]=%d [%d].\n", x, ix, n, stat);
2584 // looking for a first order mean value
2585 f.SetParameter(1, 0.); f.SetParameter(2, 3.e-2);
2587 chi2OverNdf = f.GetChisquare()/f.GetNDF();
2588 printf("x[%f] range[%f %f] chi2[%f] ndf[%d] chi2/ndf[%f]\n", x, ymin, ymax, f.GetChisquare(),f.GetNDF(),chi2OverNdf);
2589 y = f.GetParameter(1); y0 = y-4*dy; y1 = y+4*dy;
2590 ey = f.GetParError(1);
2591 sy = f.GetParameter(2); esy = f.GetParError(2);
2592 // // looking for the best chi2/ndf value
2593 // while(ymin<y0 && ymax>y1){
2594 // f.SetParameter(1, y);
2595 // f.SetParameter(2, sy);
2596 // h->Fit(&f, "QNW", "", y0, y1);
2597 // printf(" range[%f %f] chi2[%f] ndf[%d] chi2/ndf[%f]\n", y0, y1, f.GetChisquare(),f.GetNDF(),f.GetChisquare()/f.GetNDF());
2598 // if(f.GetChisquare()/f.GetNDF() < Chi2OverNdf){
2599 // chi2OverNdf = f.GetChisquare()/f.GetNDF();
2600 // y = f.GetParameter(1); ey = f.GetParError(1);
2601 // sy = f.GetParameter(2); esy = f.GetParError(2);
2602 // printf(" set y[%f] sy[%f] chi2/ndf[%f]\n", y, sy, chi2OverNdf);
2606 g[0]->SetPoint(np, x, y);
2607 g[0]->SetPointError(np, ex, ey);
2608 g[1]->SetPoint(np, x, sy);
2609 g[1]->SetPointError(np, ex, esy);
2616 //________________________________________________________
2617 Bool_t AliTRDresolution::Process(TH2 * const h2, TF1 *f, Float_t k, TGraphErrors **g)
2620 // Do the processing
2623 Char_t pn[10]; snprintf(pn, 10, "p%03d", fIdxPlot);
2625 if((n=g[0]->GetN())) for(;n--;) g[0]->RemovePoint(n);
2626 if((n=g[1]->GetN())) for(;n--;) g[1]->RemovePoint(n);
2627 if(Int_t(h2->GetEntries())){
2628 AliDebug(4, Form("%s: g[%s %s]", pn, g[0]->GetName(), g[0]->GetTitle()));
2630 AliDebug(2, Form("%s: g[%s %s]: Missing entries.", pn, g[0]->GetName(), g[0]->GetTitle()));
2635 const Int_t kINTEGRAL=1;
2636 for(Int_t ibin = 0; ibin < Int_t(h2->GetNbinsX()/kINTEGRAL); ibin++){
2637 Int_t abin(ibin*kINTEGRAL+1),bbin(abin+kINTEGRAL-1),mbin(abin+Int_t(kINTEGRAL/2));
2638 Double_t x = h2->GetXaxis()->GetBinCenter(mbin);
2639 TH1D *h = h2->ProjectionY(pn, abin, bbin);
2640 if((n=(Int_t)h->GetEntries())<150){
2641 AliDebug(4, Form(" x[%f] range[%d %d] stat[%d] low statistics !", x, abin, bbin, n));
2645 Int_t ip = g[0]->GetN();
2646 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)));
2647 g[0]->SetPoint(ip, x, k*f->GetParameter(1));
2648 g[0]->SetPointError(ip, 0., k*f->GetParError(1));
2649 g[1]->SetPoint(ip, x, k*f->GetParameter(2));
2650 g[1]->SetPointError(ip, 0., k*f->GetParError(2));
2652 g[0]->SetPoint(ip, x, k*h->GetMean());
2653 g[0]->SetPointError(ip, 0., k*h->GetMeanError());
2654 g[1]->SetPoint(ip, x, k*h->GetRMS());
2655 g[1]->SetPointError(ip, 0., k*h->GetRMSError());*/
2661 //________________________________________________________
2662 Bool_t AliTRDresolution::Process2D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k, Int_t gidx)
2665 // Do the processing
2668 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2670 // retrive containers
2673 if(!(h2= (TH2I*)(fContainer->At(plot)))) return kFALSE;
2675 TObjArray *a0(NULL);
2676 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2677 if(!(h2=(TH2I*)a0->At(idx))) return kFALSE;
2679 if(Int_t(h2->GetEntries())){
2680 AliDebug(2, Form("p[%d] idx[%d] : h[%s] %s", plot, idx, h2->GetName(), h2->GetTitle()));
2682 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2687 if(gidx<0) gidx=idx;
2688 if(!(g[0] = gidx<0 ? (TGraphErrors*)fGraphM->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphM->At(plot)))->At(gidx))) return kFALSE;
2690 if(!(g[1] = gidx<0 ? (TGraphErrors*)fGraphS->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphS->At(plot)))->At(gidx))) return kFALSE;
2692 return Process(h2, f, k, g);
2695 //________________________________________________________
2696 Bool_t AliTRDresolution::Process3D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2699 // Do the processing
2702 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2704 // retrive containers
2707 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2709 TObjArray *a0(NULL);
2710 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2711 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2713 if(Int_t(h3->GetEntries())){
2714 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2716 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2721 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2722 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2725 TAxis *az = h3->GetZaxis();
2726 for(Int_t iz(0); iz<gm->GetEntriesFast(); iz++){
2727 if(!(g[0] = (TGraphErrors*)gm->At(iz))) return kFALSE;
2728 if(!(g[1] = (TGraphErrors*)gs->At(iz))) return kFALSE;
2729 az->SetRange(iz+1, iz+1);
2730 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2737 //________________________________________________________
2738 Bool_t AliTRDresolution::Process3Dlinked(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2741 // Do the processing
2744 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2746 // retrive containers
2749 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2751 TObjArray *a0(NULL);
2752 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2753 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2755 if(Int_t(h3->GetEntries())){
2756 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2758 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2763 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2764 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2767 if(!(g[0] = (TGraphErrors*)gm->At(0))) return kFALSE;
2768 if(!(g[1] = (TGraphErrors*)gs->At(0))) return kFALSE;
2769 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2771 if(!(g[0] = (TGraphErrors*)gm->At(1))) return kFALSE;
2772 if(!(g[1] = (TGraphErrors*)gs->At(1))) return kFALSE;
2773 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2779 //________________________________________________________
2780 Bool_t AliTRDresolution::Process3DL(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2783 // Do the processing
2786 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2788 // retrive containers
2789 TH3S *h3 = (TH3S*)((TObjArray*)fContainer->At(plot))->At(idx);
2790 if(!h3) return kFALSE;
2791 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2793 TGraphAsymmErrors *gm;
2795 if(!(gm = (TGraphAsymmErrors*)((TObjArray*)fGraphM->At(plot))->At(0))) return kFALSE;
2796 if(!(gs = (TGraphErrors*)((TObjArray*)fGraphS->At(plot)))) return kFALSE;
2798 Float_t x(0.), r(0.), mpv(0.), xM(0.), xm(0.);
2799 TAxis *ay = h3->GetYaxis();
2800 for(Int_t iy=1; iy<=h3->GetNbinsY(); iy++){
2801 ay->SetRange(iy, iy);
2802 x = ay->GetBinCenter(iy);
2803 TH2F *h2=(TH2F*)h3->Project3D("zx");
2804 TAxis *ax = h2->GetXaxis();
2805 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
2806 r = ax->GetBinCenter(ix);
2807 TH1D *h1 = h2->ProjectionY("py", ix, ix);
2808 if(h1->Integral()<50) continue;
2811 GetLandauMpvFwhm(f, mpv, xm, xM);
2812 Int_t ip = gm->GetN();
2813 gm->SetPoint(ip, x, k*mpv);
2814 gm->SetPointError(ip, 0., 0., k*xm, k*xM);
2815 gs->SetPoint(ip, r, k*(xM-xm)/mpv);
2816 gs->SetPointError(ip, 0., 0.);
2823 //________________________________________________________
2824 Bool_t AliTRDresolution::Process2Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2827 // Do the processing
2830 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2832 // retrive containers
2833 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2834 if(!arr) return kFALSE;
2835 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2838 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2839 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2841 TGraphErrors *g[2]; TH2I *h2(NULL); TObjArray *a0(NULL);
2842 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2843 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2845 if(!(h2 = (TH2I*)a0->At(idx))) return kFALSE;
2846 if(Int_t(h2->GetEntries())){
2847 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h2->GetName(), h2->GetTitle()));
2849 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2853 if(!(g[0] = (TGraphErrors*)gm->At(ia))) return kFALSE;
2854 if(!(g[1] = (TGraphErrors*)gs->At(ia))) return kFALSE;
2855 if(!Process(h2, f, k, g)) return kFALSE;
2861 //________________________________________________________
2862 Bool_t AliTRDresolution::Process3Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2865 // Do the processing
2868 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2869 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2871 // retrive containers
2872 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2873 if(!arr) return kFALSE;
2874 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2877 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2878 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2880 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2882 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2883 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2885 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2886 if(Int_t(h3->GetEntries())){
2887 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2889 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2892 TAxis *az = h3->GetZaxis();
2893 for(Int_t iz=1; iz<=az->GetNbins(); iz++, in++){
2894 if(in >= gm->GetEntriesFast()) break;
2895 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2896 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2897 az->SetRange(iz, iz);
2898 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2901 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2906 //________________________________________________________
2907 Bool_t AliTRDresolution::Process3DlinkedArray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2910 // Do the processing
2913 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2914 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2916 // retrive containers
2917 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2918 if(!arr) return kFALSE;
2919 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2922 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2923 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2925 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2927 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2928 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2929 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2930 if(Int_t(h3->GetEntries())){
2931 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2933 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2936 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2937 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2938 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2941 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2942 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2943 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2946 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2951 //________________________________________________________
2952 Bool_t AliTRDresolution::GetGraph(Float_t *bb, ETRDresolutionPlot ip, Int_t idx, Bool_t kLEG, const Char_t *explain)
2958 if(!fGraphS || !fGraphM) return kFALSE;
2959 // axis titles look up
2961 for(Int_t jp=0; jp<(Int_t)ip; jp++) nref+=fgNproj[jp];
2962 UChar_t jdx = idx<0?0:idx;
2963 for(Int_t jc=0; jc<TMath::Min(jdx,fgNproj[ip]-1); jc++) nref++;
2964 Char_t **at = fAxTitle[nref];
2966 // build legends if requiered
2969 leg=new TLegend(.65, .6, .95, .9);
2970 leg->SetBorderSize(0);
2971 leg->SetFillStyle(0);
2975 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]);
2976 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
2977 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
2979 TAxis *ax = h1->GetXaxis();
2980 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
2981 ax = h1->GetYaxis();
2982 ax->SetRangeUser(bb[1], bb[3]);
2983 ax->CenterTitle(); ax->SetTitleOffset(1.4);
2986 TBox *b = new TBox(-.15, bb[1], .15, bb[3]);
2987 b->SetFillStyle(3002);b->SetLineColor(0);
2988 b->SetFillColor(ip<=Int_t(kMCcluster)?kGreen:kBlue);
2991 TGraphErrors *gm = idx<0 ? (TGraphErrors*)fGraphM->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphM->At(ip)))->At(idx);
2992 if(!gm) return kFALSE;
2993 TGraphErrors *gs = idx<0 ? (TGraphErrors*)fGraphS->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphS->At(ip)))->At(idx);
2994 if(!gs) return kFALSE;
2996 Int_t n(0), nPlots(0);
2997 if((n=gm->GetN())) {
2999 gm->Draw("pl"); if(leg) leg->AddEntry(gm, gm->GetTitle(), "pl");
3000 PutTrendValue(Form("%s_%s", fgPerformanceName[ip], at[0]), gm->GetMean(2));
3001 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[ip], at[0]), gm->GetRMS(2));
3006 gs->Draw("pl"); if(leg) leg->AddEntry(gs, gs->GetTitle(), "pl");
3007 gs->Sort(&TGraph::CompareY);
3008 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[ip], at[0]), gs->GetY()[0]);
3009 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[ip], at[0]), gs->GetY()[n-1]);
3010 gs->Sort(&TGraph::CompareX);
3012 if(!nPlots) return kFALSE;
3013 if(leg) leg->Draw();
3017 //________________________________________________________
3018 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)
3024 if(!fGraphS || !fGraphM) return kFALSE;
3026 // axis titles look up
3028 for(Int_t jp(0); jp<ip; jp++) nref+=fgNproj[jp];
3030 Char_t **at = fAxTitle[nref];
3032 // build legends if requiered
3033 TLegend *legM(NULL), *legS(NULL);
3035 legM=new TLegend(.35, .6, .65, .9);
3036 legM->SetHeader("Mean");
3037 legM->SetBorderSize(0);
3038 legM->SetFillStyle(0);
3039 legS=new TLegend(.65, .6, .95, .9);
3040 legS->SetHeader("Sigma");
3041 legS->SetBorderSize(0);
3042 legS->SetFillStyle(0);
3046 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]);
3047 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
3048 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
3050 TAxis *ax = h1->GetXaxis();
3051 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
3052 ax = h1->GetYaxis();
3053 ax->SetRangeUser(bb[1], bb[3]);
3054 ax->CenterTitle(); ax->SetTitleOffset(1.4);
3057 TGraphErrors *gm(NULL), *gs(NULL);
3058 TObjArray *a0(NULL), *a1(NULL);
3059 a0 = (TObjArray*)((TObjArray*)fGraphM->At(ip))->At(idx);
3060 a1 = (TObjArray*)((TObjArray*)fGraphS->At(ip))->At(idx);
3061 if(!n) n=a0->GetEntriesFast();
3062 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'));
3063 Int_t nn(0), nPlots(0);
3064 for(Int_t is(0), is0(0); is<n; is++){
3065 is0 = sel ? sel[is] : is;
3066 if(!(gs = (TGraphErrors*)a1->At(is0))) return kFALSE;
3067 if(!(gm = (TGraphErrors*)a0->At(is0))) return kFALSE;
3069 if((nn=gs->GetN())){
3073 //printf("LegEntry %s [%s]%s\n", at[0], gs->GetName(), gs->GetTitle());
3074 legS->AddEntry(gs, gs->GetTitle(), "pl");
3076 gs->Sort(&TGraph::CompareY);
3077 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[0]);
3078 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[nn-1]);
3079 gs->Sort(&TGraph::CompareX);
3085 //printf("LegEntry %s [%s]%s\n", at[0], gm->GetName(), gm->GetTitle());
3086 legM->AddEntry(gm, gm->GetTitle(), "pl");
3088 PutTrendValue(Form("%s_%s", fgPerformanceName[kMCtrack], at[0]), gm->GetMean(2));
3089 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[kMCtrack], at[0]), gm->GetRMS(2));
3092 if(!nPlots) return kFALSE;
3100 //____________________________________________________________________
3101 Bool_t AliTRDresolution::FitTrack(const Int_t np, AliTrackPoint *points, Float_t param[10])
3104 // Fit track with a staight line using the "np" clusters stored in the array "points".
3105 // The following particularities are stored in the clusters from points:
3106 // 1. pad tilt as cluster charge
3107 // 2. pad row cross or vertex constrain as fake cluster with cluster type 1
3108 // The parameters of the straight line fit are stored in the array "param" in the following order :
3109 // param[0] - x0 reference radial position
3110 // param[1] - y0 reference r-phi position @ x0
3111 // param[2] - z0 reference z position @ x0
3112 // param[3] - slope dy/dx
3113 // param[4] - slope dz/dx
3116 // Function should be used to refit tracks for B=0T
3120 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("D-AliTRDresolution::FitTrack: Not enough clusters to fit a track [%d].\n", np);
3123 TLinearFitter yfitter(2, "pol1"), zfitter(2, "pol1");
3126 for(Int_t ip(0); ip<np; ip++) x0+=points[ip].GetX();
3129 Double_t x, y, z, dx, tilt(0.);
3130 for(Int_t ip(0); ip<np; ip++){
3131 x = points[ip].GetX(); z = points[ip].GetZ();
3133 zfitter.AddPoint(&dx, z, points[ip].GetClusterType()?1.e-3:1.);
3135 if(zfitter.Eval() != 0) return kFALSE;
3137 Double_t z0 = zfitter.GetParameter(0);
3138 Double_t dzdx = zfitter.GetParameter(1);
3139 for(Int_t ip(0); ip<np; ip++){
3140 if(points[ip].GetClusterType()) continue;
3141 x = points[ip].GetX();
3143 y = points[ip].GetY();
3144 z = points[ip].GetZ();
3145 tilt = points[ip].GetCharge();
3146 y -= tilt*(-dzdx*dx + z - z0);
3147 Float_t xyz[3] = {x, y, z}; points[ip].SetXYZ(xyz);
3148 yfitter.AddPoint(&dx, y, 1.);
3150 if(yfitter.Eval() != 0) return kFALSE;
3151 Double_t y0 = yfitter.GetParameter(0);
3152 Double_t dydx = yfitter.GetParameter(1);
3154 param[0] = x0; param[1] = y0; param[2] = z0; param[3] = dydx; param[4] = dzdx;
3155 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);
3159 //____________________________________________________________________
3160 Bool_t AliTRDresolution::FitTracklet(const Int_t ly, const Int_t np, const AliTrackPoint *points, const Float_t param[10], Float_t par[3])
3163 // Fit tracklet with a staight line using the coresponding subset of clusters out of the total "np" clusters stored in the array "points".
3164 // See function FitTrack for the data stored in the "clusters" array
3166 // The parameters of the straight line fit are stored in the array "param" in the following order :
3167 // par[0] - x0 reference radial position
3168 // par[1] - y0 reference r-phi position @ x0
3169 // par[2] - slope dy/dx
3172 // Function should be used to refit tracks for B=0T
3175 TLinearFitter yfitter(2, "pol1");
3177 // grep data for tracklet
3178 Double_t x0(0.), x[60], y[60], dy[60];
3180 for(Int_t ip(0); ip<np; ip++){
3181 if(points[ip].GetClusterType()) continue;
3182 if(points[ip].GetVolumeID() != ly) continue;
3183 Float_t xt(points[ip].GetX())
3184 ,yt(param[1] + param[3] * (xt - param[0]));
3186 y[nly] = points[ip].GetY();
3192 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("D-AliTRDresolution::FitTracklet: Not enough clusters to fit a tracklet [%d].\n", nly);
3195 // set radial reference for fit
3198 // find tracklet core
3199 Double_t mean(0.), sig(1.e3);
3200 AliMathBase::EvaluateUni(nly, dy, mean, sig, 0);
3202 // simple cluster error parameterization
3203 Float_t kSigCut = TMath::Sqrt(5.e-4 + param[3]*param[3]*0.018);
3205 // fit tracklet core
3206 for(Int_t jly(0); jly<nly; jly++){
3207 if(TMath::Abs(dy[jly]-mean)>kSigCut) continue;
3208 Double_t dx(x[jly]-x0);
3209 yfitter.AddPoint(&dx, y[jly], 1.);
3211 if(yfitter.Eval() != 0) return kFALSE;
3213 par[1] = yfitter.GetParameter(0);
3214 par[2] = yfitter.GetParameter(1);
3218 //____________________________________________________________________
3219 Bool_t AliTRDresolution::UseTrack(const Int_t np, const AliTrackPoint *points, Float_t param[10])
3222 // Global selection mechanism of tracksbased on cluster to fit residuals
3223 // The parameters are the same as used ni function FitTrack().
3225 const Float_t kS(0.6), kM(0.2);
3226 TH1S h("h1", "", 100, -5.*kS, 5.*kS);
3227 Float_t dy, dz, s, m;
3228 for(Int_t ip(0); ip<np; ip++){
3229 if(points[ip].GetClusterType()) continue;
3230 Float_t x0(points[ip].GetX())
3231 ,y0(param[1] + param[3] * (x0 - param[0]))
3232 ,z0(param[2] + param[4] * (x0 - param[0]));
3233 dy=points[ip].GetY() - y0; h.Fill(dy);
3234 dz=points[ip].GetZ() - z0;
3236 TF1 fg("fg", "gaus", -5.*kS, 5.*kS);
3237 fg.SetParameter(1, 0.);
3238 fg.SetParameter(2, 2.e-2);
3240 m=fg.GetParameter(1); s=fg.GetParameter(2);
3241 if(s>kS || TMath::Abs(m)>kM) return kFALSE;
3245 //________________________________________________________
3246 void AliTRDresolution::GetLandauMpvFwhm(TF1 * const f, Float_t &mpv, Float_t &xm, Float_t &xM)
3249 // Get the most probable value and the full width half mean
3250 // of a Landau distribution
3253 const Float_t dx = 1.;
3254 mpv = f->GetParameter(1);
3255 Float_t fx, max = f->Eval(mpv);
3258 while((fx = f->Eval(xm))>.5*max){
3267 while((fx = f->Eval(xM))>.5*max) xM += dx;
3271 //________________________________________________________
3272 void AliTRDresolution::SetSegmentationLevel(Int_t l)
3274 // Setting the segmentation level to "l"
3277 UShort_t const lNcomp[kNprojs] = {
3279 fgkNresYsegm[fSegmentLevel], 2, //2,
3280 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3281 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3282 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3284 fgkNresYsegm[fSegmentLevel], 2, //2,
3285 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3286 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3287 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3288 6*fgkNresYsegm[fSegmentLevel], 6*2, 6*2, 6*2, 6, 6, 6, 6, 6*11, 6*11, 6*11 //11
3290 memcpy(fNcomp, lNcomp, kNprojs*sizeof(UShort_t));
3292 Char_t const *lAxTitle[kNprojs][4] = {
3294 {"Impv", "x [cm]", "I_{mpv}", "x/x_{0}"}
3295 ,{"dI/Impv", "x/x_{0}", "#delta I/I_{mpv}", "x[cm]"}
3296 // Clusters to Kalman
3297 ,{"Cluster2Track residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3298 ,{"Cluster2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3299 // TRD tracklet to Kalman fit
3300 ,{"Tracklet2Track Y residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3301 ,{"Tracklet2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3302 ,{"Tracklet2Track Z residuals", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3303 ,{"Tracklet2Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3304 ,{"Tracklet2Track Phi residuals", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3305 // TRDin 2 first TRD tracklet
3306 ,{"Tracklet2Track Y residuals @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3307 ,{"Tracklet2Track YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3308 ,{"Tracklet2Track Z residuals @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3309 ,{"Tracklet2Track Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3310 ,{"Tracklet2Track Phi residuals @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3311 // TRDout 2 first TRD tracklet
3312 ,{"Tracklet2Track Y residuals @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3313 ,{"Tracklet2Track YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3314 ,{"Tracklet2Track Z residuals @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3315 ,{"Tracklet2Track Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3316 ,{"Tracklet2Track Phi residuals @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3318 ,{"MC Cluster Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3319 ,{"MC Cluster YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3321 ,{"MC Tracklet Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3322 ,{"MC Tracklet YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3323 ,{"MC Tracklet Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3324 ,{"MC Tracklet Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3325 ,{"MC Tracklet Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3327 ,{"MC Y resolution @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3328 ,{"MC YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3329 ,{"MC Z resolution @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3330 ,{"MC Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3331 ,{"MC #Phi resolution @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3332 ,{"MC SNP pulls @ TRDin", "tg(#phi)", "SNP", "#sigma_{snp}"}
3333 ,{"MC #Theta resolution @ TRDin", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3334 ,{"MC TGL pulls @ TRDin", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3335 ,{"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}) [%]"}
3336 ,{"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}"}
3337 ,{"MC P resolution @ TRDin", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3339 ,{"MC Y resolution @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3340 ,{"MC YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3341 ,{"MC Z resolution @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3342 ,{"MC Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3343 ,{"MC #Phi resolution @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3344 ,{"MC SNP pulls @ TRDout", "tg(#phi)", "SNP", "#sigma_{snp}"}
3345 ,{"MC #Theta resolution @ TRDout", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3346 ,{"MC TGL pulls @ TRDout", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3347 ,{"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}) [%]"}
3348 ,{"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}"}
3349 ,{"MC P resolution @ TRDout", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3351 ,{"MC Track Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3352 ,{"MC Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3353 ,{"MC Track Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3354 ,{"MC Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3355 ,{"MC Track #Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3356 ,{"MC Track SNP pulls", "tg(#phi)", "SNP", "#sigma_{snp}"}
3357 ,{"MC Track #Theta resolution", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3358 ,{"MC Track TGL pulls", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3359 ,{"MC P_{t} resolution", "p_{t} [GeV/c]", "(p_{t}^{REC}-p_{t}^{MC})/p_{t}^{MC} [%]", "#sigma(#Deltap_{t}/p_{t}^{MC}) [%]"}
3360 ,{"MC 1/P_{t} pulls", "1/p_{t}^{MC} [c/GeV]", "1/p_{t}^{REC} - 1/p_{t}^{MC}", "#sigma_{1/p_{t}}"}
3361 ,{"MC P resolution", "p [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "#sigma(#Deltap/p^{MC}) [%]"}
3363 memcpy(fAxTitle, lAxTitle, 4*kNprojs*sizeof(Char_t*));
3367 //________________________________________________________
3368 Bool_t AliTRDresolution::LoadCorrection(const Char_t *file)
3371 AliWarning("Use cluster position as in reconstruction.");
3372 SetLoadCorrection();
3375 TDirectory *cwd(gDirectory);
3377 FILE *filePtr = fopen(file, "rt");
3379 AliWarning(Form("Couldn't open correction list \"%s\". Use cluster position as in reconstruction.", file));
3380 SetLoadCorrection();
3383 TH2 *h2 = new TH2F("h2", ";time [time bins];detector;dx [#mum]", 30, -0.5, 29.5, AliTRDgeometry::kNdet, -0.5, AliTRDgeometry::kNdet-0.5);
3384 while(fileList.Gets(filePtr)){
3385 if(!TFile::Open(fileList.Data())) {
3386 AliWarning(Form("Couldn't open \"%s\"", fileList.Data()));
3388 } else AliInfo(Form("\"%s\"", fileList.Data()));
3390 TTree *tSys = (TTree*)gFile->Get("tSys");
3391 h2->SetDirectory(gDirectory); h2->Reset("ICE");
3392 tSys->Draw("det:t>>h2", "dx", "goff");
3393 for(Int_t idet(0); idet<AliTRDgeometry::kNdet; idet++){
3394 for(Int_t it(0); it<30; it++) fXcorr[idet][it]+=(1.e-4*h2->GetBinContent(it+1, idet+1));
3396 h2->SetDirectory(cwd);
3401 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>=2){
3402 for(Int_t il(0); il<184; il++) printf("-"); printf("\n");
3403 printf("DET|");for(Int_t it(0); it<30; it++) printf(" tb%02d|", it); printf("\n");
3404 for(Int_t il(0); il<184; il++) printf("-"); printf("\n");
3405 for(Int_t idet(0); idet<AliTRDgeometry::kNdet; idet++){
3406 printf("%03d|", idet);
3407 for(Int_t it(0); it<30; it++) printf("%+5.0f|", 1.e4*fXcorr[idet][it]);
3411 SetLoadCorrection();