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();
149 //________________________________________________________
150 AliTRDresolution::AliTRDresolution(char* name)
151 :AliTRDrecoTask(name, "TRD spatial and momentum resolution")
166 // Default constructor
170 SetSegmentationLevel();
172 DefineOutput(kClToTrk, TObjArray::Class()); // cluster2track
173 DefineOutput(kClToMC, TObjArray::Class()); // cluster2mc
174 /* DefineOutput(kTrkltToTrk, TObjArray::Class()); // tracklet2track
175 DefineOutput(kTrkltToMC, TObjArray::Class()); // tracklet2mc*/
178 //________________________________________________________
179 AliTRDresolution::~AliTRDresolution()
185 if(fGraphS){fGraphS->Delete(); delete fGraphS;}
186 if(fGraphM){fGraphM->Delete(); delete fGraphM;}
187 if(fCl){fCl->Delete(); delete fCl;}
188 if(fMCcl){fMCcl->Delete(); delete fMCcl;}
189 /* if(fTrklt){fTrklt->Delete(); delete fTrklt;}
190 if(fMCtrklt){fMCtrklt->Delete(); delete fMCtrklt;}*/
194 //________________________________________________________
195 void AliTRDresolution::UserCreateOutputObjects()
197 // spatial resolution
199 AliTRDrecoTask::UserCreateOutputObjects();
200 InitExchangeContainers();
203 //________________________________________________________
204 void AliTRDresolution::InitExchangeContainers()
206 // Init containers for subsequent tasks (AliTRDclusterResolution)
208 fCl = new TObjArray(200);
209 fCl->SetOwner(kTRUE);
210 fMCcl = new TObjArray();
211 fMCcl->SetOwner(kTRUE);
212 /* fTrklt = new TObjArray();
213 fTrklt->SetOwner(kTRUE);
214 fMCtrklt = new TObjArray();
215 fMCtrklt->SetOwner(kTRUE);*/
216 PostData(kClToTrk, fCl);
217 PostData(kClToMC, fMCcl);
218 /* PostData(kTrkltToTrk, fTrklt);
219 PostData(kTrkltToMC, fMCtrklt);*/
222 //________________________________________________________
223 void AliTRDresolution::UserExec(Option_t *opt)
231 AliTRDrecoTask::UserExec(opt);
234 //________________________________________________________
235 Bool_t AliTRDresolution::Pulls(Double_t dyz[2], Double_t cov[3], Double_t tilt) const
237 // Helper function to calculate pulls in the yz plane
238 // using proper tilt rotation
239 // Uses functionality defined by AliTRDseedV1.
241 Double_t t2(tilt*tilt);
245 cc[0] = cov[0] - 2.*tilt*cov[1] + t2*cov[2];
246 cc[1] = cov[1]*(1.-t2) + tilt*(cov[0] - cov[2]);
247 cc[2] = t2*cov[0] + 2.*tilt*cov[1] + cov[2];
249 Double_t sqr[3]={0., 0., 0.};
250 if(AliTRDseedV1::GetCovSqrt(cc, sqr)) return kFALSE;
251 Double_t invsqr[3]={0., 0., 0.};
252 if(AliTRDseedV1::GetCovInv(sqr, invsqr)<1.e-40) return kFALSE;
253 Double_t tmp(dyz[0]);
254 dyz[0] = invsqr[0]*tmp + invsqr[1]*dyz[1];
255 dyz[1] = invsqr[1]*tmp + invsqr[2]*dyz[1];
259 //________________________________________________________
260 TH1* AliTRDresolution::PlotCharge(const AliTRDtrackV1 *track)
263 // Plots the charge distribution
266 if(track) fkTrack = track;
268 AliDebug(4, "No Track defined.");
271 TObjArray *arr = NULL;
272 if(!fContainer || !(arr = ((TObjArray*)fContainer->At(kCharge)))){
273 AliWarning("No output container defined.");
278 AliTRDseedV1 *fTracklet = NULL;
279 AliTRDcluster *c = NULL;
280 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
281 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
282 if(!fTracklet->IsOK()) continue;
283 Float_t x0 = fTracklet->GetX0();
285 for(Int_t itb=AliTRDseedV1::kNtb; itb--;){
286 if(!(c = fTracklet->GetClusters(itb))){
287 if(!(c = fTracklet->GetClusters(AliTRDseedV1::kNtb+itb))) continue;
289 dqdl = fTracklet->GetdQdl(itb, &dl);
290 if(dqdl<1.e-5) continue;
291 dl /= 0.15; // dl/dl0, dl0 = 1.5 mm for nominal vd
292 (h = (TH3S*)arr->At(0))->Fill(dl, x0-c->GetX(), dqdl);
295 // if(!HasMCdata()) continue;
297 // Float_t pt0, y0, z0, dydx0, dzdx0;
298 // if(!fMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
305 //________________________________________________________
306 TH1* AliTRDresolution::PlotCluster(const AliTRDtrackV1 *track)
309 // Plot the cluster distributions
312 if(track) fkTrack = track;
314 AliDebug(4, "No Track defined.");
317 TObjArray *arr = NULL;
318 if(!fContainer || !(arr = ((TObjArray*)fContainer->At(kCluster)))){
319 AliWarning("No output container defined.");
322 ULong_t status = fkESD ? fkESD->GetStatus():0;
325 Double_t covR[7], cov[3], dy[2], dz[2];
326 Float_t pt, x0, y0, z0, dydx, dzdx, tilt(0.);
327 const AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
328 AliTRDseedV1 *fTracklet(NULL); TObjArray *clInfoArr(NULL);
329 // do LINEAR track refit if asked by the user
330 // it is the user responsibility to check if B=0T
331 Float_t param[10]; memset(param, 0, 10*sizeof(Float_t));
332 Int_t np(0), nrc(0); AliTrackPoint clusters[300];
334 Bool_t kPrimary(kFALSE);
335 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
336 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
337 if(!fTracklet->IsOK()) continue;
338 x0 = fTracklet->GetX0();
339 tilt = fTracklet->GetTilt();
340 AliTRDcluster *c = NULL;
341 fTracklet->ResetClusterIter(kFALSE);
342 while((c = fTracklet->PrevCluster())){
343 Float_t xyz[3] = {c->GetX(), c->GetY(), c->GetZ()};
344 clusters[np].SetCharge(tilt);
345 clusters[np].SetClusterType(0);
346 clusters[np].SetVolumeID(ily);
347 clusters[np].SetXYZ(xyz);
350 if(fTracklet->IsRowCross()){
351 Float_t xcross(0.), zcross(0.);
352 if(fTracklet->GetEstimatedCrossPoint(xcross, zcross)){
353 clusters[np].SetCharge(tilt);
354 clusters[np].SetClusterType(1);
355 clusters[np].SetVolumeID(ily);
356 clusters[np].SetXYZ(xcross, 0., zcross);
361 if(fTracklet->IsPrimary()) kPrimary = kTRUE;
364 clusters[np].SetCharge(tilt);
365 clusters[np].SetClusterType(1);
366 clusters[np].SetVolumeID(-1);
367 clusters[np].SetXYZ(0., 0., 0.);
370 if(!FitTrack(np, clusters, param)) {
371 AliDebug(1, "Linear track Fit failed.");
374 if(HasTrackSelection()){
375 Bool_t kReject(kFALSE);
376 if(fkTrack->GetNumberOfTracklets() != AliTRDgeometry::kNlayer) kReject = kTRUE;
377 if(!kReject && !UseTrack(np, clusters, param)) kReject = kTRUE;
379 AliDebug(1, "Reject track for residuals analysis.");
384 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
385 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
386 if(!fTracklet->IsOK()) continue;
387 x0 = fTracklet->GetX0();
388 pt = fTracklet->GetPt();
389 sgm[2] = fTracklet->GetDetector();
390 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
391 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
393 // retrive the track angle with the chamber
396 if(!FitTracklet(ily, np, clusters, param, par)) continue;
397 dydx = par[2];//param[3];
399 y0 = par[1] + dydx * (x0 - par[0]);//param[1] + dydx * (x0 - param[0]);
400 z0 = param[2] + dzdx * (x0 - param[0]);
402 y0 = fTracklet->GetYref(0);
403 z0 = fTracklet->GetZref(0);
404 dydx = fTracklet->GetYref(1);
405 dzdx = fTracklet->GetZref(1);
407 /*printf("RC[%c] Primary[%c]\n"
408 " Fit : y0[%f] z0[%f] dydx[%f] dzdx[%f]\n"
409 " Ref: y0[%f] z0[%f] dydx[%f] dzdx[%f]\n", fTracklet->IsRowCross()?'y':'n', fTracklet->IsPrimary()?'y':'n', y0, z0, dydx, dzdx
410 ,fTracklet->GetYref(0),fTracklet->GetZref(0),fTracklet->GetYref(1),fTracklet->GetZref(1));*/
411 tilt = fTracklet->GetTilt();
412 fTracklet->GetCovRef(covR);
413 Double_t t2(tilt*tilt)
415 ,cost(TMath::Sqrt(corr));
416 AliTRDcluster *c = NULL;
417 fTracklet->ResetClusterIter(kFALSE);
418 while((c = fTracklet->PrevCluster())){
419 Float_t xc = c->GetX();
420 Float_t yc = c->GetY();
421 Float_t zc = c->GetZ();
422 Float_t dx = x0 - xc;
423 Float_t yt = y0 - dx*dydx;
424 Float_t zt = z0 - dx*dzdx;
425 dy[0] = yc-yt; dz[0]= zc-zt;
428 dy[1] = cost*(dy[0] - dz[0]*tilt);
429 dz[1] = cost*(dz[0] + dy[0]*tilt);
430 if(pt>fPtThreshold && c->IsInChamber()) ((TH3S*)arr->At(0))->Fill(dydx, dy[1], sgm[fSegmentLevel]);
432 // tilt rotation of covariance for clusters
433 Double_t sy2(c->GetSigmaY2()), sz2(c->GetSigmaZ2());
434 cov[0] = (sy2+t2*sz2)*corr;
435 cov[1] = tilt*(sz2 - sy2)*corr;
436 cov[2] = (t2*sy2+sz2)*corr;
437 // sum with track covariance
438 cov[0]+=covR[0]; cov[1]+=covR[1]; cov[2]+=covR[2];
439 Double_t dyz[2]= {dy[1], dz[1]};
440 Pulls(dyz, cov, tilt);
441 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
443 // Get z-position with respect to anode wire
444 Int_t istk = geo->GetStack(c->GetDetector());
445 AliTRDpadPlane *pp = geo->GetPadPlane(ily, istk);
446 Float_t row0 = pp->GetRow0();
447 Float_t d = row0 - zt + pp->GetAnodeWireOffset();
448 d -= ((Int_t)(2 * d)) / 2.0;
449 if (d > 0.25) d = 0.5 - d;
451 AliTRDclusterInfo *clInfo(NULL);
452 clInfo = new AliTRDclusterInfo;
453 clInfo->SetCluster(c);
454 Float_t covF[] = {cov[0], cov[1], cov[2]};
455 clInfo->SetGlobalPosition(yt, zt, dydx, dzdx, covF);
456 clInfo->SetResolution(dy[1]);
457 clInfo->SetAnisochronity(d);
458 clInfo->SetDriftLength(dx);
459 clInfo->SetTilt(tilt);
460 if(fCl) fCl->Add(clInfo);
461 else AliDebug(1, "Cl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
465 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
466 clInfoArr->SetOwner(kFALSE);
468 clInfoArr->Add(clInfo);
471 if(DebugLevel()>=1 && clInfoArr){
472 (*DebugStream()) << "cluster"
473 <<"status=" << status
474 <<"clInfo.=" << clInfoArr
479 if(clInfoArr) delete clInfoArr;
481 return (TH3S*)arr->At(0);
485 //________________________________________________________
486 TH1* AliTRDresolution::PlotTracklet(const AliTRDtrackV1 *track)
488 // Plot normalized residuals for tracklets to track.
490 // We start from the result that if X=N(|m|, |Cov|)
492 // (Cov^{-1})^{1/2}X = N((Cov^{-1})^{1/2}*|m|, |1|)
494 // in our case X=(y_trklt - y_trk z_trklt - z_trk) and |Cov| = |Cov_trklt| + |Cov_trk| at the radial
495 // reference position.
496 if(track) fkTrack = track;
498 AliDebug(4, "No Track defined.");
501 TObjArray *arr = NULL;
502 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrack ))){
503 AliWarning("No output container defined.");
508 Double_t cov[3], covR[7]/*, sqr[3], inv[3]*/;
509 Double_t pt, phi, tht, x, dx, dy[2], dz[2];
510 AliTRDseedV1 *fTracklet(NULL);
511 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++){
512 if(!(fTracklet = fkTrack->GetTracklet(il))) continue;
513 if(!fTracklet->IsOK()) continue;
514 sgm[2] = fTracklet->GetDetector();
515 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
516 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
517 x = fTracklet->GetX();
518 dx = fTracklet->GetX0() - x;
519 pt = fTracklet->GetPt();
520 phi = fTracklet->GetYref(1);
521 tht = fTracklet->GetZref(1);
523 dy[0]= fTracklet->GetYref(0)-dx*fTracklet->GetYref(1) - fTracklet->GetY();
524 dz[0]= fTracklet->GetZref(0)-dx*fTracklet->GetZref(1) - fTracklet->GetZ();
525 Double_t tilt(fTracklet->GetTilt())
528 ,cost(TMath::Sqrt(corr));
529 Bool_t rc(fTracklet->IsRowCross());
531 // calculate residuals using tilt rotation
532 dy[1]= cost*(dy[0] - dz[0]*tilt);
533 dz[1]= cost*(dz[0] + dy[0]*tilt);
534 ((TH3S*)arr->At(0))->Fill(phi, dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
535 ((TH3S*)arr->At(2))->Fill(tht, dz[1], rc);
537 // compute covariance matrix
538 fTracklet->GetCovAt(x, cov);
539 fTracklet->GetCovRef(covR);
540 cov[0] += covR[0]; cov[1] += covR[1]; cov[2] += covR[2];
541 Double_t dyz[2]= {dy[1], dz[1]};
542 Pulls(dyz, cov, tilt);
543 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
544 ((TH3S*)arr->At(3))->Fill(tht, dyz[1], rc);
546 Double_t dphi((phi-fTracklet->GetYfit(1))/(1-phi*fTracklet->GetYfit(1)));
547 Double_t dtht((tht-fTracklet->GetZfit(1))/(1-tht*fTracklet->GetZfit(1)));
548 ((TH2I*)arr->At(4))->Fill(phi, TMath::ATan(dphi));
551 UChar_t err(fTracklet->GetErrorMsg());
552 (*DebugStream()) << "tracklet"
570 return (TH2I*)arr->At(0);
574 //________________________________________________________
575 TH1* AliTRDresolution::PlotTrackIn(const AliTRDtrackV1 *track)
577 // Store resolution/pulls of Kalman before updating with the TRD information
578 // at the radial position of the first tracklet. The following points are used
580 // - the (y,z,snp) of the first TRD tracklet
581 // - the (y, z, snp, tgl, pt) of the MC track reference
583 // Additionally the momentum resolution/pulls are calculated for usage in the
586 if(track) fkTrack = track;
588 AliDebug(4, "No Track defined.");
591 TObjArray *arr = NULL;
592 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackIn))){
593 AliWarning("No output container defined.");
596 AliExternalTrackParam *tin = NULL;
597 if(!(tin = fkTrack->GetTrackIn())){
598 AliWarning("Track did not entered TRD fiducial volume.");
603 Double_t x = tin->GetX();
604 AliTRDseedV1 *fTracklet = NULL;
605 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
606 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
609 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
610 AliWarning("Tracklet did not match Track.");
614 sgm[2] = fTracklet->GetDetector();
615 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
616 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
617 Double_t tilt(fTracklet->GetTilt())
620 ,cost(TMath::Sqrt(corr));
621 Bool_t rc(fTracklet->IsRowCross());
623 const Int_t kNPAR(5);
624 Double_t parR[kNPAR]; memcpy(parR, tin->GetParameter(), kNPAR*sizeof(Double_t));
625 Double_t covR[3*kNPAR]; memcpy(covR, tin->GetCovariance(), 3*kNPAR*sizeof(Double_t));
626 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
628 // define sum covariances
629 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
630 Double_t *pc = &covR[0], *pp = &parR[0];
631 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
633 for(Int_t ic = 0; ic<=ir; ic++,pc++){
634 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
637 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
638 //COV.Print(); PAR.Print();
640 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
641 Double_t dy[2]={parR[0] - fTracklet->GetY(), 0.}
642 ,dz[2]={parR[1] - fTracklet->GetZ(), 0.}
643 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
644 // calculate residuals using tilt rotation
645 dy[1] = cost*(dy[0] - dz[0]*tilt);
646 dz[1] = cost*(dz[0] + dy[0]*tilt);
648 if(1./PAR[4]>fPtThreshold) ((TH3S*)arr->At(0))->Fill(fTracklet->GetYref(1), dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
649 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
650 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
652 Double_t dyz[2] = {dy[1], dz[1]};
653 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
654 Pulls(dyz, cc, tilt);
655 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
656 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
660 // register reference histo for mini-task
661 h = (TH2I*)arr->At(0);
664 (*DebugStream()) << "trackIn"
670 Double_t y = fTracklet->GetY();
671 Double_t z = fTracklet->GetZ();
672 (*DebugStream()) << "trackletIn"
682 if(!HasMCdata()) return h;
684 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
685 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
686 Int_t pdg = fkMC->GetPDG(),
687 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
689 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
690 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
691 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
693 // translate to reference radial position
694 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
695 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
697 TVectorD PARMC(kNPAR);
698 PARMC[0]=y0; PARMC[1]=z0;
699 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
702 // TMatrixDSymEigen eigen(COV);
703 // TVectorD evals = eigen.GetEigenValues();
704 // TMatrixDSym evalsm(kNPAR);
705 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
706 // TMatrixD evecs = eigen.GetEigenVectors();
707 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
710 if(!(arr = (TObjArray*)fContainer->At(kMCtrackIn))) {
711 AliWarning("No MC container defined.");
715 // y resolution/pulls
716 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
717 ((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)));
718 // z resolution/pulls
719 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
720 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
721 // phi resolution/snp pulls
722 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
723 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
724 // theta resolution/tgl pulls
725 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
726 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
727 // pt resolution\\1/pt pulls\\p resolution/pull
728 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
729 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
731 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
732 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
733 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
735 // p*p*PAR[4]*PAR[4]*COV(4,4)
736 // +2.*PAR[3]*COV(3,4)/PAR[4]
737 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
738 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
742 (*DebugStream()) << "trackInMC"
749 //________________________________________________________
750 TH1* AliTRDresolution::PlotTrackOut(const AliTRDtrackV1 *track)
752 // Store resolution/pulls of Kalman after last update with the TRD information
753 // at the radial position of the first tracklet. The following points are used
755 // - the (y,z,snp) of the first TRD tracklet
756 // - the (y, z, snp, tgl, pt) of the MC track reference
758 // Additionally the momentum resolution/pulls are calculated for usage in the
761 if(track) fkTrack = track;
763 AliDebug(4, "No Track defined.");
766 TObjArray *arr = NULL;
767 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackOut))){
768 AliWarning("No output container defined.");
771 AliExternalTrackParam *tout = NULL;
772 if(!(tout = fkTrack->GetTrackOut())){
773 AliDebug(2, "Track did not exit TRD.");
778 Double_t x = tout->GetX();
779 AliTRDseedV1 *fTracklet(NULL);
780 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
781 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
784 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
785 AliWarning("Tracklet did not match Track position.");
789 sgm[2] = fTracklet->GetDetector();
790 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
791 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
792 Double_t tilt(fTracklet->GetTilt())
795 ,cost(TMath::Sqrt(corr));
796 Bool_t rc(fTracklet->IsRowCross());
798 const Int_t kNPAR(5);
799 Double_t parR[kNPAR]; memcpy(parR, tout->GetParameter(), kNPAR*sizeof(Double_t));
800 Double_t covR[3*kNPAR]; memcpy(covR, tout->GetCovariance(), 3*kNPAR*sizeof(Double_t));
801 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
803 // define sum covariances
804 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
805 Double_t *pc = &covR[0], *pp = &parR[0];
806 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
808 for(Int_t ic = 0; ic<=ir; ic++,pc++){
809 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
812 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
813 //COV.Print(); PAR.Print();
815 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
816 Double_t dy[3]={parR[0] - fTracklet->GetY(), 0., 0.}
817 ,dz[3]={parR[1] - fTracklet->GetZ(), 0., 0.}
818 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
819 // calculate residuals using tilt rotation
820 dy[1] = cost*(dy[0] - dz[0]*tilt);
821 dz[1] = cost*(dz[0] + dy[0]*tilt);
823 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 !!!
824 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
825 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
827 Double_t dyz[2] = {dy[1], dz[1]};
828 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
829 Pulls(dyz, cc, tilt);
830 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
831 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
833 // register reference histo for mini-task
834 h = (TH2I*)arr->At(0);
837 (*DebugStream()) << "trackOut"
843 Double_t y = fTracklet->GetY();
844 Double_t z = fTracklet->GetZ();
845 (*DebugStream()) << "trackletOut"
855 if(!HasMCdata()) return h;
857 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
858 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
859 Int_t pdg = fkMC->GetPDG(),
860 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
862 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
863 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
864 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
866 // translate to reference radial position
867 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
868 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
870 TVectorD PARMC(kNPAR);
871 PARMC[0]=y0; PARMC[1]=z0;
872 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
875 // TMatrixDSymEigen eigen(COV);
876 // TVectorD evals = eigen.GetEigenValues();
877 // TMatrixDSym evalsm(kNPAR);
878 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
879 // TMatrixD evecs = eigen.GetEigenVectors();
880 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
883 if(!(arr = (TObjArray*)fContainer->At(kMCtrackOut))){
884 AliWarning("No MC container defined.");
887 // y resolution/pulls
888 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
889 ((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)));
890 // z resolution/pulls
891 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
892 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
893 // phi resolution/snp pulls
894 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
895 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
896 // theta resolution/tgl pulls
897 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
898 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
899 // pt resolution\\1/pt pulls\\p resolution/pull
900 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
901 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
903 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
904 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
905 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
907 // p*p*PAR[4]*PAR[4]*COV(4,4)
908 // +2.*PAR[3]*COV(3,4)/PAR[4]
909 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
910 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
914 (*DebugStream()) << "trackOutMC"
921 //________________________________________________________
922 TH1* AliTRDresolution::PlotMC(const AliTRDtrackV1 *track)
925 // Plot MC distributions
929 AliDebug(2, "No MC defined. Results will not be available.");
932 if(track) fkTrack = track;
934 AliDebug(4, "No Track defined.");
938 AliWarning("No output container defined.");
941 // retriev track characteristics
942 Int_t pdg = fkMC->GetPDG(),
943 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
946 label(fkMC->GetLabel());
947 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
948 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
949 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
951 TObjArray *arr(NULL);TH1 *h(NULL);
953 Double_t xAnode, x, y, z, pt, dydx, dzdx, dzdl;
954 Float_t pt0, x0, y0, z0, dx, dy, dz, dydx0, dzdx0;
955 Double_t covR[7]/*, cov[3]*/;
958 TVectorD dX(12), dY(12), dZ(12), vPt(12), dPt(12), cCOV(12*15);
959 fkMC->PropagateKalman(&dX, &dY, &dZ, &vPt, &dPt, &cCOV);
960 (*DebugStream()) << "MCkalman"
970 AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
971 AliTRDseedV1 *fTracklet(NULL); TObjArray *clInfoArr(NULL);
972 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
973 if(!(fTracklet = fkTrack->GetTracklet(ily)))/* ||
974 !fTracklet->IsOK())*/ continue;
976 sgm[2] = fTracklet->GetDetector();
977 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
978 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
979 Double_t tilt(fTracklet->GetTilt())
982 ,cost(TMath::Sqrt(corr));
983 x0 = fTracklet->GetX0();
984 //radial shift with respect to the MC reference (radial position of the pad plane)
985 x= fTracklet->GetX();
986 Bool_t rc(fTracklet->IsRowCross());
987 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
988 xAnode = fTracklet->GetX0();
990 // MC track position at reference radial position
993 (*DebugStream()) << "MC"
1005 Float_t ymc = y0 - dx*dydx0;
1006 Float_t zmc = z0 - dx*dzdx0;
1007 //p = pt0*TMath::Sqrt(1.+dzdx0*dzdx0); // pt -> p
1009 // Kalman position at reference radial position
1011 dydx = fTracklet->GetYref(1);
1012 dzdx = fTracklet->GetZref(1);
1013 dzdl = fTracklet->GetTgl();
1014 y = fTracklet->GetYref(0) - dx*dydx;
1016 z = fTracklet->GetZref(0) - dx*dzdx;
1018 pt = TMath::Abs(fTracklet->GetPt());
1019 fTracklet->GetCovRef(covR);
1021 arr = (TObjArray*)((TObjArray*)fContainer->At(kMCtrack))->At(ily);
1022 // y resolution/pulls
1023 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1024 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(covR[0]), dz/TMath::Sqrt(covR[2]));
1025 // z resolution/pulls
1026 ((TH3S*)arr->At(2))->Fill(dzdx0, dz, 0);
1027 ((TH3S*)arr->At(3))->Fill(dzdx0, dz/TMath::Sqrt(covR[2]), 0);
1028 // phi resolution/ snp pulls
1029 Double_t dtgp = (dydx - dydx0)/(1.- dydx*dydx0);
1030 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dtgp));
1031 Double_t dsnp = dydx/TMath::Sqrt(1.+dydx*dydx) - dydx0/TMath::Sqrt(1.+dydx0*dydx0);
1032 ((TH2I*)arr->At(5))->Fill(dydx0, dsnp/TMath::Sqrt(covR[3]));
1033 // theta resolution/ tgl pulls
1034 Double_t dzdl0 = dzdx0/TMath::Sqrt(1.+dydx0*dydx0),
1035 dtgl = (dzdl - dzdl0)/(1.- dzdl*dzdl0);
1036 ((TH2I*)arr->At(6))->Fill(dzdl0,
1038 ((TH2I*)arr->At(7))->Fill(dzdl0, (dzdl - dzdl0)/TMath::Sqrt(covR[4]));
1039 // pt resolution \\ 1/pt pulls \\ p resolution for PID
1040 Double_t p0 = TMath::Sqrt(1.+ dzdl0*dzdl0)*pt0,
1041 p = TMath::Sqrt(1.+ dzdl*dzdl)*pt;
1042 ((TH3S*)((TObjArray*)arr->At(8)))->Fill(pt0, pt/pt0-1., sign*sIdx);
1043 ((TH3S*)((TObjArray*)arr->At(9)))->Fill(1./pt0, (1./pt-1./pt0)/TMath::Sqrt(covR[6]), sign*sIdx);
1044 ((TH3S*)((TObjArray*)arr->At(10)))->Fill(p0, p/p0-1., sign*sIdx);
1046 // Fill Debug stream for Kalman track
1047 if(DebugLevel()>=4){
1048 (*DebugStream()) << "MCtrack"
1055 << "s2y=" << covR[0]
1056 << "s2z=" << covR[2]
1060 // recalculate tracklet based on the MC info
1061 AliTRDseedV1 tt(*fTracklet);
1062 tt.SetZref(0, z0 - (x0-xAnode)*dzdx0);
1063 tt.SetZref(1, dzdx0);
1064 tt.SetReconstructor(AliTRDinfoGen::Reconstructor());
1066 x= tt.GetX();y= tt.GetY();z= tt.GetZ();
1067 dydx = tt.GetYfit(1);
1069 ymc = y0 - dx*dydx0;
1070 zmc = z0 - dx*dzdx0;
1073 Float_t dphi = (dydx - dydx0);
1074 dphi /= (1.- dydx*dydx0);
1076 // add tracklet residuals for y and dydx
1077 arr = (TObjArray*)fContainer->At(kMCtracklet);
1079 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1080 if(tt.GetS2Y()>0. && tt.GetS2Z()>0.) ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(tt.GetS2Y()), dz/TMath::Sqrt(tt.GetS2Z()));
1081 ((TH3S*)arr->At(2))->Fill(dzdl0, dz, rc);
1082 if(tt.GetS2Z()>0.) ((TH3S*)arr->At(3))->Fill(dzdl0, dz/TMath::Sqrt(tt.GetS2Z()), rc);
1083 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dphi));
1085 // Fill Debug stream for tracklet
1086 if(DebugLevel()>=4){
1087 Float_t s2y = tt.GetS2Y();
1088 Float_t s2z = tt.GetS2Z();
1089 (*DebugStream()) << "MCtracklet"
1100 AliTRDpadPlane *pp = geo->GetPadPlane(ily, AliTRDgeometry::GetStack(sgm[2]));
1101 Float_t zr0 = pp->GetRow0() + pp->GetAnodeWireOffset();
1102 //Double_t exb = AliTRDCommonParam::Instance()->GetOmegaTau(1.5);
1104 arr = (TObjArray*)fContainer->At(kMCcluster);
1105 AliTRDcluster *c = NULL;
1106 tt.ResetClusterIter(kFALSE);
1107 while((c = tt.PrevCluster())){
1108 Float_t q = TMath::Abs(c->GetQ());
1109 x = c->GetX(); y = c->GetY();z = c->GetZ();
1113 dy = cost*(y - ymc - tilt*(z-zmc));
1114 dz = cost*(z - zmc + tilt*(y-ymc));
1117 if(q>20. && q<250. && pt0>fPtThreshold && c->IsInChamber()){
1118 ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1119 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(c->GetSigmaY2()), dz/TMath::Sqrt(c->GetSigmaZ2()));
1122 // Fill calibration container
1123 Float_t d = zr0 - zmc;
1124 d -= ((Int_t)(2 * d)) / 2.0;
1125 if (d > 0.25) d = 0.5 - d;
1126 AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
1127 clInfo->SetCluster(c);
1128 clInfo->SetMC(pdg, label);
1129 clInfo->SetGlobalPosition(ymc, zmc, dydx0, dzdx0);
1130 clInfo->SetResolution(dy);
1131 clInfo->SetAnisochronity(d);
1132 clInfo->SetDriftLength(dx);
1133 clInfo->SetTilt(tilt);
1134 if(fMCcl) fMCcl->Add(clInfo);
1135 else AliDebug(1, "MCcl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
1136 if(DebugLevel()>=5){
1138 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
1139 clInfoArr->SetOwner(kFALSE);
1141 clInfoArr->Add(clInfo);
1145 if(DebugLevel()>=5 && clInfoArr){
1146 (*DebugStream()) << "MCcluster"
1147 <<"clInfo.=" << clInfoArr
1152 if(clInfoArr) delete clInfoArr;
1157 //________________________________________________________
1158 Bool_t AliTRDresolution::GetRefFigure(Int_t ifig)
1161 // Get the reference figures
1164 Float_t xy[4] = {0., 0., 0., 0.};
1166 AliWarning("Please provide a canvas to draw results.");
1169 Int_t selection[100], n(0), selStart(0); //
1170 Int_t ly0(0), dly(5);
1171 //Int_t ly0(1), dly(2); // used for SA
1172 TList *l(NULL); TVirtualPad *pad(NULL);
1173 TGraphErrors *g(NULL);TGraphAsymmErrors *ga(NULL);
1175 case 0: // charge resolution
1176 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1177 ((TVirtualPad*)l->At(0))->cd();
1178 ga=((TGraphAsymmErrors*)((TObjArray*)fGraphM->At(kCharge))->At(0));
1179 if(ga->GetN()) ga->Draw("apl");
1180 ((TVirtualPad*)l->At(1))->cd();
1181 g = ((TGraphErrors*)((TObjArray*)fGraphS->At(kCharge))->At(0));
1182 if(g->GetN()) g->Draw("apl");
1184 case 1: // cluster2track residuals
1185 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1186 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1187 pad = (TVirtualPad*)l->At(0); pad->cd();
1188 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1189 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1190 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1191 pad=(TVirtualPad*)l->At(1); pad->cd();
1192 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1193 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1194 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1196 case 2: // cluster2track residuals
1197 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1198 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1199 pad = (TVirtualPad*)l->At(0); pad->cd();
1200 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1201 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1202 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1203 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-0.5; xy[3] = 2.5;
1204 pad=(TVirtualPad*)l->At(1); pad->cd();
1205 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1206 if(!GetGraphArray(xy, kCluster, 1, 1)) break;
1209 gPad->Divide(3, 2, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1210 xy[0] = -.3; xy[1] = -20.; xy[2] = .3; xy[3] = 100.;
1211 ((TVirtualPad*)l->At(0))->cd();
1212 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1213 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1215 ((TVirtualPad*)l->At(1))->cd();
1216 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1217 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1219 ((TVirtualPad*)l->At(2))->cd();
1220 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1221 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1223 ((TVirtualPad*)l->At(3))->cd();
1224 selStart=fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1225 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1227 ((TVirtualPad*)l->At(4))->cd();
1228 selStart=fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1229 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1231 ((TVirtualPad*)l->At(5))->cd();
1232 selStart=2*fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1233 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1236 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1238 xy[0] = -1.; xy[1] = -150.; xy[2] = 1.; xy[3] = 1000.;
1239 ((TVirtualPad*)l->At(0))->cd();
1241 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1243 xy[0] = -1.; xy[1] = -1500.; xy[2] = 1.; xy[3] = 10000.;
1244 ((TVirtualPad*)l->At(1))->cd();
1246 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1249 case 5: // kTrack pulls
1250 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1252 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1253 ((TVirtualPad*)l->At(0))->cd();
1254 if(!GetGraphArray(xy, kTrack, 1, 1)) break;
1256 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1257 ((TVirtualPad*)l->At(1))->cd();
1258 if(!GetGraphArray(xy, kTrack, 3, 1)) break;
1260 case 6: // kTrack phi
1261 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1262 if(GetGraph(&xy[0], kTrack , 4)) return kTRUE;
1264 case 7: // kTrackIn y
1265 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1266 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1267 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1268 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1269 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1270 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1271 pad=((TVirtualPad*)l->At(1)); pad->cd();
1272 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1273 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1274 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1276 case 8: // kTrackIn y
1277 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1278 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1279 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1280 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1281 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1282 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1283 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1284 pad=((TVirtualPad*)l->At(1)); pad->cd();
1285 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1286 if(!GetGraphArray(xy, kTrackIn, 1, 1)) break;
1288 case 9: // kTrackIn z
1289 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1290 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1291 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1292 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1294 if(!GetGraphArray(xy, kTrackIn, 2, 1, 1, selection)) break;
1295 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1296 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1297 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1298 if(!GetGraphArray(xy, kTrackIn, 3, 1)) break;
1300 case 10: // kTrackIn phi
1301 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1302 if(GetGraph(&xy[0], kTrackIn, 4)) return kTRUE;
1304 case 11: // kTrackOut y
1305 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1306 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1307 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1308 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1309 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1310 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1311 pad=((TVirtualPad*)l->At(1)); pad->cd();
1312 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1313 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1314 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1316 case 12: // kTrackOut y
1317 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1318 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1319 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1320 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1321 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1322 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1323 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1324 pad=((TVirtualPad*)l->At(1)); pad->cd();
1325 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1326 if(!GetGraphArray(xy, kTrackOut, 1, 1)) break;
1328 case 13: // kTrackOut z
1329 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1330 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1331 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1332 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1333 if(!GetGraphArray(xy, kTrackOut, 2, 1)) break;
1334 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1335 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1336 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1337 if(!GetGraphArray(xy, kTrackOut, 3, 1)) break;
1339 case 14: // kTrackOut phi
1340 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1341 if(GetGraph(&xy[0], kTrackOut, 4)) return kTRUE;
1343 case 15: // kMCcluster
1344 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1345 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1346 ((TVirtualPad*)l->At(0))->cd();
1347 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1348 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1349 ((TVirtualPad*)l->At(1))->cd();
1350 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1351 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1353 case 16: // kMCcluster
1354 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1355 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1356 ((TVirtualPad*)l->At(0))->cd();
1357 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1358 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1359 ((TVirtualPad*)l->At(1))->cd();
1360 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1361 if(!GetGraphArray(xy, kMCcluster, 1, 1)) break;
1363 case 17: //kMCtracklet [y]
1364 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1365 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1366 ((TVirtualPad*)l->At(0))->cd();
1367 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1368 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1369 ((TVirtualPad*)l->At(1))->cd();
1370 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1371 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1373 case 18: //kMCtracklet [y]
1374 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1375 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1376 ((TVirtualPad*)l->At(0))->cd();
1377 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1378 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1379 ((TVirtualPad*)l->At(1))->cd();
1380 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1381 if(!GetGraphArray(xy, kMCtracklet, 1, 1)) break;
1383 case 19: //kMCtracklet [z]
1384 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1385 xy[0]=-1.; xy[1]=-100.; xy[2]=1.; xy[3] =2500.;
1386 ((TVirtualPad*)l->At(0))->cd();
1387 if(!GetGraphArray(xy, kMCtracklet, 2)) break;
1388 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1389 ((TVirtualPad*)l->At(1))->cd();
1390 if(!GetGraphArray(xy, kMCtracklet, 3)) break;
1392 case 20: //kMCtracklet [phi]
1393 xy[0]=-.3; xy[1]=-3.; xy[2]=.3; xy[3] =25.;
1394 if(!GetGraph(&xy[0], kMCtracklet, 4)) break;
1396 case 21: //kMCtrack [y] ly [0]
1397 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1398 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1399 ((TVirtualPad*)l->At(0))->cd();
1400 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1401 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1402 ((TVirtualPad*)l->At(1))->cd();
1403 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1404 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1406 case 22: //kMCtrack [y] ly [1]
1407 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1408 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1409 ((TVirtualPad*)l->At(0))->cd();
1410 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1411 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1412 ((TVirtualPad*)l->At(1))->cd();
1413 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1414 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1416 case 23: //kMCtrack [y] ly [2]
1417 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1418 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1419 ((TVirtualPad*)l->At(0))->cd();
1420 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1421 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1422 ((TVirtualPad*)l->At(1))->cd();
1423 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1424 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1426 case 24: //kMCtrack [y] ly [3]
1427 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1428 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1429 ((TVirtualPad*)l->At(0))->cd();
1430 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1431 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1432 ((TVirtualPad*)l->At(1))->cd();
1433 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1434 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1436 case 25: //kMCtrack [y] ly [4]
1437 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1438 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1439 ((TVirtualPad*)l->At(0))->cd();
1440 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1441 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1442 ((TVirtualPad*)l->At(1))->cd();
1443 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1444 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1446 case 26: //kMCtrack [y] ly [5]
1447 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1448 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1449 ((TVirtualPad*)l->At(0))->cd();
1450 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1451 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1452 ((TVirtualPad*)l->At(1))->cd();
1453 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1454 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1456 case 27: //kMCtrack [y pulls]
1457 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1458 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 5.5;
1459 ((TVirtualPad*)l->At(0))->cd();
1460 selStart=0; for(n=0; n<6; n++) selection[n]=selStart+n;
1461 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1462 ((TVirtualPad*)l->At(1))->cd();
1463 selStart=6; for(n=0; n<6; n++) selection[n]=selStart+n;
1464 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1466 case 28: //kMCtrack [z]
1467 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1468 xy[0]=-1.; xy[1]=-1500.; xy[2]=1.; xy[3] =6000.;
1469 ((TVirtualPad*)l->At(0))->cd();
1470 if(!GetGraphArray(xy, kMCtrack, 2)) break;
1471 xy[0] = -1.; xy[1] = -1.5; xy[2] = 1.; xy[3] = 5.;
1472 ((TVirtualPad*)l->At(1))->cd();
1473 if(!GetGraphArray(xy, kMCtrack, 3)) break;
1475 case 29: //kMCtrack [phi/snp]
1476 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1477 xy[0]=-.2; xy[1]=-0.5; xy[2]=.2; xy[3] =10.;
1478 ((TVirtualPad*)l->At(0))->cd();
1479 if(!GetGraphArray(xy, kMCtrack, 4)) break;
1480 xy[0] = -.2; xy[1] = -1.5; xy[2] = .2; xy[3] = 5.;
1481 ((TVirtualPad*)l->At(1))->cd();
1482 if(!GetGraphArray(xy, kMCtrack, 5)) break;
1484 case 30: //kMCtrack [theta/tgl]
1485 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1486 xy[0]=-1.; xy[1]=-0.5; xy[2]=1.; xy[3] =5.;
1487 ((TVirtualPad*)l->At(0))->cd();
1488 if(!GetGraphArray(xy, kMCtrack, 6)) break;
1489 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
1490 ((TVirtualPad*)l->At(1))->cd();
1491 if(!GetGraphArray(xy, kMCtrack, 7)) break;
1493 case 31: //kMCtrack [pt]
1494 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1495 pad = (TVirtualPad*)l->At(0); pad->cd();
1496 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1499 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1500 selection[n++] = il*11 + 2; // pi-
1501 selection[n++] = il*11 + 8; // pi+
1503 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1504 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1505 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#pi#pm")) break;
1506 pad->Modified(); pad->Update(); pad->SetLogx();
1507 pad = (TVirtualPad*)l->At(1); pad->cd();
1508 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1511 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1512 selection[n++] = il*11 + 3; // mu-
1513 selection[n++] = il*11 + 7; // mu+
1515 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#mu#pm")) break;
1516 pad->Modified(); pad->Update(); pad->SetLogx();
1518 case 32: //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 + 0; // p bar
1526 selection[n++] = il*11 + 10; // p
1528 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1529 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1530 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "p&p bar")) 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 + 4; // e-
1538 selection[n++] = il*11 + 6; // e+
1540 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1541 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1542 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "e#pm")) break;
1543 pad->Modified(); pad->Update(); pad->SetLogx();
1545 case 33: //kMCtrack [1/pt] pulls
1546 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1547 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 4.5; // SA
1548 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1549 pad = (TVirtualPad*)l->At(0); pad->cd();
1550 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1553 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1554 selection[n++] = il*11 + 2; // pi-
1555 selection[n++] = il*11 + 8; // pi+
1557 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#pi#pm")) break;
1558 pad = (TVirtualPad*)l->At(1); pad->cd();
1559 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1562 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1563 selection[n++] = il*11 + 3; // mu-
1564 selection[n++] = il*11 + 7; // mu+
1566 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#mu#pm")) break;
1568 case 34: //kMCtrack [1/pt] pulls
1569 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1570 pad = (TVirtualPad*)l->At(0); pad->cd();
1571 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1574 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1575 selection[n++] = il*11 + 0; // p bar
1576 selection[n++] = il*11 + 10; // p
1578 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1579 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 6.; // SA
1580 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "p & p bar")) break;
1581 pad = (TVirtualPad*)l->At(1); pad->cd();
1582 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1585 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1586 selection[n++] = il*11 + 4; // e-
1587 selection[n++] = il*11 + 6; // e+
1589 xy[0] = 0.; xy[1] = -2.; xy[2] = 2.; xy[3] = 4.5;
1590 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "e#pm")) break;
1592 case 35: //kMCtrack [p]
1593 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1594 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1595 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1596 pad = (TVirtualPad*)l->At(0); pad->cd();
1597 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1600 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1601 selection[n++] = il*11 + 2; // pi-
1602 selection[n++] = il*11 + 8; // pi+
1604 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#pi#pm")) break;
1605 pad->Modified(); pad->Update(); pad->SetLogx();
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 + 3; // mu-
1612 selection[n++] = il*11 + 7; // mu+
1614 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#mu#pm")) break;
1615 pad->Modified(); pad->Update(); pad->SetLogx();
1617 case 36: //kMCtrack [p]
1618 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1619 pad = (TVirtualPad*)l->At(0); pad->cd();
1620 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1623 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1624 selection[n++] = il*11 + 0; // p bar
1625 selection[n++] = il*11 + 10; // p
1627 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1628 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.; // SA
1629 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "p & p bar")) 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 + 4; // e-
1637 selection[n++] = il*11 + 6; // e+
1639 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1640 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1641 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "e#pm")) break;
1642 pad->Modified(); pad->Update(); pad->SetLogx();
1644 case 37: // kMCtrackIn [y]
1645 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1646 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1647 ((TVirtualPad*)l->At(0))->cd();
1648 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1649 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1650 ((TVirtualPad*)l->At(1))->cd();
1651 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1652 if(!GetGraphArray(&xy[0], kMCtrackIn, 0, 1, n, selection)) break;
1654 case 38: // kMCtrackIn [y]
1655 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1656 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1657 ((TVirtualPad*)l->At(0))->cd();
1658 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1659 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1660 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1661 ((TVirtualPad*)l->At(1))->cd();
1662 if(!GetGraphArray(xy, kMCtrackIn, 1, 1)) break;
1664 case 39: // kMCtrackIn [z]
1665 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1666 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =800.;
1667 ((TVirtualPad*)l->At(0))->cd();
1668 if(!GetGraphArray(xy, kMCtrackIn, 2, 1)) break;
1669 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1670 ((TVirtualPad*)l->At(1))->cd();
1671 if(!GetGraphArray(xy, kMCtrackIn, 3, 1)) break;
1673 case 40: // kMCtrackIn [phi|snp]
1674 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1675 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1676 ((TVirtualPad*)l->At(0))->cd();
1677 if(!GetGraph(&xy[0], kMCtrackIn, 4)) break;
1678 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1679 ((TVirtualPad*)l->At(1))->cd();
1680 if(!GetGraph(&xy[0], kMCtrackIn, 5)) break;
1682 case 41: // kMCtrackIn [theta|tgl]
1683 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1684 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1685 ((TVirtualPad*)l->At(0))->cd();
1686 if(!GetGraph(&xy[0], kMCtrackIn, 6)) break;
1687 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 1.5;
1688 ((TVirtualPad*)l->At(1))->cd();
1689 if(!GetGraph(&xy[0], kMCtrackIn, 7)) break;
1691 case 42: // kMCtrackIn [pt]
1692 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1693 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1694 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.; // SA
1695 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1696 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1697 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1698 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1699 pad = (TVirtualPad*)l->At(1); pad->cd(); pad->SetLogx();
1700 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1701 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1702 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1704 case 43: //kMCtrackIn [1/pt] pulls
1705 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1706 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1707 pad = (TVirtualPad*)l->At(0); pad->cd();
1708 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1709 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1710 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1711 pad = (TVirtualPad*)l->At(1); pad->cd();
1712 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1713 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1714 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1716 case 44: // kMCtrackIn [p]
1717 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1718 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1719 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
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, 10, 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, 10, 1, n, selection)) break;
1729 case 45: // kMCtrackOut [y]
1730 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1731 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1732 ((TVirtualPad*)l->At(0))->cd();
1733 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1734 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1735 ((TVirtualPad*)l->At(1))->cd();
1736 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1737 if(!GetGraphArray(&xy[0], kMCtrackOut, 0, 1, n, selection)) break;
1739 case 46: // kMCtrackOut [y]
1740 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1741 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1742 ((TVirtualPad*)l->At(0))->cd();
1743 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1744 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1745 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1746 ((TVirtualPad*)l->At(1))->cd();
1747 if(!GetGraphArray(xy, kMCtrackOut, 1, 1)) break;
1749 case 47: // kMCtrackOut [z]
1750 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1751 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =1500.;
1752 ((TVirtualPad*)l->At(0))->cd();
1753 if(!GetGraphArray(xy, kMCtrackOut, 2, 1)) break;
1754 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1755 ((TVirtualPad*)l->At(1))->cd();
1756 if(!GetGraphArray(xy, kMCtrackOut, 3, 1)) break;
1758 case 48: // kMCtrackOut [phi|snp]
1759 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1760 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1761 ((TVirtualPad*)l->At(0))->cd();
1762 if(!GetGraph(&xy[0], kMCtrackOut, 4)) break;
1763 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1764 ((TVirtualPad*)l->At(1))->cd();
1765 if(!GetGraph(&xy[0], kMCtrackOut, 5)) break;
1767 case 49: // kMCtrackOut [theta|tgl]
1768 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1769 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1770 ((TVirtualPad*)l->At(0))->cd();
1771 if(!GetGraph(&xy[0], kMCtrackOut, 6)) break;
1772 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 15.;
1773 ((TVirtualPad*)l->At(1))->cd();
1774 if(!GetGraph(&xy[0], kMCtrackOut, 7)) break;
1776 case 50: // kMCtrackOut [pt]
1777 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1778 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1779 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1780 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1781 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1782 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1783 pad = (TVirtualPad*)l->At(1); pad->cd();pad->SetLogx();
1784 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1785 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1786 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1788 case 51: //kMCtrackOut [1/pt] pulls
1789 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1790 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1791 pad = (TVirtualPad*)l->At(0); pad->cd();
1792 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1793 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1794 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1795 pad = (TVirtualPad*)l->At(1); pad->cd();
1796 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1797 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1798 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1800 case 52: // kMCtrackOut [p]
1801 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1802 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1803 pad = ((TVirtualPad*)l->At(0));pad->cd();pad->SetLogx();
1804 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1805 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1806 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1807 pad = ((TVirtualPad*)l->At(1)); pad->cd();pad->SetLogx();
1808 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1809 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1810 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1813 AliWarning(Form("Reference plot [%d] missing result", ifig));
1817 //________________________________________________________
1818 void AliTRDresolution::MakeSummary()
1820 // Build summary plots
1822 if(!fGraphS || !fGraphM){
1823 AliError("Missing results");
1826 Float_t xy[4] = {0., 0., 0., 0.};
1828 TH2 *h2 = new TH2I("h2SF", "", 20, -.2, .2, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5);
1829 h2->GetXaxis()->CenterTitle();
1830 h2->GetYaxis()->CenterTitle();
1831 h2->GetZaxis()->CenterTitle();h2->GetZaxis()->SetTitleOffset(1.4);
1833 Int_t ih2(0), iSumPlot(0);
1834 TCanvas *cOut = new TCanvas(Form("TRDsummary%s_%d", GetName(), iSumPlot++), "Cluster & Tracklet Resolution", 1024, 768);
1835 cOut->Divide(3,2, 2.e-3, 2.e-3, kYellow-7);
1836 TVirtualPad *p(NULL);
1839 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1840 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1841 h2->SetTitle(Form("Cluster-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1842 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kCluster))->At(0), h2);
1843 GetRange(h2, 1, range);
1844 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1849 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1850 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1851 h2->SetTitle(Form("Cluster-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1852 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kCluster))->At(0), h2);
1853 GetRange(h2, 0, range);
1854 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1859 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1860 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1861 GetGraphArray(xy, kCluster, 1, 1);
1864 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1865 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1866 h2->SetTitle(Form("Tracklet-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1867 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kTrack))->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("Tracklet-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1877 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kTrack))->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 GetGraphArray(xy, kTrack, 1, 1);
1888 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1891 (!fGraphS->At(kMCcluster) || !fGraphM->At(kMCcluster) ||
1892 !fGraphS->At(kMCtracklet) || !fGraphM->At(kMCtracklet))){
1896 cOut->Clear(); cOut->SetName(Form("TRDsummary%s_%d", GetName(), iSumPlot++));
1897 cOut->Divide(3, 2, 2.e-3, 2.e-3, kBlue-10);
1900 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1901 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1902 h2->SetTitle(Form("Cluster-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1903 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCcluster))->At(0), h2);
1904 GetRange(h2, 1, range);
1905 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1910 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1911 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1913 h2->SetTitle(Form("Cluster-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1914 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCcluster))->At(0), h2);
1915 GetRange(h2, 0, range);
1916 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1921 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1922 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1923 GetGraphArray(xy, kMCcluster, 1, 1);
1926 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1927 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1929 h2->SetTitle(Form("Tracklet-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1930 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCtracklet))->At(0), h2);
1931 GetRange(h2, 1, range);
1932 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1937 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1938 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1940 h2->SetTitle(Form("Tracklet-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1941 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCtracklet))->At(0), h2);
1942 GetRange(h2, 0, range);
1943 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1948 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1949 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1950 GetGraphArray(xy, kMCtracklet, 1, 1);
1952 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1956 //________________________________________________________
1957 void AliTRDresolution::GetRange(TH2 *h2, Char_t mod, Float_t *range)
1959 // Returns the range of the bulk of data in histogram h2. Removes outliers.
1960 // The "range" vector should be initialized with 2 elements
1961 // Option "mod" can be any of
1962 // - 0 : gaussian like distribution
1963 // - 1 : tailed distribution
1965 Int_t nx(h2->GetNbinsX())
1966 , ny(h2->GetNbinsY())
1968 Double_t *data=new Double_t[n];
1969 for(Int_t ix(1), in(0); ix<=nx; ix++){
1970 for(Int_t iy(1); iy<=ny; iy++)
1971 data[in++] = h2->GetBinContent(ix, iy);
1973 Double_t mean, sigm;
1974 AliMathBase::EvaluateUni(n, data, mean, sigm, Int_t(n*.8));
1976 range[0]=mean-3.*sigm; range[1]=mean+3.*sigm;
1977 if(mod==1) range[0]=TMath::Max(Float_t(1.e-3), range[0]);
1978 AliDebug(2, Form("h[%s] range0[%f %f]", h2->GetName(), range[0], range[1]));
1979 TH1S h1("h1SF0", "", 100, range[0], range[1]);
1984 case 0:// gaussian distribution
1986 TF1 fg("fg", "gaus", mean-3.*sigm, mean+3.*sigm);
1988 mean=fg.GetParameter(1); sigm=fg.GetParameter(2);
1989 range[0] = mean-2.5*sigm;range[1] = mean+2.5*sigm;
1990 AliDebug(2, Form(" rangeG[%f %f]", range[0], range[1]));
1993 case 1:// tailed distribution
1995 Int_t bmax(h1.GetMaximumBin());
1996 Int_t jBinMin(1), jBinMax(100);
1997 for(Int_t ibin(bmax); ibin--;){
1998 if(h1.GetBinContent(ibin)<1.){
1999 jBinMin=ibin; break;
2002 for(Int_t ibin(bmax); ibin++;){
2003 if(h1.GetBinContent(ibin)<1.){
2004 jBinMax=ibin; break;
2007 range[0]=h1.GetBinCenter(jBinMin); range[1]=h1.GetBinCenter(jBinMax);
2008 AliDebug(2, Form(" rangeT[%f %f]", range[0], range[1]));
2016 //________________________________________________________
2017 void AliTRDresolution::MakeSummaryPlot(TObjArray *a, TH2 *h2)
2019 // Core functionality for MakeSummary function.
2023 TGraphErrors *g(NULL); TAxis *ax(h2->GetXaxis());
2024 for(Int_t iseg(0); iseg<fgkNresYsegm[fSegmentLevel]; iseg++){
2025 g=(TGraphErrors*)a->At(iseg);
2026 for(Int_t in(0); in<g->GetN(); in++){
2027 g->GetPoint(in, x, y);
2028 h2->SetBinContent(ax->FindBin(x), iseg+1, y);
2034 //________________________________________________________
2035 Bool_t AliTRDresolution::PostProcess()
2037 // Fit, Project, Combine, Extract values from the containers filled during execution
2039 /*fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));*/
2041 AliError("ERROR: list not available");
2045 // define general behavior parameters
2046 const Color_t fgColorS[11]={
2047 kOrange, kOrange-3, kMagenta+1, kViolet, kRed,
2049 kRed, kViolet, kMagenta+1, kOrange-3, kOrange
2051 const Color_t fgColorM[11]={
2052 kCyan-5, kAzure-4, kBlue-7, kBlue+2, kViolet+10,
2054 kViolet+10, kBlue+2, kBlue-7, kAzure-4, kCyan-5
2056 const Marker_t fgMarker[11]={
2062 TGraph *gm= NULL, *gs= NULL;
2063 if(!fGraphS && !fGraphM){
2064 TObjArray *aM(NULL), *aS(NULL);
2065 Int_t n = fContainer->GetEntriesFast();
2066 fGraphS = new TObjArray(n); fGraphS->SetOwner();
2067 fGraphM = new TObjArray(n); fGraphM->SetOwner();
2068 for(Int_t ig(0), nc(0); ig<n; ig++){
2069 fGraphM->AddAt(aM = new TObjArray(fgNproj[ig]), ig);
2070 fGraphS->AddAt(aS = new TObjArray(fgNproj[ig]), ig);
2072 for(Int_t ic=0; ic<fgNproj[ig]; ic++, nc++){
2073 AliDebug(2, Form("building G[%d] P[%d] N[%d]", ig, ic, fNcomp[nc]));
2075 TObjArray *agS(NULL), *agM(NULL);
2076 aS->AddAt(agS = new TObjArray(fNcomp[nc]), ic);
2077 aM->AddAt(agM = new TObjArray(fNcomp[nc]), ic);
2078 for(Int_t is=fNcomp[nc]; is--;){
2079 agS->AddAt(gs = new TGraphErrors(), is);
2080 Int_t is0(is%11), il0(is/11);
2081 gs->SetMarkerStyle(fgMarker[is0]);
2082 gs->SetMarkerColor(fgColorS[is0]);
2083 gs->SetLineColor(fgColorS[is0]);
2084 gs->SetLineStyle(il0);gs->SetLineWidth(2);
2085 gs->SetName(Form("s_%d_%02d_%02d", ig, ic, is));
2087 agM->AddAt(gm = new TGraphErrors(), is);
2088 gm->SetMarkerStyle(fgMarker[is0]);
2089 gm->SetMarkerColor(fgColorM[is0]);
2090 gm->SetLineColor(fgColorM[is0]);
2091 gm->SetLineStyle(il0);gm->SetLineWidth(2);
2092 gm->SetName(Form("m_%d_%02d_%02d", ig, ic, is));
2093 // this is important for labels in the legend
2095 gs->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2096 gm->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2098 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"z":"y", is/2));
2099 gm->SetTitle(Form("%s Ly[%d]", is%2?"z":"y", is/2));
2100 } else if(ic==2||ic==3) {
2101 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"RC":"no RC", is/2));
2102 gm->SetTitle(Form("%s Ly[%d]", is%2?"RC":"no RC", is/2));
2104 gs->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2105 gm->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2107 gs->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2108 gm->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2112 aS->AddAt(gs = new TGraphErrors(), ic);
2113 gs->SetMarkerStyle(23);
2114 gs->SetMarkerColor(kRed);
2115 gs->SetLineColor(kRed);
2116 gs->SetNameTitle(Form("s_%d_%02d", ig, ic), "sigma");
2118 aM->AddAt(gm = ig ? (TGraph*)new TGraphErrors() : (TGraph*)new TGraphAsymmErrors(), ic);
2119 gm->SetLineColor(kBlack);
2120 gm->SetMarkerStyle(7);
2121 gm->SetMarkerColor(kBlack);
2122 gm->SetNameTitle(Form("m_%d_%02d", ig, ic), "mean");
2128 /* printf("\n\n\n"); fGraphS->ls();
2129 printf("\n\n\n"); fGraphM->ls();*/
2134 TF1 fg("fGauss", "gaus", -.5, .5);
2135 // Landau for charge resolution
2136 TF1 fch("fClCh", "landau", 0., 1000.);
2137 // Landau for e+- pt resolution
2138 TF1 fpt("fPt", "landau", -0.1, 0.2);
2140 //PROCESS EXPERIMENTAL DISTRIBUTIONS
2141 // Charge resolution
2142 //Process3DL(kCharge, 0, &fl);
2143 // Clusters residuals
2144 Process3D(kCluster, 0, &fg, 1.e4);
2145 Process3Dlinked(kCluster, 1, &fg);
2147 // Tracklet residual/pulls
2148 Process3D(kTrack , 0, &fg, 1.e4);
2149 Process3Dlinked(kTrack , 1, &fg);
2150 Process3D(kTrack , 2, &fg, 1.e4);
2151 Process3D(kTrack , 3, &fg);
2152 Process2D(kTrack , 4, &fg, 1.e3);
2154 // TRDin residual/pulls
2155 Process3D(kTrackIn, 0, &fg, 1.e4);
2156 Process3Dlinked(kTrackIn, 1, &fg);
2157 Process3D(kTrackIn, 2, &fg, 1.e4);
2158 Process3D(kTrackIn, 3, &fg);
2159 Process2D(kTrackIn, 4, &fg, 1.e3);
2161 // TRDout residual/pulls
2162 Process3D(kTrackOut, 0, &fg, 1.e3); // scale to fit - see PlotTrackOut
2163 Process3Dlinked(kTrackOut, 1, &fg);
2164 Process3D(kTrackOut, 2, &fg, 1.e4);
2165 Process3D(kTrackOut, 3, &fg);
2166 Process2D(kTrackOut, 4, &fg, 1.e3);
2169 if(!HasMCdata()) return kTRUE;
2172 //PROCESS MC RESIDUAL DISTRIBUTIONS
2174 // CLUSTER Y RESOLUTION/PULLS
2175 Process3D(kMCcluster, 0, &fg, 1.e4);
2176 Process3Dlinked(kMCcluster, 1, &fg, 1.);
2179 // TRACKLET RESOLUTION/PULLS
2180 Process3D(kMCtracklet, 0, &fg, 1.e4); // y
2181 Process3Dlinked(kMCtracklet, 1, &fg, 1.); // y pulls
2182 Process3D(kMCtracklet, 2, &fg, 1.e4); // z
2183 Process3D(kMCtracklet, 3, &fg, 1.); // z pulls
2184 Process2D(kMCtracklet, 4, &fg, 1.e3); // phi
2187 // TRACK RESOLUTION/PULLS
2188 Process3Darray(kMCtrack, 0, &fg, 1.e4); // y
2189 Process3DlinkedArray(kMCtrack, 1, &fg); // y PULL
2190 Process3Darray(kMCtrack, 2, &fg, 1.e4); // z
2191 Process3Darray(kMCtrack, 3, &fg); // z PULL
2192 Process2Darray(kMCtrack, 4, &fg, 1.e3); // phi
2193 Process2Darray(kMCtrack, 5, &fg); // snp PULL
2194 Process2Darray(kMCtrack, 6, &fg, 1.e3); // theta
2195 Process2Darray(kMCtrack, 7, &fg); // tgl PULL
2196 Process3Darray(kMCtrack, 8, &fg, 1.e2); // pt resolution
2197 Process3Darray(kMCtrack, 9, &fg); // 1/pt pulls
2198 Process3Darray(kMCtrack, 10, &fg, 1.e2); // p resolution
2201 // TRACK TRDin RESOLUTION/PULLS
2202 Process3D(kMCtrackIn, 0, &fg, 1.e4);// y resolution
2203 Process3Dlinked(kMCtrackIn, 1, &fg); // y pulls
2204 Process3D(kMCtrackIn, 2, &fg, 1.e4);// z resolution
2205 Process3D(kMCtrackIn, 3, &fg); // z pulls
2206 Process2D(kMCtrackIn, 4, &fg, 1.e3);// phi resolution
2207 Process2D(kMCtrackIn, 5, &fg); // snp pulls
2208 Process2D(kMCtrackIn, 6, &fg, 1.e3);// theta resolution
2209 Process2D(kMCtrackIn, 7, &fg); // tgl pulls
2210 Process3D(kMCtrackIn, 8, &fg, 1.e2);// pt resolution
2211 Process3D(kMCtrackIn, 9, &fg); // 1/pt pulls
2212 Process3D(kMCtrackIn, 10, &fg, 1.e2);// p resolution
2215 // TRACK TRDout RESOLUTION/PULLS
2216 Process3D(kMCtrackOut, 0, &fg, 1.e4);// y resolution
2217 Process3Dlinked(kMCtrackOut, 1, &fg); // y pulls
2218 Process3D(kMCtrackOut, 2, &fg, 1.e4);// z resolution
2219 Process3D(kMCtrackOut, 3, &fg); // z pulls
2220 Process2D(kMCtrackOut, 4, &fg, 1.e3);// phi resolution
2221 Process2D(kMCtrackOut, 5, &fg); // snp pulls
2222 Process2D(kMCtrackOut, 6, &fg, 1.e3);// theta resolution
2223 Process2D(kMCtrackOut, 7, &fg); // tgl pulls
2224 Process3D(kMCtrackOut, 8, &fg, 1.e2);// pt resolution
2225 Process3D(kMCtrackOut, 9, &fg); // 1/pt pulls
2226 Process3D(kMCtrackOut, 10, &fg, 1.e2);// p resolution
2233 //________________________________________________________
2234 void AliTRDresolution::Terminate(Option_t *opt)
2236 AliTRDrecoTask::Terminate(opt);
2237 if(HasPostProcess()) PostProcess();
2240 //________________________________________________________
2241 void AliTRDresolution::AdjustF1(TH1 *h, TF1 *f)
2243 // Helper function to avoid duplication of code
2244 // Make first guesses on the fit parameters
2246 // find the intial parameters of the fit !! (thanks George)
2247 Int_t nbinsy = Int_t(.5*h->GetNbinsX());
2249 for(Int_t jbin=nbinsy-4; jbin<=nbinsy+4; jbin++) sum+=h->GetBinContent(jbin); sum/=9.;
2250 f->SetParLimits(0, 0., 3.*sum);
2251 f->SetParameter(0, .9*sum);
2252 Double_t rms = h->GetRMS();
2253 f->SetParLimits(1, -rms, rms);
2254 f->SetParameter(1, h->GetMean());
2256 f->SetParLimits(2, 0., 2.*rms);
2257 f->SetParameter(2, rms);
2258 if(f->GetNpar() <= 4) return;
2260 f->SetParLimits(3, 0., sum);
2261 f->SetParameter(3, .1*sum);
2263 f->SetParLimits(4, -.3, .3);
2264 f->SetParameter(4, 0.);
2266 f->SetParLimits(5, 0., 1.e2);
2267 f->SetParameter(5, 2.e-1);
2270 //________________________________________________________
2271 TObjArray* AliTRDresolution::BuildMonitorContainerCluster(const char* name, Bool_t expand)
2273 // Build performance histograms for AliTRDcluster.vs TRD track or MC
2274 // - y reziduals/pulls
2276 TObjArray *arr = new TObjArray(2);
2277 arr->SetName(name); arr->SetOwner();
2278 TH1 *h(NULL); char hname[100], htitle[300];
2280 // tracklet resolution/pull in y direction
2281 sprintf(hname, "%s_%s_Y", GetNameId(), name);
2282 sprintf(htitle, "Y res for \"%s\" @ %s;tg(#phi);#Delta y [cm];%s", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2283 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2284 Int_t nybins=fgkNresYsegm[fSegmentLevel];
2285 if(expand) nybins*=2;
2286 h = new TH3S(hname, htitle,
2287 48, -.48, .48, // phi
2288 60, -fDyRange, fDyRange, // dy
2289 nybins, -0.5, nybins-0.5);// segment
2292 sprintf(hname, "%s_%s_YZpull", GetNameId(), name);
2293 sprintf(htitle, "YZ pull for \"%s\" @ %s;%s;#Delta y / #sigma_{y};#Delta z / #sigma_{z}", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2294 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2295 h = new TH3S(hname, htitle, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5, 100, -4.5, 4.5, 100, -4.5, 4.5);
2302 //________________________________________________________
2303 TObjArray* AliTRDresolution::BuildMonitorContainerTracklet(const char* name, Bool_t expand)
2305 // Build performance histograms for AliExternalTrackParam.vs TRD tracklet
2306 // - y reziduals/pulls
2307 // - z reziduals/pulls
2309 TObjArray *arr = BuildMonitorContainerCluster(name, expand);
2311 TH1 *h(NULL); char hname[100], htitle[300];
2313 // tracklet resolution/pull in z direction
2314 sprintf(hname, "%s_%s_Z", GetNameId(), name);
2315 sprintf(htitle, "Z res for \"%s\" @ %s;tg(#theta);#Delta z [cm];row cross", GetNameId(), name);
2316 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2317 h = new TH3S(hname, htitle, 50, -1., 1., 100, -1.5, 1.5, 2, -0.5, 1.5);
2320 sprintf(hname, "%s_%s_Zpull", GetNameId(), name);
2321 sprintf(htitle, "Z pull for \"%s\" @ %s;tg(#theta);#Delta z / #sigma_{z};row cross", GetNameId(), name);
2322 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2323 h = new TH3S(hname, htitle, 50, -1., 1., 100, -5.5, 5.5, 2, -0.5, 1.5);
2324 h->GetZaxis()->SetBinLabel(1, "no RC");
2325 h->GetZaxis()->SetBinLabel(2, "RC");
2329 // tracklet to track phi resolution
2330 sprintf(hname, "%s_%s_PHI", GetNameId(), name);
2331 sprintf(htitle, "#Phi res for \"%s\" @ %s;tg(#phi);#Delta #phi [rad];entries", GetNameId(), name);
2332 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2333 h = new TH2I(hname, htitle, 21, -.33, .33, 100, -.5, .5);
2340 //________________________________________________________
2341 TObjArray* AliTRDresolution::BuildMonitorContainerTrack(const char* name)
2343 // Build performance histograms for AliExternalTrackParam.vs MC
2344 // - y resolution/pulls
2345 // - z resolution/pulls
2346 // - phi resolution, snp pulls
2347 // - theta resolution, tgl pulls
2348 // - pt resolution, 1/pt pulls, p resolution
2350 TObjArray *arr = BuildMonitorContainerTracklet(name);
2352 TH1 *h(NULL); char hname[100], htitle[300];
2356 sprintf(hname, "%s_%s_SNPpull", GetNameId(), name);
2357 sprintf(htitle, "SNP pull for \"%s\" @ %s;tg(#phi);#Delta snp / #sigma_{snp};entries", GetNameId(), name);
2358 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2359 h = new TH2I(hname, htitle, 60, -.3, .3, 100, -4.5, 4.5);
2364 sprintf(hname, "%s_%s_THT", GetNameId(), name);
2365 sprintf(htitle, "#Theta res for \"%s\" @ %s;tg(#theta);#Delta #theta [rad];entries", GetNameId(), name);
2366 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2367 h = new TH2I(hname, htitle, 100, -1., 1., 100, -5e-3, 5e-3);
2371 sprintf(hname, "%s_%s_TGLpull", GetNameId(), name);
2372 sprintf(htitle, "TGL pull for \"%s\" @ %s;tg(#theta);#Delta tgl / #sigma_{tgl};entries", GetNameId(), name);
2373 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2374 h = new TH2I(hname, htitle, 100, -1., 1., 100, -4.5, 4.5);
2378 const Int_t kNpt(14);
2379 const Int_t kNdpt(150);
2380 const Int_t kNspc = 2*AliPID::kSPECIES+1;
2381 Float_t lPt=0.1, lDPt=-.1, lSpc=-5.5;
2382 Float_t binsPt[kNpt+1], binsSpc[kNspc+1], binsDPt[kNdpt+1];
2383 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2384 for(Int_t i=0; i<kNspc+1; i++,lSpc+=1.) binsSpc[i]=lSpc;
2385 for(Int_t i=0; i<kNdpt+1; i++,lDPt+=2.e-3) binsDPt[i]=lDPt;
2388 sprintf(hname, "%s_%s_Pt", GetNameId(), name);
2389 sprintf(htitle, "P_{t} res for \"%s\" @ %s;p_{t} [GeV/c];#Delta p_{t}/p_{t}^{MC};SPECIES", GetNameId(), name);
2390 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2391 h = new TH3S(hname, htitle,
2392 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2394 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2398 sprintf(hname, "%s_%s_1Pt", GetNameId(), name);
2399 sprintf(htitle, "1/P_{t} pull for \"%s\" @ %s;1/p_{t}^{MC} [c/GeV];#Delta(1/p_{t})/#sigma(1/p_{t});SPECIES", GetNameId(), name);
2400 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2401 h = new TH3S(hname, htitle,
2402 kNpt, 0., 2., 100, -4., 4., kNspc, -5.5, 5.5);
2404 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2408 sprintf(hname, "%s_%s_P", GetNameId(), name);
2409 sprintf(htitle, "P res for \"%s\" @ %s;p [GeV/c];#Delta p/p^{MC};SPECIES", GetNameId(), name);
2410 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2411 h = new TH3S(hname, htitle,
2412 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2414 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2422 //________________________________________________________
2423 TObjArray* AliTRDresolution::Histos()
2426 // Define histograms
2429 if(fContainer) return fContainer;
2431 fContainer = new TObjArray(kNviews);
2432 //fContainer->SetOwner(kTRUE);
2434 TObjArray *arr(NULL);
2436 // binnings for plots containing momentum or pt
2437 const Int_t kNpt(14), kNphi(48), kNdy(60);
2438 Float_t lPhi=-.48, lDy=-.3, lPt=0.1;
2439 Float_t binsPhi[kNphi+1], binsDy[kNdy+1], binsPt[kNpt+1];
2440 for(Int_t i=0; i<kNphi+1; i++,lPhi+=.02) binsPhi[i]=lPhi;
2441 for(Int_t i=0; i<kNdy+1; i++,lDy+=.01) binsDy[i]=lDy;
2442 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2444 // cluster to track residuals/pulls
2445 fContainer->AddAt(arr = new TObjArray(2), kCharge);
2446 arr->SetName("Charge");
2447 if(!(h = (TH3S*)gROOT->FindObject("hCharge"))){
2448 h = new TH3S("hCharge", "Charge Resolution", 20, 1., 2., 24, 0., 3.6, 100, 0., 500.);
2449 h->GetXaxis()->SetTitle("dx/dx_{0}");
2450 h->GetYaxis()->SetTitle("x_{d} [cm]");
2451 h->GetZaxis()->SetTitle("dq/dx [ADC/cm]");
2455 // cluster to track residuals/pulls
2456 fContainer->AddAt(BuildMonitorContainerCluster("Cl"), kCluster);
2457 // tracklet to TRD track
2458 fContainer->AddAt(BuildMonitorContainerTracklet("Trk", kTRUE), kTrack);
2459 // tracklet to TRDin
2460 fContainer->AddAt(BuildMonitorContainerTracklet("TrkIN", kTRUE), kTrackIn);
2461 // tracklet to TRDout
2462 fContainer->AddAt(BuildMonitorContainerTracklet("TrkOUT"), kTrackOut);
2465 // Resolution histos
2466 if(!HasMCdata()) return fContainer;
2468 // cluster resolution
2469 fContainer->AddAt(BuildMonitorContainerCluster("MCcl"), kMCcluster);
2471 // tracklet resolution
2472 fContainer->AddAt(BuildMonitorContainerTracklet("MCtracklet"), kMCtracklet);
2475 fContainer->AddAt(arr = new TObjArray(AliTRDgeometry::kNlayer), kMCtrack);
2476 arr->SetName("MCtrk");
2477 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++) arr->AddAt(BuildMonitorContainerTrack(Form("MCtrk_Ly%d", il)), il);
2479 // TRDin TRACK RESOLUTION
2480 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkIN"), kMCtrackIn);
2482 // TRDout TRACK RESOLUTION
2483 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkOUT"), kMCtrackOut);
2488 //________________________________________________________
2489 Bool_t AliTRDresolution::Load(const Char_t *file, const Char_t *dir)
2491 // Custom load function. Used to guess the segmentation level of the data.
2493 if(!AliTRDrecoTask::Load(file, dir)) return kFALSE;
2495 // look for cluster residual plot - always available
2496 TH3S* h3((TH3S*)((TObjArray*)fContainer->At(kClToTrk))->At(0));
2497 Int_t segmentation(h3->GetNbinsZ()/2);
2498 if(segmentation==fgkNresYsegm[0]){ // default segmentation. Nothing to do
2500 } else if(segmentation==fgkNresYsegm[1]){ // stack segmentation.
2501 SetSegmentationLevel(1);
2502 } else if(segmentation==fgkNresYsegm[2]){ // detector segmentation.
2503 SetSegmentationLevel(2);
2505 AliError(Form("Unknown segmentation [%d].", h3->GetNbinsZ()));
2509 AliDebug(2, Form("Segmentation set to level \"%s\"", fgkResYsegmName[fSegmentLevel]));
2514 //________________________________________________________
2515 Bool_t AliTRDresolution::Process(TH2 * const h2, TF1 *f, Float_t k, TGraphErrors **g)
2518 // Do the processing
2521 Char_t pn[10]; sprintf(pn, "p%03d", fIdxPlot);
2523 if((n=g[0]->GetN())) for(;n--;) g[0]->RemovePoint(n);
2524 if((n=g[1]->GetN())) for(;n--;) g[1]->RemovePoint(n);
2525 if(Int_t(h2->GetEntries())){
2526 AliDebug(4, Form("%s: g[%s %s]", pn, g[0]->GetName(), g[0]->GetTitle()));
2528 AliDebug(2, Form("%s: g[%s %s]: Missing entries.", pn, g[0]->GetName(), g[0]->GetTitle()));
2533 const Int_t kINTEGRAL=1;
2534 for(Int_t ibin = 0; ibin < Int_t(h2->GetNbinsX()/kINTEGRAL); ibin++){
2535 Int_t abin(ibin*kINTEGRAL+1),bbin(abin+kINTEGRAL-1),mbin(abin+Int_t(kINTEGRAL/2));
2536 Double_t x = h2->GetXaxis()->GetBinCenter(mbin);
2537 TH1D *h = h2->ProjectionY(pn, abin, bbin);
2538 if((n=(Int_t)h->GetEntries())<150){
2539 AliDebug(4, Form(" x[%f] range[%d %d] stat[%d] low statistics !", x, abin, bbin, n));
2543 Int_t ip = g[0]->GetN();
2544 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)));
2545 g[0]->SetPoint(ip, x, k*f->GetParameter(1));
2546 g[0]->SetPointError(ip, 0., k*f->GetParError(1));
2547 g[1]->SetPoint(ip, x, k*f->GetParameter(2));
2548 g[1]->SetPointError(ip, 0., k*f->GetParError(2));
2550 g[0]->SetPoint(ip, x, k*h->GetMean());
2551 g[0]->SetPointError(ip, 0., k*h->GetMeanError());
2552 g[1]->SetPoint(ip, x, k*h->GetRMS());
2553 g[1]->SetPointError(ip, 0., k*h->GetRMSError());*/
2559 //________________________________________________________
2560 Bool_t AliTRDresolution::Process2D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k, Int_t gidx)
2563 // Do the processing
2566 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2568 // retrive containers
2571 if(!(h2= (TH2I*)(fContainer->At(plot)))) return kFALSE;
2573 TObjArray *a0(NULL);
2574 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2575 if(!(h2=(TH2I*)a0->At(idx))) return kFALSE;
2577 if(Int_t(h2->GetEntries())){
2578 AliDebug(2, Form("p[%d] idx[%d] : h[%s] %s", plot, idx, h2->GetName(), h2->GetTitle()));
2580 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2585 if(gidx<0) gidx=idx;
2586 if(!(g[0] = gidx<0 ? (TGraphErrors*)fGraphM->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphM->At(plot)))->At(gidx))) return kFALSE;
2588 if(!(g[1] = gidx<0 ? (TGraphErrors*)fGraphS->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphS->At(plot)))->At(gidx))) return kFALSE;
2590 return Process(h2, f, k, g);
2593 //________________________________________________________
2594 Bool_t AliTRDresolution::Process3D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2597 // Do the processing
2600 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2602 // retrive containers
2605 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2607 TObjArray *a0(NULL);
2608 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2609 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2611 if(Int_t(h3->GetEntries())){
2612 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2614 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2619 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2620 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2623 TAxis *az = h3->GetZaxis();
2624 for(Int_t iz(0); iz<gm->GetEntriesFast(); iz++){
2625 if(!(g[0] = (TGraphErrors*)gm->At(iz))) return kFALSE;
2626 if(!(g[1] = (TGraphErrors*)gs->At(iz))) return kFALSE;
2627 az->SetRange(iz+1, iz+1);
2628 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2635 //________________________________________________________
2636 Bool_t AliTRDresolution::Process3Dlinked(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2639 // Do the processing
2642 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2644 // retrive containers
2647 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2649 TObjArray *a0(NULL);
2650 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2651 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2653 if(Int_t(h3->GetEntries())){
2654 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2656 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2661 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2662 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2665 if(!(g[0] = (TGraphErrors*)gm->At(0))) return kFALSE;
2666 if(!(g[1] = (TGraphErrors*)gs->At(0))) return kFALSE;
2667 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2669 if(!(g[0] = (TGraphErrors*)gm->At(1))) return kFALSE;
2670 if(!(g[1] = (TGraphErrors*)gs->At(1))) return kFALSE;
2671 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2677 //________________________________________________________
2678 Bool_t AliTRDresolution::Process3DL(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2681 // Do the processing
2684 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2686 // retrive containers
2687 TH3S *h3 = (TH3S*)((TObjArray*)fContainer->At(plot))->At(idx);
2688 if(!h3) return kFALSE;
2689 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2691 TGraphAsymmErrors *gm;
2693 if(!(gm = (TGraphAsymmErrors*)((TObjArray*)fGraphM->At(plot))->At(0))) return kFALSE;
2694 if(!(gs = (TGraphErrors*)((TObjArray*)fGraphS->At(plot)))) return kFALSE;
2696 Float_t x, r, mpv, xM, xm;
2697 TAxis *ay = h3->GetYaxis();
2698 for(Int_t iy=1; iy<=h3->GetNbinsY(); iy++){
2699 ay->SetRange(iy, iy);
2700 x = ay->GetBinCenter(iy);
2701 TH2F *h2=(TH2F*)h3->Project3D("zx");
2702 TAxis *ax = h2->GetXaxis();
2703 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
2704 r = ax->GetBinCenter(ix);
2705 TH1D *h1 = h2->ProjectionY("py", ix, ix);
2706 if(h1->Integral()<50) continue;
2709 GetLandauMpvFwhm(f, mpv, xm, xM);
2710 Int_t ip = gm->GetN();
2711 gm->SetPoint(ip, x, k*mpv);
2712 gm->SetPointError(ip, 0., 0., k*xm, k*xM);
2713 gs->SetPoint(ip, r, k*(xM-xm)/mpv);
2714 gs->SetPointError(ip, 0., 0.);
2721 //________________________________________________________
2722 Bool_t AliTRDresolution::Process2Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2725 // Do the processing
2728 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2730 // retrive containers
2731 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2732 if(!arr) return kFALSE;
2733 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2736 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2737 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2739 TGraphErrors *g[2]; TH2I *h2(NULL); TObjArray *a0(NULL);
2740 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2741 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2743 if(!(h2 = (TH2I*)a0->At(idx))) return kFALSE;
2744 if(Int_t(h2->GetEntries())){
2745 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h2->GetName(), h2->GetTitle()));
2747 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2751 if(!(g[0] = (TGraphErrors*)gm->At(ia))) return kFALSE;
2752 if(!(g[1] = (TGraphErrors*)gs->At(ia))) return kFALSE;
2753 if(!Process(h2, f, k, g)) return kFALSE;
2759 //________________________________________________________
2760 Bool_t AliTRDresolution::Process3Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2763 // Do the processing
2766 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2767 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2769 // retrive containers
2770 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2771 if(!arr) return kFALSE;
2772 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2775 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2776 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2778 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2780 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2781 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2783 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2784 if(Int_t(h3->GetEntries())){
2785 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2787 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2790 TAxis *az = h3->GetZaxis();
2791 for(Int_t iz=1; iz<=az->GetNbins(); iz++, in++){
2792 if(in >= gm->GetEntriesFast()) break;
2793 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2794 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2795 az->SetRange(iz, iz);
2796 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2799 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2804 //________________________________________________________
2805 Bool_t AliTRDresolution::Process3DlinkedArray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2808 // Do the processing
2811 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2812 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2814 // retrive containers
2815 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2816 if(!arr) return kFALSE;
2817 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2820 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2821 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2823 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2825 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2826 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2827 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2828 if(Int_t(h3->GetEntries())){
2829 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2831 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2834 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2835 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2836 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2839 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2840 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2841 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2844 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2849 //________________________________________________________
2850 Bool_t AliTRDresolution::GetGraph(Float_t *bb, ETRDresolutionPlot ip, Int_t idx, Bool_t kLEG, const Char_t *explain)
2856 if(!fGraphS || !fGraphM) return kFALSE;
2857 // axis titles look up
2859 for(Int_t jp=0; jp<(Int_t)ip; jp++) nref+=fgNproj[jp];
2860 UChar_t jdx = idx<0?0:idx;
2861 for(Int_t jc=0; jc<TMath::Min(jdx,fgNproj[ip]-1); jc++) nref++;
2862 Char_t **at = fAxTitle[nref];
2864 // build legends if requiered
2867 leg=new TLegend(.65, .6, .95, .9);
2868 leg->SetBorderSize(0);
2869 leg->SetFillStyle(0);
2873 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]);
2874 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
2875 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
2877 TAxis *ax = h1->GetXaxis();
2878 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
2879 ax = h1->GetYaxis();
2880 ax->SetRangeUser(bb[1], bb[3]);
2881 ax->CenterTitle(); ax->SetTitleOffset(1.4);
2884 TBox *b = new TBox(-.15, bb[1], .15, bb[3]);
2885 b->SetFillStyle(3002);b->SetLineColor(0);
2886 b->SetFillColor(ip<=Int_t(kMCcluster)?kGreen:kBlue);
2889 TGraphErrors *gm = idx<0 ? (TGraphErrors*)fGraphM->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphM->At(ip)))->At(idx);
2890 if(!gm) return kFALSE;
2891 TGraphErrors *gs = idx<0 ? (TGraphErrors*)fGraphS->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphS->At(ip)))->At(idx);
2892 if(!gs) return kFALSE;
2894 Int_t n(0), nPlots(0);
2895 if((n=gm->GetN())) {
2897 gm->Draw("pl"); if(leg) leg->AddEntry(gm, gm->GetTitle(), "pl");
2898 PutTrendValue(Form("%s_%s", fgPerformanceName[ip], at[0]), gm->GetMean(2));
2899 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[ip], at[0]), gm->GetRMS(2));
2904 gs->Draw("pl"); if(leg) leg->AddEntry(gs, gs->GetTitle(), "pl");
2905 gs->Sort(&TGraph::CompareY);
2906 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[ip], at[0]), gs->GetY()[0]);
2907 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[ip], at[0]), gs->GetY()[n-1]);
2908 gs->Sort(&TGraph::CompareX);
2910 if(!nPlots) return kFALSE;
2911 if(leg) leg->Draw();
2915 //________________________________________________________
2916 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)
2922 if(!fGraphS || !fGraphM) return kFALSE;
2924 // axis titles look up
2926 for(Int_t jp(0); jp<ip; jp++) nref+=fgNproj[jp];
2928 Char_t **at = fAxTitle[nref];
2930 // build legends if requiered
2931 TLegend *legM(NULL), *legS(NULL);
2933 legM=new TLegend(.35, .6, .65, .9);
2934 legM->SetHeader("Mean");
2935 legM->SetBorderSize(0);
2936 legM->SetFillStyle(0);
2937 legS=new TLegend(.65, .6, .95, .9);
2938 legS->SetHeader("Sigma");
2939 legS->SetBorderSize(0);
2940 legS->SetFillStyle(0);
2944 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]);
2945 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
2946 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
2948 TAxis *ax = h1->GetXaxis();
2949 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
2950 ax = h1->GetYaxis();
2951 ax->SetRangeUser(bb[1], bb[3]);
2952 ax->CenterTitle(); ax->SetTitleOffset(1.4);
2955 TGraphErrors *gm(NULL), *gs(NULL);
2956 TObjArray *a0(NULL), *a1(NULL);
2957 a0 = (TObjArray*)((TObjArray*)fGraphM->At(ip))->At(idx);
2958 a1 = (TObjArray*)((TObjArray*)fGraphS->At(ip))->At(idx);
2959 if(!n) n=a0->GetEntriesFast();
2960 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'));
2961 Int_t nn(0), nPlots(0);
2962 for(Int_t is(0), is0(0); is<n; is++){
2963 is0 = sel ? sel[is] : is;
2964 if(!(gs = (TGraphErrors*)a1->At(is0))) return kFALSE;
2965 if(!(gm = (TGraphErrors*)a0->At(is0))) return kFALSE;
2967 if((nn=gs->GetN())){
2971 //printf("LegEntry %s [%s]%s\n", at[0], gs->GetName(), gs->GetTitle());
2972 legS->AddEntry(gs, gs->GetTitle(), "pl");
2974 gs->Sort(&TGraph::CompareY);
2975 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[0]);
2976 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[nn-1]);
2977 gs->Sort(&TGraph::CompareX);
2983 //printf("LegEntry %s [%s]%s\n", at[0], gm->GetName(), gm->GetTitle());
2984 legM->AddEntry(gm, gm->GetTitle(), "pl");
2986 PutTrendValue(Form("%s_%s", fgPerformanceName[kMCtrack], at[0]), gm->GetMean(2));
2987 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[kMCtrack], at[0]), gm->GetRMS(2));
2990 if(!nPlots) return kFALSE;
2998 //____________________________________________________________________
2999 Bool_t AliTRDresolution::FitTrack(const Int_t np, AliTrackPoint *points, Float_t param[10])
3002 // Fit track with a staight line using the "np" clusters stored in the array "points".
3003 // The following particularities are stored in the clusters from points:
3004 // 1. pad tilt as cluster charge
3005 // 2. pad row cross or vertex constrain as fake cluster with cluster type 1
3006 // The parameters of the straight line fit are stored in the array "param" in the following order :
3007 // param[0] - x0 reference radial position
3008 // param[1] - y0 reference r-phi position @ x0
3009 // param[2] - z0 reference z position @ x0
3010 // param[3] - slope dy/dx
3011 // param[4] - slope dz/dx
3014 // Function should be used to refit tracks for B=0T
3018 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("D-AliTRDresolution::FitTrack: Not enough clusters to fit a track [%d].", np);
3021 TLinearFitter yfitter(2, "pol1"), zfitter(2, "pol1");
3024 for(Int_t ip(0); ip<np; ip++) x0+=points[ip].GetX();
3027 Double_t x, y, z, dx, tilt(0.);
3028 for(Int_t ip(0); ip<np; ip++){
3029 x = points[ip].GetX(); z = points[ip].GetZ();
3031 zfitter.AddPoint(&dx, z, points[ip].GetClusterType()?1.e-3:1.);
3033 if(zfitter.Eval() != 0) return kFALSE;
3035 Double_t z0 = zfitter.GetParameter(0);
3036 Double_t dzdx = zfitter.GetParameter(1);
3037 for(Int_t ip(0); ip<np; ip++){
3038 if(points[ip].GetClusterType()) continue;
3039 x = points[ip].GetX();
3041 y = points[ip].GetY();
3042 z = points[ip].GetZ();
3043 tilt = points[ip].GetCharge();
3044 y -= tilt*(-dzdx*dx + z - z0);
3045 Float_t xyz[3] = {x, y, z}; points[ip].SetXYZ(xyz);
3046 yfitter.AddPoint(&dx, y, 1.);
3048 if(yfitter.Eval() != 0) return kFALSE;
3049 Double_t y0 = yfitter.GetParameter(0);
3050 Double_t dydx = yfitter.GetParameter(1);
3052 param[0] = x0; param[1] = y0; param[2] = z0; param[3] = dydx; param[4] = dzdx;
3053 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);
3057 //____________________________________________________________________
3058 Bool_t AliTRDresolution::FitTracklet(const Int_t ly, const Int_t np, AliTrackPoint *points, const Float_t param[10], Float_t par[3])
3061 // Fit tracklet with a staight line using the coresponding subset of clusters out of the total "np" clusters stored in the array "points".
3062 // See function FitTrack for the data stored in the "clusters" array
3064 // The parameters of the straight line fit are stored in the array "param" in the following order :
3065 // par[0] - x0 reference radial position
3066 // par[1] - y0 reference r-phi position @ x0
3067 // par[2] - slope dy/dx
3070 // Function should be used to refit tracks for B=0T
3073 TLinearFitter yfitter(2, "pol1");
3075 // grep data for tracklet
3076 Double_t x0(0.), x[60], y[60], dy[60];
3078 for(Int_t ip(0); ip<np; ip++){
3079 if(points[ip].GetClusterType()) continue;
3080 if(points[ip].GetVolumeID() != ly) continue;
3081 Float_t xt(points[ip].GetX())
3082 ,yt(param[1] + param[3] * (xt - param[0]));
3084 y[nly] = points[ip].GetY();
3090 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("D-AliTRDresolution::FitTracklet: Not enough clusters to fit a tracklet [%d].", nly);
3093 // set radial reference for fit
3096 // find tracklet core
3097 Double_t mean(0.), sig(1.e3);
3098 AliMathBase::EvaluateUni(nly, dy, mean, sig, 0);
3100 // simple cluster error parameterization
3101 Float_t kSigCut = TMath::Sqrt(5.e-4 + param[3]*param[3]*0.018);
3103 // fit tracklet core
3104 for(Int_t jly(0); jly<nly; jly++){
3105 if(TMath::Abs(dy[jly]-mean)>kSigCut) continue;
3106 Double_t dx(x[jly]-x0);
3107 yfitter.AddPoint(&dx, y[jly], 1.);
3109 if(yfitter.Eval() != 0) return kFALSE;
3111 par[1] = yfitter.GetParameter(0);
3112 par[2] = yfitter.GetParameter(1);
3116 //____________________________________________________________________
3117 Bool_t AliTRDresolution::UseTrack(const Int_t np, AliTrackPoint *points, Float_t param[10])
3120 // Global selection mechanism of tracksbased on cluster to fit residuals
3121 // The parameters are the same as used ni function FitTrack().
3123 const Float_t kS(0.6), kM(0.2);
3124 TH1S h("h1", "", 100, -5.*kS, 5.*kS);
3125 Float_t dy, dz, s, m;
3126 for(Int_t ip(0); ip<np; ip++){
3127 if(points[ip].GetClusterType()) continue;
3128 Float_t x0(points[ip].GetX())
3129 ,y0(param[1] + param[3] * (x0 - param[0]))
3130 ,z0(param[2] + param[4] * (x0 - param[0]));
3131 dy=points[ip].GetY() - y0; h.Fill(dy);
3132 dz=points[ip].GetZ() - z0;
3134 TF1 fg("fg", "gaus", -5.*kS, 5.*kS);
3135 fg.SetParameter(1, 0.);
3136 fg.SetParameter(2, 2.e-2);
3138 m=fg.GetParameter(1); s=fg.GetParameter(2);
3139 if(s>kS || TMath::Abs(m)>kM) return kFALSE;
3143 //________________________________________________________
3144 void AliTRDresolution::GetLandauMpvFwhm(TF1 * const f, Float_t &mpv, Float_t &xm, Float_t &xM)
3147 // Get the most probable value and the full width half mean
3148 // of a Landau distribution
3151 const Float_t dx = 1.;
3152 mpv = f->GetParameter(1);
3153 Float_t fx, max = f->Eval(mpv);
3156 while((fx = f->Eval(xm))>.5*max){
3165 while((fx = f->Eval(xM))>.5*max) xM += dx;
3169 //________________________________________________________
3170 void AliTRDresolution::SetSegmentationLevel(Int_t l)
3172 // Setting the segmentation level to "l"
3175 UShort_t const lNcomp[kNprojs] = {
3177 fgkNresYsegm[fSegmentLevel], 2, //2,
3178 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3179 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3180 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3182 fgkNresYsegm[fSegmentLevel], 2, //2,
3183 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3184 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3185 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3186 6*fgkNresYsegm[fSegmentLevel], 6*2, 6*2, 6*2, 6, 6, 6, 6, 6*11, 6*11, 6*11 //11
3188 memcpy(fNcomp, lNcomp, kNprojs*sizeof(UShort_t));
3190 Char_t const *lAxTitle[kNprojs][4] = {
3192 {"Impv", "x [cm]", "I_{mpv}", "x/x_{0}"}
3193 ,{"dI/Impv", "x/x_{0}", "#delta I/I_{mpv}", "x[cm]"}
3194 // Clusters to Kalman
3195 ,{"Cluster2Track residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3196 ,{"Cluster2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3197 // TRD tracklet to Kalman fit
3198 ,{"Tracklet2Track Y residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3199 ,{"Tracklet2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3200 ,{"Tracklet2Track Z residuals", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3201 ,{"Tracklet2Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3202 ,{"Tracklet2Track Phi residuals", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3203 // TRDin 2 first TRD tracklet
3204 ,{"Tracklet2Track Y residuals @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3205 ,{"Tracklet2Track YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3206 ,{"Tracklet2Track Z residuals @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3207 ,{"Tracklet2Track Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3208 ,{"Tracklet2Track Phi residuals @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3209 // TRDout 2 first TRD tracklet
3210 ,{"Tracklet2Track Y residuals @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3211 ,{"Tracklet2Track YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3212 ,{"Tracklet2Track Z residuals @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3213 ,{"Tracklet2Track Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3214 ,{"Tracklet2Track Phi residuals @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3216 ,{"MC Cluster Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3217 ,{"MC Cluster YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3219 ,{"MC Tracklet Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3220 ,{"MC Tracklet YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3221 ,{"MC Tracklet Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3222 ,{"MC Tracklet Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3223 ,{"MC Tracklet Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3225 ,{"MC Y resolution @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3226 ,{"MC YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3227 ,{"MC Z resolution @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3228 ,{"MC Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3229 ,{"MC #Phi resolution @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3230 ,{"MC SNP pulls @ TRDin", "tg(#phi)", "SNP", "#sigma_{snp}"}
3231 ,{"MC #Theta resolution @ TRDin", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3232 ,{"MC TGL pulls @ TRDin", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3233 ,{"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}) [%]"}
3234 ,{"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}"}
3235 ,{"MC P resolution @ TRDin", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3237 ,{"MC Y resolution @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3238 ,{"MC YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3239 ,{"MC Z resolution @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3240 ,{"MC Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3241 ,{"MC #Phi resolution @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3242 ,{"MC SNP pulls @ TRDout", "tg(#phi)", "SNP", "#sigma_{snp}"}
3243 ,{"MC #Theta resolution @ TRDout", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3244 ,{"MC TGL pulls @ TRDout", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3245 ,{"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}) [%]"}
3246 ,{"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}"}
3247 ,{"MC P resolution @ TRDout", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3249 ,{"MC Track Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3250 ,{"MC Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3251 ,{"MC Track Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3252 ,{"MC Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3253 ,{"MC Track #Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3254 ,{"MC Track SNP pulls", "tg(#phi)", "SNP", "#sigma_{snp}"}
3255 ,{"MC Track #Theta resolution", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3256 ,{"MC Track TGL pulls", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3257 ,{"MC P_{t} resolution", "p_{t} [GeV/c]", "(p_{t}^{REC}-p_{t}^{MC})/p_{t}^{MC} [%]", "#sigma(#Deltap_{t}/p_{t}^{MC}) [%]"}
3258 ,{"MC 1/P_{t} pulls", "1/p_{t}^{MC} [c/GeV]", "1/p_{t}^{REC} - 1/p_{t}^{MC}", "#sigma_{1/p_{t}}"}
3259 ,{"MC P resolution", "p [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "#sigma(#Deltap/p^{MC}) [%]"}
3261 memcpy(fAxTitle, lAxTitle, 4*kNprojs*sizeof(Char_t*));