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));
333 Bool_t kPrimary(kFALSE);
334 Int_t np(0), nrc(0); AliTrackPoint clusters[300];
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].SetXYZ(xyz);
349 if(fTracklet->IsRowCross()){
350 Float_t xcross(0.), zcross(0.);
351 if(fTracklet->GetEstimatedCrossPoint(xcross, zcross)){
352 clusters[np].SetCharge(tilt);
353 clusters[np].SetClusterType(1);
354 clusters[np].SetXYZ(xcross, 0., zcross);
359 if(fTracklet->IsPrimary()) kPrimary = kTRUE;
362 clusters[np].SetCharge(tilt);
363 clusters[np].SetClusterType(1);
364 clusters[np].SetXYZ(0., 0., 0.);
367 if(!FitTrack(np, clusters, param)) {
368 AliDebug(1, "Linear track Fit failed.");
371 if(HasTrackSelection()){
372 Bool_t kReject(kFALSE);
373 if(fkTrack->GetNumberOfTracklets() != AliTRDgeometry::kNlayer) kReject = kTRUE;
374 if(!kReject && !UseTrack(np, clusters, param)) kReject = kTRUE;
376 AliDebug(1, "Reject track for residuals analysis.");
381 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
382 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
383 if(!fTracklet->IsOK()) continue;
384 x0 = fTracklet->GetX0();
385 pt = fTracklet->GetPt();
386 sgm[2] = fTracklet->GetDetector();
387 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
388 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
390 // retrive the track angle with the chamber
394 y0 = param[1] + dydx * (x0 - param[0]);
395 z0 = param[2] + dzdx * (x0 - param[0]);
397 y0 = fTracklet->GetYref(0);
398 z0 = fTracklet->GetZref(0);
399 dydx = fTracklet->GetYref(1);
400 dzdx = fTracklet->GetZref(1);
402 /*printf("RC[%c] Primary[%c]\n"
403 " Fit : y0[%f] z0[%f] dydx[%f] dzdx[%f]\n"
404 " Ref: y0[%f] z0[%f] dydx[%f] dzdx[%f]\n", fTracklet->IsRowCross()?'y':'n', fTracklet->IsPrimary()?'y':'n', y0, z0, dydx, dzdx
405 ,fTracklet->GetYref(0),fTracklet->GetZref(0),fTracklet->GetYref(1),fTracklet->GetZref(1));*/
406 tilt = fTracklet->GetTilt();
407 fTracklet->GetCovRef(covR);
408 Double_t t2(tilt*tilt)
410 ,cost(TMath::Sqrt(corr));
411 AliTRDcluster *c = NULL;
412 fTracklet->ResetClusterIter(kFALSE);
413 while((c = fTracklet->PrevCluster())){
414 Float_t xc = c->GetX();
415 Float_t yc = c->GetY();
416 Float_t zc = c->GetZ();
417 Float_t dx = x0 - xc;
418 Float_t yt = y0 - dx*dydx;
419 Float_t zt = z0 - dx*dzdx;
420 dy[0] = yc-yt; dz[0]= zc-zt;
423 dy[1] = cost*(dy[0] - dz[0]*tilt);
424 dz[1] = cost*(dz[0] + dy[0]*tilt);
425 if(pt>fPtThreshold && c->IsInChamber()) ((TH3S*)arr->At(0))->Fill(dydx, dy[1], sgm[fSegmentLevel]);
427 // tilt rotation of covariance for clusters
428 Double_t sy2(c->GetSigmaY2()), sz2(c->GetSigmaZ2());
429 cov[0] = (sy2+t2*sz2)*corr;
430 cov[1] = tilt*(sz2 - sy2)*corr;
431 cov[2] = (t2*sy2+sz2)*corr;
432 // sum with track covariance
433 cov[0]+=covR[0]; cov[1]+=covR[1]; cov[2]+=covR[2];
434 Double_t dyz[2]= {dy[1], dz[1]};
435 Pulls(dyz, cov, tilt);
436 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
438 // Get z-position with respect to anode wire
439 Int_t istk = geo->GetStack(c->GetDetector());
440 AliTRDpadPlane *pp = geo->GetPadPlane(ily, istk);
441 Float_t row0 = pp->GetRow0();
442 Float_t d = row0 - zt + pp->GetAnodeWireOffset();
443 d -= ((Int_t)(2 * d)) / 2.0;
444 if (d > 0.25) d = 0.5 - d;
446 AliTRDclusterInfo *clInfo(NULL);
447 clInfo = new AliTRDclusterInfo;
448 clInfo->SetCluster(c);
449 Float_t covF[] = {cov[0], cov[1], cov[2]};
450 clInfo->SetGlobalPosition(yt, zt, dydx, dzdx, covF);
451 clInfo->SetResolution(dy[1]);
452 clInfo->SetAnisochronity(d);
453 clInfo->SetDriftLength(dx);
454 clInfo->SetTilt(tilt);
455 if(fCl) fCl->Add(clInfo);
456 else AliDebug(1, "Cl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
460 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
461 clInfoArr->SetOwner(kFALSE);
463 clInfoArr->Add(clInfo);
466 if(DebugLevel()>=1 && clInfoArr){
467 (*DebugStream()) << "cluster"
468 <<"status=" << status
469 <<"clInfo.=" << clInfoArr
474 if(clInfoArr) delete clInfoArr;
476 return (TH3S*)arr->At(0);
480 //________________________________________________________
481 TH1* AliTRDresolution::PlotTracklet(const AliTRDtrackV1 *track)
483 // Plot normalized residuals for tracklets to track.
485 // We start from the result that if X=N(|m|, |Cov|)
487 // (Cov^{-1})^{1/2}X = N((Cov^{-1})^{1/2}*|m|, |1|)
489 // in our case X=(y_trklt - y_trk z_trklt - z_trk) and |Cov| = |Cov_trklt| + |Cov_trk| at the radial
490 // reference position.
491 if(track) fkTrack = track;
493 AliDebug(4, "No Track defined.");
496 TObjArray *arr = NULL;
497 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrack ))){
498 AliWarning("No output container defined.");
503 Double_t cov[3], covR[7]/*, sqr[3], inv[3]*/;
504 Double_t pt, phi, tht, x, dx, dy[2], dz[2];
505 AliTRDseedV1 *fTracklet(NULL);
506 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++){
507 if(!(fTracklet = fkTrack->GetTracklet(il))) continue;
508 if(!fTracklet->IsOK()) continue;
509 sgm[2] = fTracklet->GetDetector();
510 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
511 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
512 x = fTracklet->GetX();
513 dx = fTracklet->GetX0() - x;
514 pt = fTracklet->GetPt();
515 phi = fTracklet->GetYref(1);
516 tht = fTracklet->GetZref(1);
518 dy[0]= fTracklet->GetYref(0)-dx*fTracklet->GetYref(1) - fTracklet->GetY();
519 dz[0]= fTracklet->GetZref(0)-dx*fTracklet->GetZref(1) - fTracklet->GetZ();
520 Double_t tilt(fTracklet->GetTilt())
523 ,cost(TMath::Sqrt(corr));
524 Bool_t rc(fTracklet->IsRowCross());
526 // calculate residuals using tilt rotation
527 dy[1]= cost*(dy[0] - dz[0]*tilt);
528 dz[1]= cost*(dz[0] + dy[0]*tilt);
529 ((TH3S*)arr->At(0))->Fill(phi, dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
530 ((TH3S*)arr->At(2))->Fill(tht, dz[1], rc);
532 // compute covariance matrix
533 fTracklet->GetCovAt(x, cov);
534 fTracklet->GetCovRef(covR);
535 cov[0] += covR[0]; cov[1] += covR[1]; cov[2] += covR[2];
536 Double_t dyz[2]= {dy[1], dz[1]};
537 Pulls(dyz, cov, tilt);
538 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
539 ((TH3S*)arr->At(3))->Fill(tht, dyz[1], rc);
541 Double_t dphi((phi-fTracklet->GetYfit(1))/(1-phi*fTracklet->GetYfit(1)));
542 Double_t dtht((tht-fTracklet->GetZfit(1))/(1-tht*fTracklet->GetZfit(1)));
543 ((TH2I*)arr->At(4))->Fill(phi, TMath::ATan(dphi));
546 UChar_t err(fTracklet->GetErrorMsg());
547 (*DebugStream()) << "tracklet"
565 return (TH2I*)arr->At(0);
569 //________________________________________________________
570 TH1* AliTRDresolution::PlotTrackIn(const AliTRDtrackV1 *track)
572 // Store resolution/pulls of Kalman before updating with the TRD information
573 // at the radial position of the first tracklet. The following points are used
575 // - the (y,z,snp) of the first TRD tracklet
576 // - the (y, z, snp, tgl, pt) of the MC track reference
578 // Additionally the momentum resolution/pulls are calculated for usage in the
581 if(track) fkTrack = track;
583 AliDebug(4, "No Track defined.");
586 TObjArray *arr = NULL;
587 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackIn))){
588 AliWarning("No output container defined.");
591 AliExternalTrackParam *tin = NULL;
592 if(!(tin = fkTrack->GetTrackIn())){
593 AliWarning("Track did not entered TRD fiducial volume.");
598 Double_t x = tin->GetX();
599 AliTRDseedV1 *fTracklet = NULL;
600 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
601 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
604 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
605 AliWarning("Tracklet did not match Track.");
609 sgm[2] = fTracklet->GetDetector();
610 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
611 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
612 Double_t tilt(fTracklet->GetTilt())
615 ,cost(TMath::Sqrt(corr));
616 Bool_t rc(fTracklet->IsRowCross());
618 const Int_t kNPAR(5);
619 Double_t parR[kNPAR]; memcpy(parR, tin->GetParameter(), kNPAR*sizeof(Double_t));
620 Double_t covR[3*kNPAR]; memcpy(covR, tin->GetCovariance(), 3*kNPAR*sizeof(Double_t));
621 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
623 // define sum covariances
624 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
625 Double_t *pc = &covR[0], *pp = &parR[0];
626 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
628 for(Int_t ic = 0; ic<=ir; ic++,pc++){
629 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
632 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
633 //COV.Print(); PAR.Print();
635 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
636 Double_t dy[2]={parR[0] - fTracklet->GetY(), 0.}
637 ,dz[2]={parR[1] - fTracklet->GetZ(), 0.}
638 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
639 // calculate residuals using tilt rotation
640 dy[1] = cost*(dy[0] - dz[0]*tilt);
641 dz[1] = cost*(dz[0] + dy[0]*tilt);
643 if(1./PAR[4]>fPtThreshold) ((TH3S*)arr->At(0))->Fill(fTracklet->GetYref(1), dy[1], sgm[fSegmentLevel]+rc*fgkNresYsegm[fSegmentLevel]);
644 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
645 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
647 Double_t dyz[2] = {dy[1], dz[1]};
648 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
649 Pulls(dyz, cc, tilt);
650 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
651 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
655 // register reference histo for mini-task
656 h = (TH2I*)arr->At(0);
659 (*DebugStream()) << "trackIn"
665 Double_t y = fTracklet->GetY();
666 Double_t z = fTracklet->GetZ();
667 (*DebugStream()) << "trackletIn"
677 if(!HasMCdata()) return h;
679 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
680 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
681 Int_t pdg = fkMC->GetPDG(),
682 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
684 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
685 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
686 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
688 // translate to reference radial position
689 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
690 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
692 TVectorD PARMC(kNPAR);
693 PARMC[0]=y0; PARMC[1]=z0;
694 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
697 // TMatrixDSymEigen eigen(COV);
698 // TVectorD evals = eigen.GetEigenValues();
699 // TMatrixDSym evalsm(kNPAR);
700 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
701 // TMatrixD evecs = eigen.GetEigenVectors();
702 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
705 if(!(arr = (TObjArray*)fContainer->At(kMCtrackIn))) {
706 AliWarning("No MC container defined.");
710 // y resolution/pulls
711 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
712 ((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)));
713 // z resolution/pulls
714 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
715 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
716 // phi resolution/snp pulls
717 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
718 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
719 // theta resolution/tgl pulls
720 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
721 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
722 // pt resolution\\1/pt pulls\\p resolution/pull
723 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
724 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
726 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
727 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
728 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
730 // p*p*PAR[4]*PAR[4]*COV(4,4)
731 // +2.*PAR[3]*COV(3,4)/PAR[4]
732 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
733 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
737 (*DebugStream()) << "trackInMC"
744 //________________________________________________________
745 TH1* AliTRDresolution::PlotTrackOut(const AliTRDtrackV1 *track)
747 // Store resolution/pulls of Kalman after last update with the TRD information
748 // at the radial position of the first tracklet. The following points are used
750 // - the (y,z,snp) of the first TRD tracklet
751 // - the (y, z, snp, tgl, pt) of the MC track reference
753 // Additionally the momentum resolution/pulls are calculated for usage in the
756 if(track) fkTrack = track;
758 AliDebug(4, "No Track defined.");
761 TObjArray *arr = NULL;
762 if(!fContainer || !(arr = (TObjArray*)fContainer->At(kTrackOut))){
763 AliWarning("No output container defined.");
766 AliExternalTrackParam *tout = NULL;
767 if(!(tout = fkTrack->GetTrackOut())){
768 AliDebug(2, "Track did not exit TRD.");
773 Double_t x = tout->GetX();
774 AliTRDseedV1 *fTracklet(NULL);
775 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
776 if(!(fTracklet = fkTrack->GetTracklet(ily))) continue;
779 if(!fTracklet || TMath::Abs(x-fTracklet->GetX())>1.e-3){
780 AliWarning("Tracklet did not match Track position.");
784 sgm[2] = fTracklet->GetDetector();
785 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
786 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
787 Double_t tilt(fTracklet->GetTilt())
790 ,cost(TMath::Sqrt(corr));
791 Bool_t rc(fTracklet->IsRowCross());
793 const Int_t kNPAR(5);
794 Double_t parR[kNPAR]; memcpy(parR, tout->GetParameter(), kNPAR*sizeof(Double_t));
795 Double_t covR[3*kNPAR]; memcpy(covR, tout->GetCovariance(), 3*kNPAR*sizeof(Double_t));
796 Double_t cov[3]; fTracklet->GetCovAt(x, cov);
798 // define sum covariances
799 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
800 Double_t *pc = &covR[0], *pp = &parR[0];
801 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
803 for(Int_t ic = 0; ic<=ir; ic++,pc++){
804 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
807 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
808 //COV.Print(); PAR.Print();
810 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
811 Double_t dy[3]={parR[0] - fTracklet->GetY(), 0., 0.}
812 ,dz[3]={parR[1] - fTracklet->GetZ(), 0., 0.}
813 ,dphi(TMath::ASin(PAR[2])-TMath::ATan(fTracklet->GetYfit(1)));
814 // calculate residuals using tilt rotation
815 dy[1] = cost*(dy[0] - dz[0]*tilt);
816 dz[1] = cost*(dz[0] + dy[0]*tilt);
818 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 !!!
819 ((TH3S*)arr->At(2))->Fill(fTracklet->GetZref(1), dz[1], rc);
820 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), dphi);
822 Double_t dyz[2] = {dy[1], dz[1]};
823 Double_t cc[3] = {COV(0,0)+cov[0], COV(0,1)+cov[1], COV(1,1)+cov[2]};
824 Pulls(dyz, cc, tilt);
825 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dyz[0], dyz[1]);
826 ((TH3S*)arr->At(3))->Fill(fTracklet->GetZref(1), dyz[1], rc);
828 // register reference histo for mini-task
829 h = (TH2I*)arr->At(0);
832 (*DebugStream()) << "trackOut"
838 Double_t y = fTracklet->GetY();
839 Double_t z = fTracklet->GetZ();
840 (*DebugStream()) << "trackletOut"
850 if(!HasMCdata()) return h;
852 Float_t dx, pt0, x0=fTracklet->GetX0(), y0, z0, dydx0, dzdx0;
853 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
854 Int_t pdg = fkMC->GetPDG(),
855 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
857 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
858 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
859 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
861 // translate to reference radial position
862 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
863 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
865 TVectorD PARMC(kNPAR);
866 PARMC[0]=y0; PARMC[1]=z0;
867 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
870 // TMatrixDSymEigen eigen(COV);
871 // TVectorD evals = eigen.GetEigenValues();
872 // TMatrixDSym evalsm(kNPAR);
873 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
874 // TMatrixD evecs = eigen.GetEigenVectors();
875 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
878 if(!(arr = (TObjArray*)fContainer->At(kMCtrackOut))){
879 AliWarning("No MC container defined.");
882 // y resolution/pulls
883 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0], sgm[fSegmentLevel]);
884 ((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)));
885 // z resolution/pulls
886 ((TH3S*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1], 0);
887 ((TH3S*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)), 0);
888 // phi resolution/snp pulls
889 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
890 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
891 // theta resolution/tgl pulls
892 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
893 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
894 // pt resolution\\1/pt pulls\\p resolution/pull
895 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., sign*sIdx);
896 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), sign*sIdx);
898 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
899 p = TMath::Sqrt(1.+ PAR[3]*PAR[3])/PAR[4];
900 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., sign*sIdx);
902 // p*p*PAR[4]*PAR[4]*COV(4,4)
903 // +2.*PAR[3]*COV(3,4)/PAR[4]
904 // +PAR[3]*PAR[3]*COV(3,3)/p/p/PAR[4]/PAR[4]/PAR[4]/PAR[4];
905 // if(sp>0.) ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/TMath::Sqrt(sp), sign*sIdx);
909 (*DebugStream()) << "trackOutMC"
916 //________________________________________________________
917 TH1* AliTRDresolution::PlotMC(const AliTRDtrackV1 *track)
920 // Plot MC distributions
924 AliDebug(2, "No MC defined. Results will not be available.");
927 if(track) fkTrack = track;
929 AliDebug(4, "No Track defined.");
933 AliWarning("No output container defined.");
936 // retriev track characteristics
937 Int_t pdg = fkMC->GetPDG(),
938 sIdx(AliTRDpidUtil::Pdg2Pid(TMath::Abs(pdg))+1), // species index
941 label(fkMC->GetLabel());
942 if(!fDBPDG) fDBPDG=TDatabasePDG::Instance();
943 TParticlePDG *ppdg(fDBPDG->GetParticle(pdg));
944 if(ppdg) sign = ppdg->Charge() > 0. ? 1 : -1;
946 TObjArray *arr(NULL);TH1 *h(NULL);
948 Double_t xAnode, x, y, z, pt, dydx, dzdx, dzdl;
949 Float_t pt0, x0, y0, z0, dx, dy, dz, dydx0, dzdx0;
950 Double_t covR[7]/*, cov[3]*/;
953 TVectorD dX(12), dY(12), dZ(12), vPt(12), dPt(12), cCOV(12*15);
954 fkMC->PropagateKalman(&dX, &dY, &dZ, &vPt, &dPt, &cCOV);
955 (*DebugStream()) << "MCkalman"
965 AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
966 AliTRDseedV1 *fTracklet(NULL); TObjArray *clInfoArr(NULL);
967 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
968 if(!(fTracklet = fkTrack->GetTracklet(ily)))/* ||
969 !fTracklet->IsOK())*/ continue;
971 sgm[2] = fTracklet->GetDetector();
972 sgm[0] = AliTRDgeometry::GetSector(sgm[2]);
973 sgm[1] = sgm[0] * AliTRDgeometry::kNstack + AliTRDgeometry::GetStack(sgm[2]);
974 Double_t tilt(fTracklet->GetTilt())
977 ,cost(TMath::Sqrt(corr));
978 x0 = fTracklet->GetX0();
979 //radial shift with respect to the MC reference (radial position of the pad plane)
980 x= fTracklet->GetX();
981 Bool_t rc(fTracklet->IsRowCross());
982 if(!fkMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
983 xAnode = fTracklet->GetX0();
985 // MC track position at reference radial position
988 (*DebugStream()) << "MC"
1000 Float_t ymc = y0 - dx*dydx0;
1001 Float_t zmc = z0 - dx*dzdx0;
1002 //p = pt0*TMath::Sqrt(1.+dzdx0*dzdx0); // pt -> p
1004 // Kalman position at reference radial position
1006 dydx = fTracklet->GetYref(1);
1007 dzdx = fTracklet->GetZref(1);
1008 dzdl = fTracklet->GetTgl();
1009 y = fTracklet->GetYref(0) - dx*dydx;
1011 z = fTracklet->GetZref(0) - dx*dzdx;
1013 pt = TMath::Abs(fTracklet->GetPt());
1014 fTracklet->GetCovRef(covR);
1016 arr = (TObjArray*)((TObjArray*)fContainer->At(kMCtrack))->At(ily);
1017 // y resolution/pulls
1018 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1019 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(covR[0]), dz/TMath::Sqrt(covR[2]));
1020 // z resolution/pulls
1021 ((TH3S*)arr->At(2))->Fill(dzdx0, dz, 0);
1022 ((TH3S*)arr->At(3))->Fill(dzdx0, dz/TMath::Sqrt(covR[2]), 0);
1023 // phi resolution/ snp pulls
1024 Double_t dtgp = (dydx - dydx0)/(1.- dydx*dydx0);
1025 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dtgp));
1026 Double_t dsnp = dydx/TMath::Sqrt(1.+dydx*dydx) - dydx0/TMath::Sqrt(1.+dydx0*dydx0);
1027 ((TH2I*)arr->At(5))->Fill(dydx0, dsnp/TMath::Sqrt(covR[3]));
1028 // theta resolution/ tgl pulls
1029 Double_t dzdl0 = dzdx0/TMath::Sqrt(1.+dydx0*dydx0),
1030 dtgl = (dzdl - dzdl0)/(1.- dzdl*dzdl0);
1031 ((TH2I*)arr->At(6))->Fill(dzdl0,
1033 ((TH2I*)arr->At(7))->Fill(dzdl0, (dzdl - dzdl0)/TMath::Sqrt(covR[4]));
1034 // pt resolution \\ 1/pt pulls \\ p resolution for PID
1035 Double_t p0 = TMath::Sqrt(1.+ dzdl0*dzdl0)*pt0,
1036 p = TMath::Sqrt(1.+ dzdl*dzdl)*pt;
1037 ((TH3S*)((TObjArray*)arr->At(8)))->Fill(pt0, pt/pt0-1., sign*sIdx);
1038 ((TH3S*)((TObjArray*)arr->At(9)))->Fill(1./pt0, (1./pt-1./pt0)/TMath::Sqrt(covR[6]), sign*sIdx);
1039 ((TH3S*)((TObjArray*)arr->At(10)))->Fill(p0, p/p0-1., sign*sIdx);
1041 // Fill Debug stream for Kalman track
1042 if(DebugLevel()>=4){
1043 (*DebugStream()) << "MCtrack"
1050 << "s2y=" << covR[0]
1051 << "s2z=" << covR[2]
1055 // recalculate tracklet based on the MC info
1056 AliTRDseedV1 tt(*fTracklet);
1057 tt.SetZref(0, z0 - (x0-xAnode)*dzdx0);
1058 tt.SetZref(1, dzdx0);
1059 tt.SetReconstructor(AliTRDinfoGen::Reconstructor());
1061 x= tt.GetX();y= tt.GetY();z= tt.GetZ();
1062 dydx = tt.GetYfit(1);
1064 ymc = y0 - dx*dydx0;
1065 zmc = z0 - dx*dzdx0;
1068 Float_t dphi = (dydx - dydx0);
1069 dphi /= (1.- dydx*dydx0);
1071 // add tracklet residuals for y and dydx
1072 arr = (TObjArray*)fContainer->At(kMCtracklet);
1074 if(pt0>fPtThreshold) ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1075 if(tt.GetS2Y()>0. && tt.GetS2Z()>0.) ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(tt.GetS2Y()), dz/TMath::Sqrt(tt.GetS2Z()));
1076 ((TH3S*)arr->At(2))->Fill(dzdl0, dz, rc);
1077 if(tt.GetS2Z()>0.) ((TH3S*)arr->At(3))->Fill(dzdl0, dz/TMath::Sqrt(tt.GetS2Z()), rc);
1078 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dphi));
1080 // Fill Debug stream for tracklet
1081 if(DebugLevel()>=4){
1082 Float_t s2y = tt.GetS2Y();
1083 Float_t s2z = tt.GetS2Z();
1084 (*DebugStream()) << "MCtracklet"
1095 AliTRDpadPlane *pp = geo->GetPadPlane(ily, AliTRDgeometry::GetStack(sgm[2]));
1096 Float_t zr0 = pp->GetRow0() + pp->GetAnodeWireOffset();
1097 //Double_t exb = AliTRDCommonParam::Instance()->GetOmegaTau(1.5);
1099 arr = (TObjArray*)fContainer->At(kMCcluster);
1100 AliTRDcluster *c = NULL;
1101 tt.ResetClusterIter(kFALSE);
1102 while((c = tt.PrevCluster())){
1103 Float_t q = TMath::Abs(c->GetQ());
1104 x = c->GetX(); y = c->GetY();z = c->GetZ();
1108 dy = cost*(y - ymc - tilt*(z-zmc));
1109 dz = cost*(z - zmc + tilt*(y-ymc));
1112 if(q>20. && q<250. && pt0>fPtThreshold && c->IsInChamber()){
1113 ((TH3S*)arr->At(0))->Fill(dydx0, dy, sgm[fSegmentLevel]);
1114 ((TH3S*)arr->At(1))->Fill(sgm[fSegmentLevel], dy/TMath::Sqrt(c->GetSigmaY2()), dz/TMath::Sqrt(c->GetSigmaZ2()));
1117 // Fill calibration container
1118 Float_t d = zr0 - zmc;
1119 d -= ((Int_t)(2 * d)) / 2.0;
1120 if (d > 0.25) d = 0.5 - d;
1121 AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
1122 clInfo->SetCluster(c);
1123 clInfo->SetMC(pdg, label);
1124 clInfo->SetGlobalPosition(ymc, zmc, dydx0, dzdx0);
1125 clInfo->SetResolution(dy);
1126 clInfo->SetAnisochronity(d);
1127 clInfo->SetDriftLength(dx);
1128 clInfo->SetTilt(tilt);
1129 if(fMCcl) fMCcl->Add(clInfo);
1130 else AliDebug(1, "MCcl exchange container missing. Activate by calling \"InitExchangeContainers()\"");
1131 if(DebugLevel()>=5){
1133 clInfoArr=new TObjArray(AliTRDseedV1::kNclusters);
1134 clInfoArr->SetOwner(kFALSE);
1136 clInfoArr->Add(clInfo);
1140 if(DebugLevel()>=5 && clInfoArr){
1141 (*DebugStream()) << "MCcluster"
1142 <<"clInfo.=" << clInfoArr
1147 if(clInfoArr) delete clInfoArr;
1152 //________________________________________________________
1153 Bool_t AliTRDresolution::GetRefFigure(Int_t ifig)
1156 // Get the reference figures
1159 Float_t xy[4] = {0., 0., 0., 0.};
1161 AliWarning("Please provide a canvas to draw results.");
1164 Int_t selection[100], n(0), selStart(0); //
1165 Int_t ly0(0), dly(5);
1166 //Int_t ly0(1), dly(2); // used for SA
1167 TList *l(NULL); TVirtualPad *pad(NULL);
1168 TGraphErrors *g(NULL);TGraphAsymmErrors *ga(NULL);
1170 case 0: // charge resolution
1171 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1172 ((TVirtualPad*)l->At(0))->cd();
1173 ga=((TGraphAsymmErrors*)((TObjArray*)fGraphM->At(kCharge))->At(0));
1174 if(ga->GetN()) ga->Draw("apl");
1175 ((TVirtualPad*)l->At(1))->cd();
1176 g = ((TGraphErrors*)((TObjArray*)fGraphS->At(kCharge))->At(0));
1177 if(g->GetN()) g->Draw("apl");
1179 case 1: // cluster2track residuals
1180 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1181 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1182 pad = (TVirtualPad*)l->At(0); pad->cd();
1183 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1184 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1185 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1186 pad=(TVirtualPad*)l->At(1); pad->cd();
1187 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1188 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1189 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1191 case 2: // cluster2track residuals
1192 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1193 xy[0] = -.3; xy[1] = -100.; xy[2] = .3; xy[3] = 1000.;
1194 pad = (TVirtualPad*)l->At(0); pad->cd();
1195 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1196 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1197 if(!GetGraphArray(xy, kCluster, 0, 1, n, selection)) break;
1198 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-0.5; xy[3] = 2.5;
1199 pad=(TVirtualPad*)l->At(1); pad->cd();
1200 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1201 if(!GetGraphArray(xy, kCluster, 1, 1)) break;
1204 gPad->Divide(3, 2, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1205 xy[0] = -.3; xy[1] = -20.; xy[2] = .3; xy[3] = 100.;
1206 ((TVirtualPad*)l->At(0))->cd();
1207 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1208 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1210 ((TVirtualPad*)l->At(1))->cd();
1211 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1212 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1214 ((TVirtualPad*)l->At(2))->cd();
1215 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1216 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection)) break;
1218 ((TVirtualPad*)l->At(3))->cd();
1219 selStart=fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1220 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1222 ((TVirtualPad*)l->At(4))->cd();
1223 selStart=fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1224 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1226 ((TVirtualPad*)l->At(5))->cd();
1227 selStart=2*fgkNresYsegm[fSegmentLevel]/3+fgkNresYsegm[fSegmentLevel]; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1228 if(!GetGraphArray(xy, kTrack, 0, 1, n, selection, "[RC]")) break;
1231 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1233 xy[0] = -1.; xy[1] = -150.; xy[2] = 1.; xy[3] = 1000.;
1234 ((TVirtualPad*)l->At(0))->cd();
1236 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1238 xy[0] = -1.; xy[1] = -1500.; xy[2] = 1.; xy[3] = 10000.;
1239 ((TVirtualPad*)l->At(1))->cd();
1241 if(!GetGraphArray(xy, kTrack, 2, 1, 1, selection)) break;
1244 case 5: // kTrack pulls
1245 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1247 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1248 ((TVirtualPad*)l->At(0))->cd();
1249 if(!GetGraphArray(xy, kTrack, 1, 1)) break;
1251 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1252 ((TVirtualPad*)l->At(1))->cd();
1253 if(!GetGraphArray(xy, kTrack, 3, 1)) break;
1255 case 6: // kTrack phi
1256 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1257 if(GetGraph(&xy[0], kTrack , 4)) return kTRUE;
1259 case 7: // kTrackIn y
1260 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1261 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1262 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1263 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1264 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1265 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1266 pad=((TVirtualPad*)l->At(1)); pad->cd();
1267 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1268 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1269 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1271 case 8: // kTrackIn y
1272 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1273 xy[0] = -.3; xy[1] = -1500.; xy[2] = .3; xy[3] = 5000.;
1274 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1275 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1276 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1277 if(!GetGraphArray(xy, kTrackIn, 0, 1, n, selection)) break;
1278 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1279 pad=((TVirtualPad*)l->At(1)); pad->cd();
1280 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1281 if(!GetGraphArray(xy, kTrackIn, 1, 1)) break;
1283 case 9: // kTrackIn z
1284 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1285 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1286 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1287 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1289 if(!GetGraphArray(xy, kTrackIn, 2, 1, 1, selection)) break;
1290 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1291 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1292 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1293 if(!GetGraphArray(xy, kTrackIn, 3, 1)) break;
1295 case 10: // kTrackIn phi
1296 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1297 if(GetGraph(&xy[0], kTrackIn, 4)) return kTRUE;
1299 case 11: // kTrackOut y
1300 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1301 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1302 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1303 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1304 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1305 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1306 pad=((TVirtualPad*)l->At(1)); pad->cd();
1307 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1308 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1309 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1311 case 12: // kTrackOut y
1312 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1313 xy[0] = -.3; xy[1] = -50.; xy[2] = .3; xy[3] = 150.;
1314 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1315 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1316 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1317 if(!GetGraphArray(xy, kTrackOut, 0, 1, n, selection)) break;
1318 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1319 pad=((TVirtualPad*)l->At(1)); pad->cd();
1320 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1321 if(!GetGraphArray(xy, kTrackOut, 1, 1)) break;
1323 case 13: // kTrackOut z
1324 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1325 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
1326 pad = ((TVirtualPad*)l->At(0)); pad->cd();
1327 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1328 if(!GetGraphArray(xy, kTrackOut, 2, 1)) break;
1329 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1330 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1331 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
1332 if(!GetGraphArray(xy, kTrackOut, 3, 1)) break;
1334 case 14: // kTrackOut phi
1335 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
1336 if(GetGraph(&xy[0], kTrackOut, 4)) return kTRUE;
1338 case 15: // kMCcluster
1339 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1340 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1341 ((TVirtualPad*)l->At(0))->cd();
1342 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1343 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1344 ((TVirtualPad*)l->At(1))->cd();
1345 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1346 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1348 case 16: // kMCcluster
1349 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1350 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
1351 ((TVirtualPad*)l->At(0))->cd();
1352 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1353 if(!GetGraphArray(xy, kMCcluster, 0, 1, n, selection)) break;
1354 ((TVirtualPad*)l->At(1))->cd();
1355 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1356 if(!GetGraphArray(xy, kMCcluster, 1, 1)) break;
1358 case 17: //kMCtracklet [y]
1359 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1360 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1361 ((TVirtualPad*)l->At(0))->cd();
1362 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1363 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1364 ((TVirtualPad*)l->At(1))->cd();
1365 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1366 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1368 case 18: //kMCtracklet [y]
1369 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1370 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =500.;
1371 ((TVirtualPad*)l->At(0))->cd();
1372 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1373 if(!GetGraphArray(xy, kMCtracklet, 0, 1, n, selection)) break;
1374 ((TVirtualPad*)l->At(1))->cd();
1375 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1376 if(!GetGraphArray(xy, kMCtracklet, 1, 1)) break;
1378 case 19: //kMCtracklet [z]
1379 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1380 xy[0]=-1.; xy[1]=-100.; xy[2]=1.; xy[3] =2500.;
1381 ((TVirtualPad*)l->At(0))->cd();
1382 if(!GetGraphArray(xy, kMCtracklet, 2)) break;
1383 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1384 ((TVirtualPad*)l->At(1))->cd();
1385 if(!GetGraphArray(xy, kMCtracklet, 3)) break;
1387 case 20: //kMCtracklet [phi]
1388 xy[0]=-.3; xy[1]=-3.; xy[2]=.3; xy[3] =25.;
1389 if(!GetGraph(&xy[0], kMCtracklet, 4)) break;
1391 case 21: //kMCtrack [y] ly [0]
1392 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1393 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1394 ((TVirtualPad*)l->At(0))->cd();
1395 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1396 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1397 ((TVirtualPad*)l->At(1))->cd();
1398 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*0.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1399 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer1")) break;
1401 case 22: //kMCtrack [y] ly [1]
1402 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1403 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1404 ((TVirtualPad*)l->At(0))->cd();
1405 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1406 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1407 ((TVirtualPad*)l->At(1))->cd();
1408 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*1.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1409 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer2")) break;
1411 case 23: //kMCtrack [y] ly [2]
1412 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1413 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1414 ((TVirtualPad*)l->At(0))->cd();
1415 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1416 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1417 ((TVirtualPad*)l->At(1))->cd();
1418 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*2.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1419 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer3")) break;
1421 case 24: //kMCtrack [y] ly [3]
1422 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1423 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1424 ((TVirtualPad*)l->At(0))->cd();
1425 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1426 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1427 ((TVirtualPad*)l->At(1))->cd();
1428 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*3.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1429 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer4")) break;
1431 case 25: //kMCtrack [y] ly [4]
1432 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1433 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1434 ((TVirtualPad*)l->At(0))->cd();
1435 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1436 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1437 ((TVirtualPad*)l->At(1))->cd();
1438 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*4.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1439 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer5")) break;
1441 case 26: //kMCtrack [y] ly [5]
1442 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1443 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =400.;
1444 ((TVirtualPad*)l->At(0))->cd();
1445 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1446 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1447 ((TVirtualPad*)l->At(1))->cd();
1448 selStart=Int_t(fgkNresYsegm[fSegmentLevel]*5.5); for(n=0; n<fgkNresYsegm[fSegmentLevel]/2; n++) selection[n]=selStart+n;
1449 if(!GetGraphArray(xy, kMCtrack, 0, 1, n, selection, "Layer6")) break;
1451 case 27: //kMCtrack [y pulls]
1452 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1453 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 5.5;
1454 ((TVirtualPad*)l->At(0))->cd();
1455 selStart=0; for(n=0; n<6; n++) selection[n]=selStart+n;
1456 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1457 ((TVirtualPad*)l->At(1))->cd();
1458 selStart=6; for(n=0; n<6; n++) selection[n]=selStart+n;
1459 if(!GetGraphArray(xy, kMCtrack, 1, 1, n, selection)) break;
1461 case 28: //kMCtrack [z]
1462 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1463 xy[0]=-1.; xy[1]=-1500.; xy[2]=1.; xy[3] =6000.;
1464 ((TVirtualPad*)l->At(0))->cd();
1465 if(!GetGraphArray(xy, kMCtrack, 2)) break;
1466 xy[0] = -1.; xy[1] = -1.5; xy[2] = 1.; xy[3] = 5.;
1467 ((TVirtualPad*)l->At(1))->cd();
1468 if(!GetGraphArray(xy, kMCtrack, 3)) break;
1470 case 29: //kMCtrack [phi/snp]
1471 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1472 xy[0]=-.2; xy[1]=-0.5; xy[2]=.2; xy[3] =10.;
1473 ((TVirtualPad*)l->At(0))->cd();
1474 if(!GetGraphArray(xy, kMCtrack, 4)) break;
1475 xy[0] = -.2; xy[1] = -1.5; xy[2] = .2; xy[3] = 5.;
1476 ((TVirtualPad*)l->At(1))->cd();
1477 if(!GetGraphArray(xy, kMCtrack, 5)) break;
1479 case 30: //kMCtrack [theta/tgl]
1480 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1481 xy[0]=-1.; xy[1]=-0.5; xy[2]=1.; xy[3] =5.;
1482 ((TVirtualPad*)l->At(0))->cd();
1483 if(!GetGraphArray(xy, kMCtrack, 6)) break;
1484 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
1485 ((TVirtualPad*)l->At(1))->cd();
1486 if(!GetGraphArray(xy, kMCtrack, 7)) break;
1488 case 31: //kMCtrack [pt]
1489 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1490 pad = (TVirtualPad*)l->At(0); pad->cd();
1491 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1494 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1495 selection[n++] = il*11 + 2; // pi-
1496 selection[n++] = il*11 + 8; // pi+
1498 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1499 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1500 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#pi#pm")) break;
1501 pad->Modified(); pad->Update(); pad->SetLogx();
1502 pad = (TVirtualPad*)l->At(1); pad->cd();
1503 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1506 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1507 selection[n++] = il*11 + 3; // mu-
1508 selection[n++] = il*11 + 7; // mu+
1510 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "#mu#pm")) break;
1511 pad->Modified(); pad->Update(); pad->SetLogx();
1513 case 32: //kMCtrack [pt]
1514 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1515 pad = (TVirtualPad*)l->At(0); pad->cd();
1516 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1519 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1520 selection[n++] = il*11 + 0; // p bar
1521 selection[n++] = il*11 + 10; // p
1523 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1524 //xy[0] = 0.2; xy[1] = -1.; xy[2] = 7.; xy[3] = 10.; // SA
1525 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "p&p bar")) break;
1526 pad->Modified(); pad->Update(); pad->SetLogx();
1527 pad = (TVirtualPad*)l->At(1); pad->cd();
1528 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1531 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1532 selection[n++] = il*11 + 4; // e-
1533 selection[n++] = il*11 + 6; // e+
1535 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1536 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1537 if(!GetGraphArray(xy, kMCtrack, 8, kTRUE, n, selection, "e#pm")) break;
1538 pad->Modified(); pad->Update(); pad->SetLogx();
1540 case 33: //kMCtrack [1/pt] pulls
1541 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1542 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 4.5; // SA
1543 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1544 pad = (TVirtualPad*)l->At(0); pad->cd();
1545 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1548 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1549 selection[n++] = il*11 + 2; // pi-
1550 selection[n++] = il*11 + 8; // pi+
1552 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#pi#pm")) break;
1553 pad = (TVirtualPad*)l->At(1); pad->cd();
1554 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1557 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1558 selection[n++] = il*11 + 3; // mu-
1559 selection[n++] = il*11 + 7; // mu+
1561 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "#mu#pm")) break;
1563 case 34: //kMCtrack [1/pt] pulls
1564 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1565 pad = (TVirtualPad*)l->At(0); pad->cd();
1566 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1569 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1570 selection[n++] = il*11 + 0; // p bar
1571 selection[n++] = il*11 + 10; // p
1573 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1574 //xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 6.; // SA
1575 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "p & p bar")) break;
1576 pad = (TVirtualPad*)l->At(1); pad->cd();
1577 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1580 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1581 selection[n++] = il*11 + 4; // e-
1582 selection[n++] = il*11 + 6; // e+
1584 xy[0] = 0.; xy[1] = -2.; xy[2] = 2.; xy[3] = 4.5;
1585 if(!GetGraphArray(xy, kMCtrack, 9, kTRUE, n, selection, "e#pm")) break;
1587 case 35: //kMCtrack [p]
1588 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 4.;
1589 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1590 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1591 pad = (TVirtualPad*)l->At(0); pad->cd();
1592 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1595 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1596 selection[n++] = il*11 + 2; // pi-
1597 selection[n++] = il*11 + 8; // pi+
1599 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#pi#pm")) break;
1600 pad->Modified(); pad->Update(); pad->SetLogx();
1601 pad = (TVirtualPad*)l->At(1); pad->cd();
1602 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1605 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1606 selection[n++] = il*11 + 3; // mu-
1607 selection[n++] = il*11 + 7; // mu+
1609 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "#mu#pm")) break;
1610 pad->Modified(); pad->Update(); pad->SetLogx();
1612 case 36: //kMCtrack [p]
1613 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1614 pad = (TVirtualPad*)l->At(0); pad->cd();
1615 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1618 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1619 selection[n++] = il*11 + 0; // p bar
1620 selection[n++] = il*11 + 10; // p
1622 xy[0] = 0.2; xy[1] = -.7; xy[2] = 7.; xy[3] = 8.;
1623 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.; // SA
1624 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "p & p bar")) break;
1625 pad->Modified(); pad->Update(); pad->SetLogx();
1626 pad = (TVirtualPad*)l->At(1); pad->cd();
1627 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1630 for(Int_t il(ly0); il<AliTRDgeometry::kNlayer; il+=dly){
1631 selection[n++] = il*11 + 4; // e-
1632 selection[n++] = il*11 + 6; // e+
1634 xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 12.;
1635 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 14.; // SA
1636 if(!GetGraphArray(xy, kMCtrack, 10, kTRUE, n, selection, "e#pm")) break;
1637 pad->Modified(); pad->Update(); pad->SetLogx();
1639 case 37: // kMCtrackIn [y]
1640 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1641 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1642 ((TVirtualPad*)l->At(0))->cd();
1643 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1644 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1645 ((TVirtualPad*)l->At(1))->cd();
1646 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1647 if(!GetGraphArray(&xy[0], kMCtrackIn, 0, 1, n, selection)) break;
1649 case 38: // kMCtrackIn [y]
1650 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1651 xy[0]=-.25; xy[1]=-1000.; xy[2]=.25; xy[3] =3000.;
1652 ((TVirtualPad*)l->At(0))->cd();
1653 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1654 if(!GetGraphArray(xy, kMCtrackIn, 0, 1, n, selection)) break;
1655 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1656 ((TVirtualPad*)l->At(1))->cd();
1657 if(!GetGraphArray(xy, kMCtrackIn, 1, 1)) break;
1659 case 39: // kMCtrackIn [z]
1660 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1661 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =800.;
1662 ((TVirtualPad*)l->At(0))->cd();
1663 if(!GetGraphArray(xy, kMCtrackIn, 2, 1)) break;
1664 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1665 ((TVirtualPad*)l->At(1))->cd();
1666 if(!GetGraphArray(xy, kMCtrackIn, 3, 1)) break;
1668 case 40: // kMCtrackIn [phi|snp]
1669 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1670 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1671 ((TVirtualPad*)l->At(0))->cd();
1672 if(!GetGraph(&xy[0], kMCtrackIn, 4)) break;
1673 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1674 ((TVirtualPad*)l->At(1))->cd();
1675 if(!GetGraph(&xy[0], kMCtrackIn, 5)) break;
1677 case 41: // kMCtrackIn [theta|tgl]
1678 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1679 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1680 ((TVirtualPad*)l->At(0))->cd();
1681 if(!GetGraph(&xy[0], kMCtrackIn, 6)) break;
1682 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 1.5;
1683 ((TVirtualPad*)l->At(1))->cd();
1684 if(!GetGraph(&xy[0], kMCtrackIn, 7)) break;
1686 case 42: // kMCtrackIn [pt]
1687 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1688 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1689 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.; // SA
1690 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1691 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1692 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1693 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1694 pad = (TVirtualPad*)l->At(1); pad->cd(); pad->SetLogx();
1695 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1696 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1697 if(!GetGraphArray(xy, kMCtrackIn, 8, 1, n, selection)) break;
1699 case 43: //kMCtrackIn [1/pt] pulls
1700 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1701 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1702 pad = (TVirtualPad*)l->At(0); pad->cd();
1703 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1704 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1705 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1706 pad = (TVirtualPad*)l->At(1); pad->cd();
1707 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1708 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1709 if(!GetGraphArray(xy, kMCtrackIn, 9, 1, n, selection)) break;
1711 case 44: // kMCtrackIn [p]
1712 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1713 //xy[0] = 0.2; xy[1] = -1.5; xy[2] = 7.; xy[3] = 10.;
1714 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1715 pad = ((TVirtualPad*)l->At(0));pad->cd();pad->SetLogx();
1716 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1717 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1718 if(!GetGraphArray(xy, kMCtrackIn, 10, 1, n, selection)) break;
1719 pad = ((TVirtualPad*)l->At(1)); pad->cd();pad->SetLogx();
1720 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1721 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1722 if(!GetGraphArray(xy, kMCtrackIn, 10, 1, n, selection)) break;
1724 case 45: // kMCtrackOut [y]
1725 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1726 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1727 ((TVirtualPad*)l->At(0))->cd();
1728 selStart=0; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1729 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1730 ((TVirtualPad*)l->At(1))->cd();
1731 selStart=fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1732 if(!GetGraphArray(&xy[0], kMCtrackOut, 0, 1, n, selection)) break;
1734 case 46: // kMCtrackOut [y]
1735 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1736 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3] =400.;
1737 ((TVirtualPad*)l->At(0))->cd();
1738 selStart=2*fgkNresYsegm[fSegmentLevel]/3; for(n=0; n<fgkNresYsegm[fSegmentLevel]/3; n++) selection[n]=selStart+n;
1739 if(!GetGraphArray(xy, kMCtrackOut, 0, 1, n, selection)) break;
1740 xy[0] = -.5; xy[1] = -0.5; xy[2] = fgkNresYsegm[fSegmentLevel]-.5; xy[3] = 2.5;
1741 ((TVirtualPad*)l->At(1))->cd();
1742 if(!GetGraphArray(xy, kMCtrackOut, 1, 1)) break;
1744 case 47: // kMCtrackOut [z]
1745 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1746 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =1500.;
1747 ((TVirtualPad*)l->At(0))->cd();
1748 if(!GetGraphArray(xy, kMCtrackOut, 2, 1)) break;
1749 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
1750 ((TVirtualPad*)l->At(1))->cd();
1751 if(!GetGraphArray(xy, kMCtrackOut, 3, 1)) break;
1753 case 48: // kMCtrackOut [phi|snp]
1754 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1755 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
1756 ((TVirtualPad*)l->At(0))->cd();
1757 if(!GetGraph(&xy[0], kMCtrackOut, 4)) break;
1758 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
1759 ((TVirtualPad*)l->At(1))->cd();
1760 if(!GetGraph(&xy[0], kMCtrackOut, 5)) break;
1762 case 49: // kMCtrackOut [theta|tgl]
1763 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1764 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
1765 ((TVirtualPad*)l->At(0))->cd();
1766 if(!GetGraph(&xy[0], kMCtrackOut, 6)) break;
1767 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 15.;
1768 ((TVirtualPad*)l->At(1))->cd();
1769 if(!GetGraph(&xy[0], kMCtrackOut, 7)) break;
1771 case 50: // kMCtrackOut [pt]
1772 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1773 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1774 pad=(TVirtualPad*)l->At(0); pad->cd(); pad->SetLogx();
1775 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1776 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1777 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1778 pad = (TVirtualPad*)l->At(1); pad->cd();pad->SetLogx();
1779 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1780 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1781 if(!GetGraphArray(xy, kMCtrackOut, 8, 1, n, selection)) break;
1783 case 51: //kMCtrackOut [1/pt] pulls
1784 xy[0] = 0.; xy[1] = -1.; xy[2] = 2.; xy[3] = 3.5;
1785 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1786 pad = (TVirtualPad*)l->At(0); pad->cd();
1787 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1788 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1789 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1790 pad = (TVirtualPad*)l->At(1); pad->cd();
1791 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1792 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1793 if(!GetGraphArray(xy, kMCtrackOut, 9, 1, n, selection)) break;
1795 case 52: // kMCtrackOut [p]
1796 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
1797 xy[0] = 0.2; xy[1] = -.8; xy[2] = 7.; xy[3] = 6.;
1798 pad = ((TVirtualPad*)l->At(0));pad->cd();pad->SetLogx();
1799 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1800 n=0; selection[n++]=2; selection[n++]=3; selection[n++]=7; selection[n++]=8;
1801 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1802 pad = ((TVirtualPad*)l->At(1)); pad->cd();pad->SetLogx();
1803 pad->SetMargin(0.125, 0.015, 0.1, 0.015);
1804 n=0; selection[n++]=0; selection[n++]=4; selection[n++]=6; selection[n++]=10;
1805 if(!GetGraphArray(xy, kMCtrackOut, 10, 1, n, selection)) break;
1808 AliWarning(Form("Reference plot [%d] missing result", ifig));
1812 //________________________________________________________
1813 void AliTRDresolution::MakeSummary()
1815 // Build summary plots
1817 if(!fGraphS || !fGraphM){
1818 AliError("Missing results");
1821 Float_t xy[4] = {0., 0., 0., 0.};
1823 TH2 *h2 = new TH2I("h2SF", "", 20, -.2, .2, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5);
1824 h2->GetXaxis()->CenterTitle();
1825 h2->GetYaxis()->CenterTitle();
1826 h2->GetZaxis()->CenterTitle();h2->GetZaxis()->SetTitleOffset(1.4);
1828 Int_t ih2(0), iSumPlot(0);
1829 TCanvas *cOut = new TCanvas(Form("TRDsummary%s_%d", GetName(), iSumPlot++), "Cluster & Tracklet Resolution", 1024, 768);
1830 cOut->Divide(3,2, 2.e-3, 2.e-3, kYellow-7);
1831 TVirtualPad *p(NULL);
1834 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1835 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1836 h2->SetTitle(Form("Cluster-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1837 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kCluster))->At(0), h2);
1838 GetRange(h2, 1, range);
1839 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1844 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1845 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1846 h2->SetTitle(Form("Cluster-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1847 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kCluster))->At(0), h2);
1848 GetRange(h2, 0, range);
1849 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1854 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1855 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1856 GetGraphArray(xy, kCluster, 1, 1);
1859 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1860 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1861 h2->SetTitle(Form("Tracklet-Track R-Phi Residuals;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1862 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kTrack))->At(0), h2);
1863 GetRange(h2, 1, range);
1864 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1869 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1870 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1871 h2->SetTitle(Form("Tracklet-Track R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1872 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kTrack))->At(0), h2);
1873 GetRange(h2, 0, range);
1874 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1879 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1880 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1881 GetGraphArray(xy, kTrack, 1, 1);
1883 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1889 cOut->Clear(); cOut->SetName(Form("TRDsummary%s_%d", GetName(), iSumPlot++));
1890 cOut->Divide(3, 2, 2.e-3, 2.e-3, kBlue-10);
1893 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1894 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1895 h2->SetTitle(Form("Cluster-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1896 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCcluster))->At(0), h2);
1897 GetRange(h2, 1, range);
1898 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1903 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1904 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1906 h2->SetTitle(Form("Cluster-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1907 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCcluster))->At(0), h2);
1908 GetRange(h2, 0, range);
1909 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1914 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1915 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1916 GetGraphArray(xy, kMCcluster, 1, 1);
1919 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1920 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1922 h2->SetTitle(Form("Tracklet-MC R-Phi Resolution;tg(#phi);%s;Sigma [#mum]", fgkResYsegmName[fSegmentLevel]));
1923 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphS->At(kMCtracklet))->At(0), h2);
1924 GetRange(h2, 1, range);
1925 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1930 p->SetRightMargin(0.16);p->SetTopMargin(0.06);
1931 h2=(TH2I*)h2->Clone(Form("h2SF_%d", ih2++));
1933 h2->SetTitle(Form("Tracklet-MC R-Phi Systematics;tg(#phi);%s;Mean [#mum]", fgkResYsegmName[fSegmentLevel]));
1934 MakeSummaryPlot((TObjArray*) ((TObjArray*)fGraphM->At(kMCtracklet))->At(0), h2);
1935 GetRange(h2, 0, range);
1936 h2->GetZaxis()->SetRangeUser(range[0], range[1]);
1941 p->SetRightMargin(0.06);p->SetTopMargin(0.06);
1942 xy[0]=-.5; xy[1]=-0.5; xy[2]=fgkNresYsegm[fSegmentLevel]-.5; xy[3]=2.5;
1943 GetGraphArray(xy, kMCtracklet, 1, 1);
1945 cOut->SaveAs(Form("%s.gif", cOut->GetName()));
1949 //________________________________________________________
1950 void AliTRDresolution::GetRange(TH2 *h2, Char_t mod, Float_t *range)
1952 // Returns the range of the bulk of data in histogram h2. Removes outliers.
1953 // The "range" vector should be initialized with 2 elements
1954 // Option "mod" can be any of
1955 // - 0 : gaussian like distribution
1956 // - 1 : tailed distribution
1958 Int_t nx(h2->GetNbinsX())
1959 , ny(h2->GetNbinsY())
1961 Double_t *data=new Double_t[n];
1962 for(Int_t ix(1), in(0); ix<=nx; ix++){
1963 for(Int_t iy(1); iy<=ny; iy++)
1964 data[in++] = h2->GetBinContent(ix, iy);
1966 Double_t mean, sigm;
1967 AliMathBase::EvaluateUni(n, data, mean, sigm, Int_t(n*.8));
1969 range[0]=mean-3.*sigm; range[1]=mean+3.*sigm;
1970 if(mod==1) range[0]=TMath::Max(Float_t(1.e-3), range[0]);
1971 AliDebug(2, Form("h[%s] range0[%f %f]", h2->GetName(), range[0], range[1]));
1972 TH1S h1("h1SF0", "", 100, range[0], range[1]);
1977 case 0:// gaussian distribution
1979 TF1 fg("fg", "gaus", mean-3.*sigm, mean+3.*sigm);
1981 mean=fg.GetParameter(1); sigm=fg.GetParameter(2);
1982 range[0] = mean-2.5*sigm;range[1] = mean+2.5*sigm;
1983 AliDebug(2, Form(" rangeG[%f %f]", range[0], range[1]));
1986 case 1:// tailed distribution
1988 Int_t bmax(h1.GetMaximumBin());
1989 Int_t jBinMin(1), jBinMax(100);
1990 for(Int_t ibin(bmax); ibin--;){
1991 if(h1.GetBinContent(ibin)<1.){
1992 jBinMin=ibin; break;
1995 for(Int_t ibin(bmax); ibin++;){
1996 if(h1.GetBinContent(ibin)<1.){
1997 jBinMax=ibin; break;
2000 range[0]=h1.GetBinCenter(jBinMin); range[1]=h1.GetBinCenter(jBinMax);
2001 AliDebug(2, Form(" rangeT[%f %f]", range[0], range[1]));
2009 //________________________________________________________
2010 void AliTRDresolution::MakeSummaryPlot(TObjArray *a, TH2 *h2)
2012 // Core functionality for MakeSummary function.
2016 TGraphErrors *g(NULL); TAxis *ax(h2->GetXaxis());
2017 for(Int_t iseg(0); iseg<fgkNresYsegm[fSegmentLevel]; iseg++){
2018 g=(TGraphErrors*)a->At(iseg);
2019 for(Int_t in(0); in<g->GetN(); in++){
2020 g->GetPoint(in, x, y);
2021 h2->SetBinContent(ax->FindBin(x), iseg+1, y);
2027 //________________________________________________________
2028 Bool_t AliTRDresolution::PostProcess()
2030 // Fit, Project, Combine, Extract values from the containers filled during execution
2032 /*fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));*/
2034 AliError("ERROR: list not available");
2038 // define general behavior parameters
2039 const Color_t fgColorS[11]={
2040 kOrange, kOrange-3, kMagenta+1, kViolet, kRed,
2042 kRed, kViolet, kMagenta+1, kOrange-3, kOrange
2044 const Color_t fgColorM[11]={
2045 kCyan-5, kAzure-4, kBlue-7, kBlue+2, kViolet+10,
2047 kViolet+10, kBlue+2, kBlue-7, kAzure-4, kCyan-5
2049 const Marker_t fgMarker[11]={
2055 TGraph *gm= NULL, *gs= NULL;
2056 if(!fGraphS && !fGraphM){
2057 TObjArray *aM(NULL), *aS(NULL);
2058 Int_t n = fContainer->GetEntriesFast();
2059 fGraphS = new TObjArray(n); fGraphS->SetOwner();
2060 fGraphM = new TObjArray(n); fGraphM->SetOwner();
2061 for(Int_t ig(0), nc(0); ig<n; ig++){
2062 fGraphM->AddAt(aM = new TObjArray(fgNproj[ig]), ig);
2063 fGraphS->AddAt(aS = new TObjArray(fgNproj[ig]), ig);
2065 for(Int_t ic=0; ic<fgNproj[ig]; ic++, nc++){
2066 AliDebug(2, Form("building G[%d] P[%d] N[%d]", ig, ic, fNcomp[nc]));
2068 TObjArray *agS(NULL), *agM(NULL);
2069 aS->AddAt(agS = new TObjArray(fNcomp[nc]), ic);
2070 aM->AddAt(agM = new TObjArray(fNcomp[nc]), ic);
2071 for(Int_t is=fNcomp[nc]; is--;){
2072 agS->AddAt(gs = new TGraphErrors(), is);
2073 Int_t is0(is%11), il0(is/11);
2074 gs->SetMarkerStyle(fgMarker[is0]);
2075 gs->SetMarkerColor(fgColorS[is0]);
2076 gs->SetLineColor(fgColorS[is0]);
2077 gs->SetLineStyle(il0);gs->SetLineWidth(2);
2078 gs->SetName(Form("s_%d_%02d_%02d", ig, ic, is));
2080 agM->AddAt(gm = new TGraphErrors(), is);
2081 gm->SetMarkerStyle(fgMarker[is0]);
2082 gm->SetMarkerColor(fgColorM[is0]);
2083 gm->SetLineColor(fgColorM[is0]);
2084 gm->SetLineStyle(il0);gm->SetLineWidth(2);
2085 gm->SetName(Form("m_%d_%02d_%02d", ig, ic, is));
2086 // this is important for labels in the legend
2088 gs->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2089 gm->SetTitle(Form("%s %02d", fgkResYsegmName[fSegmentLevel], is%fgkNresYsegm[fSegmentLevel]));
2091 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"z":"y", is/2));
2092 gm->SetTitle(Form("%s Ly[%d]", is%2?"z":"y", is/2));
2093 } else if(ic==2||ic==3) {
2094 gs->SetTitle(Form("%s Ly[%d]", is%2 ?"RC":"no RC", is/2));
2095 gm->SetTitle(Form("%s Ly[%d]", is%2?"RC":"no RC", is/2));
2097 gs->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2098 gm->SetTitle(Form("Layer[%d]", is%AliTRDgeometry::kNlayer));
2100 gs->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2101 gm->SetTitle(Form("%s @ ly[%d]", fgParticle[is0], il0));
2105 aS->AddAt(gs = new TGraphErrors(), ic);
2106 gs->SetMarkerStyle(23);
2107 gs->SetMarkerColor(kRed);
2108 gs->SetLineColor(kRed);
2109 gs->SetNameTitle(Form("s_%d_%02d", ig, ic), "sigma");
2111 aM->AddAt(gm = ig ? (TGraph*)new TGraphErrors() : (TGraph*)new TGraphAsymmErrors(), ic);
2112 gm->SetLineColor(kBlack);
2113 gm->SetMarkerStyle(7);
2114 gm->SetMarkerColor(kBlack);
2115 gm->SetNameTitle(Form("m_%d_%02d", ig, ic), "mean");
2121 /* printf("\n\n\n"); fGraphS->ls();
2122 printf("\n\n\n"); fGraphM->ls();*/
2127 TF1 fg("fGauss", "gaus", -.5, .5);
2128 // Landau for charge resolution
2129 TF1 fch("fClCh", "landau", 0., 1000.);
2130 // Landau for e+- pt resolution
2131 TF1 fpt("fPt", "landau", -0.1, 0.2);
2133 //PROCESS EXPERIMENTAL DISTRIBUTIONS
2134 // Charge resolution
2135 //Process3DL(kCharge, 0, &fl);
2136 // Clusters residuals
2137 Process3D(kCluster, 0, &fg, 1.e4);
2138 Process3Dlinked(kCluster, 1, &fg);
2140 // Tracklet residual/pulls
2141 Process3D(kTrack , 0, &fg, 1.e4);
2142 Process3Dlinked(kTrack , 1, &fg);
2143 Process3D(kTrack , 2, &fg, 1.e4);
2144 Process3D(kTrack , 3, &fg);
2145 Process2D(kTrack , 4, &fg, 1.e3);
2147 // TRDin residual/pulls
2148 Process3D(kTrackIn, 0, &fg, 1.e4);
2149 Process3Dlinked(kTrackIn, 1, &fg);
2150 Process3D(kTrackIn, 2, &fg, 1.e4);
2151 Process3D(kTrackIn, 3, &fg);
2152 Process2D(kTrackIn, 4, &fg, 1.e3);
2154 // TRDout residual/pulls
2155 Process3D(kTrackOut, 0, &fg, 1.e3); // scale to fit - see PlotTrackOut
2156 Process3Dlinked(kTrackOut, 1, &fg);
2157 Process3D(kTrackOut, 2, &fg, 1.e4);
2158 Process3D(kTrackOut, 3, &fg);
2159 Process2D(kTrackOut, 4, &fg, 1.e3);
2162 if(!HasMCdata()) return kTRUE;
2165 //PROCESS MC RESIDUAL DISTRIBUTIONS
2167 // CLUSTER Y RESOLUTION/PULLS
2168 Process3D(kMCcluster, 0, &fg, 1.e4);
2169 Process3Dlinked(kMCcluster, 1, &fg, 1.);
2172 // TRACKLET RESOLUTION/PULLS
2173 Process3D(kMCtracklet, 0, &fg, 1.e4); // y
2174 Process3Dlinked(kMCtracklet, 1, &fg, 1.); // y pulls
2175 Process3D(kMCtracklet, 2, &fg, 1.e4); // z
2176 Process3D(kMCtracklet, 3, &fg, 1.); // z pulls
2177 Process2D(kMCtracklet, 4, &fg, 1.e3); // phi
2180 // TRACK RESOLUTION/PULLS
2181 Process3Darray(kMCtrack, 0, &fg, 1.e4); // y
2182 Process3DlinkedArray(kMCtrack, 1, &fg); // y PULL
2183 Process3Darray(kMCtrack, 2, &fg, 1.e4); // z
2184 Process3Darray(kMCtrack, 3, &fg); // z PULL
2185 Process2Darray(kMCtrack, 4, &fg, 1.e3); // phi
2186 Process2Darray(kMCtrack, 5, &fg); // snp PULL
2187 Process2Darray(kMCtrack, 6, &fg, 1.e3); // theta
2188 Process2Darray(kMCtrack, 7, &fg); // tgl PULL
2189 Process3Darray(kMCtrack, 8, &fg, 1.e2); // pt resolution
2190 Process3Darray(kMCtrack, 9, &fg); // 1/pt pulls
2191 Process3Darray(kMCtrack, 10, &fg, 1.e2); // p resolution
2194 // TRACK TRDin RESOLUTION/PULLS
2195 Process3D(kMCtrackIn, 0, &fg, 1.e4);// y resolution
2196 Process3Dlinked(kMCtrackIn, 1, &fg); // y pulls
2197 Process3D(kMCtrackIn, 2, &fg, 1.e4);// z resolution
2198 Process3D(kMCtrackIn, 3, &fg); // z pulls
2199 Process2D(kMCtrackIn, 4, &fg, 1.e3);// phi resolution
2200 Process2D(kMCtrackIn, 5, &fg); // snp pulls
2201 Process2D(kMCtrackIn, 6, &fg, 1.e3);// theta resolution
2202 Process2D(kMCtrackIn, 7, &fg); // tgl pulls
2203 Process3D(kMCtrackIn, 8, &fg, 1.e2);// pt resolution
2204 Process3D(kMCtrackIn, 9, &fg); // 1/pt pulls
2205 Process3D(kMCtrackIn, 10, &fg, 1.e2);// p resolution
2208 // TRACK TRDout RESOLUTION/PULLS
2209 Process3D(kMCtrackOut, 0, &fg, 1.e4);// y resolution
2210 Process3Dlinked(kMCtrackOut, 1, &fg); // y pulls
2211 Process3D(kMCtrackOut, 2, &fg, 1.e4);// z resolution
2212 Process3D(kMCtrackOut, 3, &fg); // z pulls
2213 Process2D(kMCtrackOut, 4, &fg, 1.e3);// phi resolution
2214 Process2D(kMCtrackOut, 5, &fg); // snp pulls
2215 Process2D(kMCtrackOut, 6, &fg, 1.e3);// theta resolution
2216 Process2D(kMCtrackOut, 7, &fg); // tgl pulls
2217 Process3D(kMCtrackOut, 8, &fg, 1.e2);// pt resolution
2218 Process3D(kMCtrackOut, 9, &fg); // 1/pt pulls
2219 Process3D(kMCtrackOut, 10, &fg, 1.e2);// p resolution
2226 //________________________________________________________
2227 void AliTRDresolution::Terminate(Option_t *opt)
2229 AliTRDrecoTask::Terminate(opt);
2230 if(HasPostProcess()) PostProcess();
2233 //________________________________________________________
2234 void AliTRDresolution::AdjustF1(TH1 *h, TF1 *f)
2236 // Helper function to avoid duplication of code
2237 // Make first guesses on the fit parameters
2239 // find the intial parameters of the fit !! (thanks George)
2240 Int_t nbinsy = Int_t(.5*h->GetNbinsX());
2242 for(Int_t jbin=nbinsy-4; jbin<=nbinsy+4; jbin++) sum+=h->GetBinContent(jbin); sum/=9.;
2243 f->SetParLimits(0, 0., 3.*sum);
2244 f->SetParameter(0, .9*sum);
2245 Double_t rms = h->GetRMS();
2246 f->SetParLimits(1, -rms, rms);
2247 f->SetParameter(1, h->GetMean());
2249 f->SetParLimits(2, 0., 2.*rms);
2250 f->SetParameter(2, rms);
2251 if(f->GetNpar() <= 4) return;
2253 f->SetParLimits(3, 0., sum);
2254 f->SetParameter(3, .1*sum);
2256 f->SetParLimits(4, -.3, .3);
2257 f->SetParameter(4, 0.);
2259 f->SetParLimits(5, 0., 1.e2);
2260 f->SetParameter(5, 2.e-1);
2263 //________________________________________________________
2264 TObjArray* AliTRDresolution::BuildMonitorContainerCluster(const char* name, Bool_t expand)
2266 // Build performance histograms for AliTRDcluster.vs TRD track or MC
2267 // - y reziduals/pulls
2269 TObjArray *arr = new TObjArray(2);
2270 arr->SetName(name); arr->SetOwner();
2271 TH1 *h(NULL); char hname[100], htitle[300];
2273 // tracklet resolution/pull in y direction
2274 sprintf(hname, "%s_%s_Y", GetNameId(), name);
2275 sprintf(htitle, "Y res for \"%s\" @ %s;tg(#phi);#Delta y [cm];%s", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2276 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2277 Int_t nybins=fgkNresYsegm[fSegmentLevel];
2278 if(expand) nybins*=2;
2279 h = new TH3S(hname, htitle,
2280 48, -.48, .48, // phi
2281 60, -fDyRange, fDyRange, // dy
2282 nybins, -0.5, nybins-0.5);// segment
2285 sprintf(hname, "%s_%s_YZpull", GetNameId(), name);
2286 sprintf(htitle, "YZ pull for \"%s\" @ %s;%s;#Delta y / #sigma_{y};#Delta z / #sigma_{z}", GetNameId(), name, fgkResYsegmName[fSegmentLevel]);
2287 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2288 h = new TH3S(hname, htitle, fgkNresYsegm[fSegmentLevel], -0.5, fgkNresYsegm[fSegmentLevel]-0.5, 100, -4.5, 4.5, 100, -4.5, 4.5);
2295 //________________________________________________________
2296 TObjArray* AliTRDresolution::BuildMonitorContainerTracklet(const char* name, Bool_t expand)
2298 // Build performance histograms for AliExternalTrackParam.vs TRD tracklet
2299 // - y reziduals/pulls
2300 // - z reziduals/pulls
2302 TObjArray *arr = BuildMonitorContainerCluster(name, expand);
2304 TH1 *h(NULL); char hname[100], htitle[300];
2306 // tracklet resolution/pull in z direction
2307 sprintf(hname, "%s_%s_Z", GetNameId(), name);
2308 sprintf(htitle, "Z res for \"%s\" @ %s;tg(#theta);#Delta z [cm];row cross", GetNameId(), name);
2309 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2310 h = new TH3S(hname, htitle, 50, -1., 1., 100, -1.5, 1.5, 2, -0.5, 1.5);
2313 sprintf(hname, "%s_%s_Zpull", GetNameId(), name);
2314 sprintf(htitle, "Z pull for \"%s\" @ %s;tg(#theta);#Delta z / #sigma_{z};row cross", GetNameId(), name);
2315 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2316 h = new TH3S(hname, htitle, 50, -1., 1., 100, -5.5, 5.5, 2, -0.5, 1.5);
2317 h->GetZaxis()->SetBinLabel(1, "no RC");
2318 h->GetZaxis()->SetBinLabel(2, "RC");
2322 // tracklet to track phi resolution
2323 sprintf(hname, "%s_%s_PHI", GetNameId(), name);
2324 sprintf(htitle, "#Phi res for \"%s\" @ %s;tg(#phi);#Delta #phi [rad];entries", GetNameId(), name);
2325 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2326 h = new TH2I(hname, htitle, 21, -.33, .33, 100, -.5, .5);
2333 //________________________________________________________
2334 TObjArray* AliTRDresolution::BuildMonitorContainerTrack(const char* name)
2336 // Build performance histograms for AliExternalTrackParam.vs MC
2337 // - y resolution/pulls
2338 // - z resolution/pulls
2339 // - phi resolution, snp pulls
2340 // - theta resolution, tgl pulls
2341 // - pt resolution, 1/pt pulls, p resolution
2343 TObjArray *arr = BuildMonitorContainerTracklet(name);
2345 TH1 *h(NULL); char hname[100], htitle[300];
2349 sprintf(hname, "%s_%s_SNPpull", GetNameId(), name);
2350 sprintf(htitle, "SNP pull for \"%s\" @ %s;tg(#phi);#Delta snp / #sigma_{snp};entries", GetNameId(), name);
2351 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2352 h = new TH2I(hname, htitle, 60, -.3, .3, 100, -4.5, 4.5);
2357 sprintf(hname, "%s_%s_THT", GetNameId(), name);
2358 sprintf(htitle, "#Theta res for \"%s\" @ %s;tg(#theta);#Delta #theta [rad];entries", GetNameId(), name);
2359 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2360 h = new TH2I(hname, htitle, 100, -1., 1., 100, -5e-3, 5e-3);
2364 sprintf(hname, "%s_%s_TGLpull", GetNameId(), name);
2365 sprintf(htitle, "TGL pull for \"%s\" @ %s;tg(#theta);#Delta tgl / #sigma_{tgl};entries", GetNameId(), name);
2366 if(!(h = (TH2I*)gROOT->FindObject(hname))){
2367 h = new TH2I(hname, htitle, 100, -1., 1., 100, -4.5, 4.5);
2371 const Int_t kNpt(14);
2372 const Int_t kNdpt(150);
2373 const Int_t kNspc = 2*AliPID::kSPECIES+1;
2374 Float_t lPt=0.1, lDPt=-.1, lSpc=-5.5;
2375 Float_t binsPt[kNpt+1], binsSpc[kNspc+1], binsDPt[kNdpt+1];
2376 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2377 for(Int_t i=0; i<kNspc+1; i++,lSpc+=1.) binsSpc[i]=lSpc;
2378 for(Int_t i=0; i<kNdpt+1; i++,lDPt+=2.e-3) binsDPt[i]=lDPt;
2381 sprintf(hname, "%s_%s_Pt", GetNameId(), name);
2382 sprintf(htitle, "P_{t} res for \"%s\" @ %s;p_{t} [GeV/c];#Delta p_{t}/p_{t}^{MC};SPECIES", GetNameId(), name);
2383 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2384 h = new TH3S(hname, htitle,
2385 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2387 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2391 sprintf(hname, "%s_%s_1Pt", GetNameId(), name);
2392 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);
2393 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2394 h = new TH3S(hname, htitle,
2395 kNpt, 0., 2., 100, -4., 4., kNspc, -5.5, 5.5);
2397 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2401 sprintf(hname, "%s_%s_P", GetNameId(), name);
2402 sprintf(htitle, "P res for \"%s\" @ %s;p [GeV/c];#Delta p/p^{MC};SPECIES", GetNameId(), name);
2403 if(!(h = (TH3S*)gROOT->FindObject(hname))){
2404 h = new TH3S(hname, htitle,
2405 kNpt, binsPt, kNdpt, binsDPt, kNspc, binsSpc);
2407 for(Int_t ib(1); ib<=ax->GetNbins(); ib++) ax->SetBinLabel(ib, fgParticle[ib-1]);
2415 //________________________________________________________
2416 TObjArray* AliTRDresolution::Histos()
2419 // Define histograms
2422 if(fContainer) return fContainer;
2424 fContainer = new TObjArray(kNviews);
2425 //fContainer->SetOwner(kTRUE);
2427 TObjArray *arr(NULL);
2429 // binnings for plots containing momentum or pt
2430 const Int_t kNpt(14), kNphi(48), kNdy(60);
2431 Float_t lPhi=-.48, lDy=-.3, lPt=0.1;
2432 Float_t binsPhi[kNphi+1], binsDy[kNdy+1], binsPt[kNpt+1];
2433 for(Int_t i=0; i<kNphi+1; i++,lPhi+=.02) binsPhi[i]=lPhi;
2434 for(Int_t i=0; i<kNdy+1; i++,lDy+=.01) binsDy[i]=lDy;
2435 for(Int_t i=0;i<kNpt+1; i++,lPt=TMath::Exp(i*.15)-1.) binsPt[i]=lPt;
2437 // cluster to track residuals/pulls
2438 fContainer->AddAt(arr = new TObjArray(2), kCharge);
2439 arr->SetName("Charge");
2440 if(!(h = (TH3S*)gROOT->FindObject("hCharge"))){
2441 h = new TH3S("hCharge", "Charge Resolution", 20, 1., 2., 24, 0., 3.6, 100, 0., 500.);
2442 h->GetXaxis()->SetTitle("dx/dx_{0}");
2443 h->GetYaxis()->SetTitle("x_{d} [cm]");
2444 h->GetZaxis()->SetTitle("dq/dx [ADC/cm]");
2448 // cluster to track residuals/pulls
2449 fContainer->AddAt(BuildMonitorContainerCluster("Cl"), kCluster);
2450 // tracklet to TRD track
2451 fContainer->AddAt(BuildMonitorContainerTracklet("Trk", kTRUE), kTrack);
2452 // tracklet to TRDin
2453 fContainer->AddAt(BuildMonitorContainerTracklet("TrkIN", kTRUE), kTrackIn);
2454 // tracklet to TRDout
2455 fContainer->AddAt(BuildMonitorContainerTracklet("TrkOUT"), kTrackOut);
2458 // Resolution histos
2459 if(!HasMCdata()) return fContainer;
2461 // cluster resolution
2462 fContainer->AddAt(BuildMonitorContainerCluster("MCcl"), kMCcluster);
2464 // tracklet resolution
2465 fContainer->AddAt(BuildMonitorContainerTracklet("MCtracklet"), kMCtracklet);
2468 fContainer->AddAt(arr = new TObjArray(AliTRDgeometry::kNlayer), kMCtrack);
2469 arr->SetName("MCtrk");
2470 for(Int_t il(0); il<AliTRDgeometry::kNlayer; il++) arr->AddAt(BuildMonitorContainerTrack(Form("MCtrk_Ly%d", il)), il);
2472 // TRDin TRACK RESOLUTION
2473 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkIN"), kMCtrackIn);
2475 // TRDout TRACK RESOLUTION
2476 fContainer->AddAt(BuildMonitorContainerTrack("MCtrkOUT"), kMCtrackOut);
2481 //________________________________________________________
2482 Bool_t AliTRDresolution::Load(const Char_t *file, const Char_t *dir)
2484 // Custom load function. Used to guess the segmentation level of the data.
2486 if(!AliTRDrecoTask::Load(file, dir)) return kFALSE;
2488 // look for cluster residual plot - always available
2489 TH3S* h3((TH3S*)((TObjArray*)fContainer->At(kClToTrk))->At(0));
2490 Int_t segmentation(h3->GetNbinsZ()/2);
2491 if(segmentation==fgkNresYsegm[0]){ // default segmentation. Nothing to do
2493 } else if(segmentation==fgkNresYsegm[1]){ // stack segmentation.
2494 SetSegmentationLevel(1);
2495 } else if(segmentation==fgkNresYsegm[2]){ // detector segmentation.
2496 SetSegmentationLevel(2);
2498 AliError(Form("Unknown segmentation [%d].", h3->GetNbinsZ()));
2502 AliDebug(2, Form("Segmentation set to level \"%s\"", fgkResYsegmName[fSegmentLevel]));
2507 //________________________________________________________
2508 Bool_t AliTRDresolution::Process(TH2 * const h2, TF1 *f, Float_t k, TGraphErrors **g)
2511 // Do the processing
2514 Char_t pn[10]; sprintf(pn, "p%03d", fIdxPlot);
2516 if((n=g[0]->GetN())) for(;n--;) g[0]->RemovePoint(n);
2517 if((n=g[1]->GetN())) for(;n--;) g[1]->RemovePoint(n);
2518 if(Int_t(h2->GetEntries())){
2519 AliDebug(4, Form("%s: g[%s %s]", pn, g[0]->GetName(), g[0]->GetTitle()));
2521 AliDebug(2, Form("%s: g[%s %s]: Missing entries.", pn, g[0]->GetName(), g[0]->GetTitle()));
2526 const Int_t kINTEGRAL=1;
2527 for(Int_t ibin = 0; ibin < Int_t(h2->GetNbinsX()/kINTEGRAL); ibin++){
2528 Int_t abin(ibin*kINTEGRAL+1),bbin(abin+kINTEGRAL-1),mbin(abin+Int_t(kINTEGRAL/2));
2529 Double_t x = h2->GetXaxis()->GetBinCenter(mbin);
2530 TH1D *h = h2->ProjectionY(pn, abin, bbin);
2531 if((n=(Int_t)h->GetEntries())<150){
2532 AliDebug(4, Form(" x[%f] range[%d %d] stat[%d] low statistics !", x, abin, bbin, n));
2536 Int_t ip = g[0]->GetN();
2537 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)));
2538 g[0]->SetPoint(ip, x, k*f->GetParameter(1));
2539 g[0]->SetPointError(ip, 0., k*f->GetParError(1));
2540 g[1]->SetPoint(ip, x, k*f->GetParameter(2));
2541 g[1]->SetPointError(ip, 0., k*f->GetParError(2));
2543 g[0]->SetPoint(ip, x, k*h->GetMean());
2544 g[0]->SetPointError(ip, 0., k*h->GetMeanError());
2545 g[1]->SetPoint(ip, x, k*h->GetRMS());
2546 g[1]->SetPointError(ip, 0., k*h->GetRMSError());*/
2552 //________________________________________________________
2553 Bool_t AliTRDresolution::Process2D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k, Int_t gidx)
2556 // Do the processing
2559 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2561 // retrive containers
2564 if(!(h2= (TH2I*)(fContainer->At(plot)))) return kFALSE;
2566 TObjArray *a0(NULL);
2567 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2568 if(!(h2=(TH2I*)a0->At(idx))) return kFALSE;
2570 if(Int_t(h2->GetEntries())){
2571 AliDebug(2, Form("p[%d] idx[%d] : h[%s] %s", plot, idx, h2->GetName(), h2->GetTitle()));
2573 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2578 if(gidx<0) gidx=idx;
2579 if(!(g[0] = gidx<0 ? (TGraphErrors*)fGraphM->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphM->At(plot)))->At(gidx))) return kFALSE;
2581 if(!(g[1] = gidx<0 ? (TGraphErrors*)fGraphS->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphS->At(plot)))->At(gidx))) return kFALSE;
2583 return Process(h2, f, k, g);
2586 //________________________________________________________
2587 Bool_t AliTRDresolution::Process3D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2590 // Do the processing
2593 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2595 // retrive containers
2598 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2600 TObjArray *a0(NULL);
2601 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2602 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2604 if(Int_t(h3->GetEntries())){
2605 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2607 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2612 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2613 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2616 TAxis *az = h3->GetZaxis();
2617 for(Int_t iz(0); iz<gm->GetEntriesFast(); iz++){
2618 if(!(g[0] = (TGraphErrors*)gm->At(iz))) return kFALSE;
2619 if(!(g[1] = (TGraphErrors*)gs->At(iz))) return kFALSE;
2620 az->SetRange(iz+1, iz+1);
2621 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2628 //________________________________________________________
2629 Bool_t AliTRDresolution::Process3Dlinked(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2632 // Do the processing
2635 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2637 // retrive containers
2640 if(!(h3= (TH3S*)(fContainer->At(plot)))) return kFALSE;
2642 TObjArray *a0(NULL);
2643 if(!(a0=(TObjArray*)(fContainer->At(plot)))) return kFALSE;
2644 if(!(h3=(TH3S*)a0->At(idx))) return kFALSE;
2646 if(Int_t(h3->GetEntries())){
2647 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2649 AliDebug(2, Form("p[%d] idx[%d] : Missing entries.", plot, idx));
2654 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2655 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2658 if(!(g[0] = (TGraphErrors*)gm->At(0))) return kFALSE;
2659 if(!(g[1] = (TGraphErrors*)gs->At(0))) return kFALSE;
2660 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2662 if(!(g[0] = (TGraphErrors*)gm->At(1))) return kFALSE;
2663 if(!(g[1] = (TGraphErrors*)gs->At(1))) return kFALSE;
2664 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2670 //________________________________________________________
2671 Bool_t AliTRDresolution::Process3DL(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2674 // Do the processing
2677 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2679 // retrive containers
2680 TH3S *h3 = (TH3S*)((TObjArray*)fContainer->At(plot))->At(idx);
2681 if(!h3) return kFALSE;
2682 AliDebug(2, Form("p[%d] idx[%d] h[%s] %s", plot, idx, h3->GetName(), h3->GetTitle()));
2684 TGraphAsymmErrors *gm;
2686 if(!(gm = (TGraphAsymmErrors*)((TObjArray*)fGraphM->At(plot))->At(0))) return kFALSE;
2687 if(!(gs = (TGraphErrors*)((TObjArray*)fGraphS->At(plot)))) return kFALSE;
2689 Float_t x, r, mpv, xM, xm;
2690 TAxis *ay = h3->GetYaxis();
2691 for(Int_t iy=1; iy<=h3->GetNbinsY(); iy++){
2692 ay->SetRange(iy, iy);
2693 x = ay->GetBinCenter(iy);
2694 TH2F *h2=(TH2F*)h3->Project3D("zx");
2695 TAxis *ax = h2->GetXaxis();
2696 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
2697 r = ax->GetBinCenter(ix);
2698 TH1D *h1 = h2->ProjectionY("py", ix, ix);
2699 if(h1->Integral()<50) continue;
2702 GetLandauMpvFwhm(f, mpv, xm, xM);
2703 Int_t ip = gm->GetN();
2704 gm->SetPoint(ip, x, k*mpv);
2705 gm->SetPointError(ip, 0., 0., k*xm, k*xM);
2706 gs->SetPoint(ip, r, k*(xM-xm)/mpv);
2707 gs->SetPointError(ip, 0., 0.);
2714 //________________________________________________________
2715 Bool_t AliTRDresolution::Process2Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2718 // Do the processing
2721 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2723 // retrive containers
2724 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2725 if(!arr) return kFALSE;
2726 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2729 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2730 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2732 TGraphErrors *g[2]; TH2I *h2(NULL); TObjArray *a0(NULL);
2733 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2734 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2736 if(!(h2 = (TH2I*)a0->At(idx))) return kFALSE;
2737 if(Int_t(h2->GetEntries())){
2738 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h2->GetName(), h2->GetTitle()));
2740 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2744 if(!(g[0] = (TGraphErrors*)gm->At(ia))) return kFALSE;
2745 if(!(g[1] = (TGraphErrors*)gs->At(ia))) return kFALSE;
2746 if(!Process(h2, f, k, g)) return kFALSE;
2752 //________________________________________________________
2753 Bool_t AliTRDresolution::Process3Darray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2756 // Do the processing
2759 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2760 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2762 // retrive containers
2763 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2764 if(!arr) return kFALSE;
2765 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2768 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2769 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2771 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2773 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2774 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2776 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2777 if(Int_t(h3->GetEntries())){
2778 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2780 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2783 TAxis *az = h3->GetZaxis();
2784 for(Int_t iz=1; iz<=az->GetNbins(); iz++, in++){
2785 if(in >= gm->GetEntriesFast()) break;
2786 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2787 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2788 az->SetRange(iz, iz);
2789 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2792 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2797 //________________________________________________________
2798 Bool_t AliTRDresolution::Process3DlinkedArray(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
2801 // Do the processing
2804 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
2805 //printf("Process4D : processing plot[%d] idx[%d]\n", plot, idx);
2807 // retrive containers
2808 TObjArray *arr = (TObjArray*)(fContainer->At(plot));
2809 if(!arr) return kFALSE;
2810 AliDebug(2, Form("p[%d] idx[%d] arr[%s]", plot, idx, arr->GetName()));
2813 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
2814 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
2816 TGraphErrors *g[2]; TH3S *h3(NULL); TObjArray *a0(NULL);
2818 for(Int_t ia(0); ia<arr->GetEntriesFast(); ia++){
2819 if(!(a0 = (TObjArray*)arr->At(ia))) continue;
2820 if(!(h3 = (TH3S*)a0->At(idx))) return kFALSE;
2821 if(Int_t(h3->GetEntries())){
2822 AliDebug(4, Form(" idx[%d] h[%s] %s", ia, h3->GetName(), h3->GetTitle()));
2824 AliDebug(2, Form(" idx[%d] : Missing entries.", ia));
2827 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2828 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2829 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
2832 if(!(g[0] = (TGraphErrors*)gm->At(in))) return kFALSE;
2833 if(!(g[1] = (TGraphErrors*)gs->At(in))) return kFALSE;
2834 if(!Process((TH2*)h3->Project3D("zx"), f, k, g)) return kFALSE;
2837 AliDebug(2, Form("Projections [%d] from [%d]", in, gs->GetEntriesFast()));
2842 //________________________________________________________
2843 Bool_t AliTRDresolution::GetGraph(Float_t *bb, ETRDresolutionPlot ip, Int_t idx, Bool_t kLEG, const Char_t *explain)
2849 if(!fGraphS || !fGraphM) return kFALSE;
2850 // axis titles look up
2852 for(Int_t jp=0; jp<(Int_t)ip; jp++) nref+=fgNproj[jp];
2853 UChar_t jdx = idx<0?0:idx;
2854 for(Int_t jc=0; jc<TMath::Min(jdx,fgNproj[ip]-1); jc++) nref++;
2855 Char_t **at = fAxTitle[nref];
2857 // build legends if requiered
2860 leg=new TLegend(.65, .6, .95, .9);
2861 leg->SetBorderSize(0);
2862 leg->SetFillStyle(0);
2866 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]);
2867 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
2868 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
2870 TAxis *ax = h1->GetXaxis();
2871 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
2872 ax = h1->GetYaxis();
2873 ax->SetRangeUser(bb[1], bb[3]);
2874 ax->CenterTitle(); ax->SetTitleOffset(1.4);
2877 TBox *b = new TBox(-.15, bb[1], .15, bb[3]);
2878 b->SetFillStyle(3002);b->SetLineColor(0);
2879 b->SetFillColor(ip<=Int_t(kMCcluster)?kGreen:kBlue);
2882 TGraphErrors *gm = idx<0 ? (TGraphErrors*)fGraphM->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphM->At(ip)))->At(idx);
2883 if(!gm) return kFALSE;
2884 TGraphErrors *gs = idx<0 ? (TGraphErrors*)fGraphS->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphS->At(ip)))->At(idx);
2885 if(!gs) return kFALSE;
2887 Int_t n(0), nPlots(0);
2888 if((n=gm->GetN())) {
2890 gm->Draw("pl"); if(leg) leg->AddEntry(gm, gm->GetTitle(), "pl");
2891 PutTrendValue(Form("%s_%s", fgPerformanceName[ip], at[0]), gm->GetMean(2));
2892 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[ip], at[0]), gm->GetRMS(2));
2897 gs->Draw("pl"); if(leg) leg->AddEntry(gs, gs->GetTitle(), "pl");
2898 gs->Sort(&TGraph::CompareY);
2899 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[ip], at[0]), gs->GetY()[0]);
2900 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[ip], at[0]), gs->GetY()[n-1]);
2901 gs->Sort(&TGraph::CompareX);
2903 if(!nPlots) return kFALSE;
2904 if(leg) leg->Draw();
2908 //________________________________________________________
2909 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)
2915 if(!fGraphS || !fGraphM) return kFALSE;
2917 // axis titles look up
2919 for(Int_t jp(0); jp<ip; jp++) nref+=fgNproj[jp];
2921 Char_t **at = fAxTitle[nref];
2923 // build legends if requiered
2924 TLegend *legM(NULL), *legS(NULL);
2926 legM=new TLegend(.35, .6, .65, .9);
2927 legM->SetHeader("Mean");
2928 legM->SetBorderSize(0);
2929 legM->SetFillStyle(0);
2930 legS=new TLegend(.65, .6, .95, .9);
2931 legS->SetHeader("Sigma");
2932 legS->SetBorderSize(0);
2933 legS->SetFillStyle(0);
2937 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]);
2938 h1->SetMinimum(bb[1]);h1->SetMaximum(bb[3]);
2939 h1->SetLineColor(kBlack); h1->SetLineWidth(1);h1->SetLineStyle(2);
2941 TAxis *ax = h1->GetXaxis();
2942 ax->CenterTitle();ax->SetMoreLogLabels();ax->SetTitleOffset(1.2);
2943 ax = h1->GetYaxis();
2944 ax->SetRangeUser(bb[1], bb[3]);
2945 ax->CenterTitle(); ax->SetTitleOffset(1.4);
2948 TGraphErrors *gm(NULL), *gs(NULL);
2949 TObjArray *a0(NULL), *a1(NULL);
2950 a0 = (TObjArray*)((TObjArray*)fGraphM->At(ip))->At(idx);
2951 a1 = (TObjArray*)((TObjArray*)fGraphS->At(ip))->At(idx);
2952 if(!n) n=a0->GetEntriesFast();
2953 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'));
2954 Int_t nn(0), nPlots(0);
2955 for(Int_t is(0), is0(0); is<n; is++){
2956 is0 = sel ? sel[is] : is;
2957 if(!(gs = (TGraphErrors*)a1->At(is0))) return kFALSE;
2958 if(!(gm = (TGraphErrors*)a0->At(is0))) return kFALSE;
2960 if((nn=gs->GetN())){
2964 //printf("LegEntry %s [%s]%s\n", at[0], gs->GetName(), gs->GetTitle());
2965 legS->AddEntry(gs, gs->GetTitle(), "pl");
2967 gs->Sort(&TGraph::CompareY);
2968 PutTrendValue(Form("%s_%sSigMin", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[0]);
2969 PutTrendValue(Form("%s_%sSigMax", fgPerformanceName[kMCtrack], at[0]), gs->GetY()[nn-1]);
2970 gs->Sort(&TGraph::CompareX);
2976 //printf("LegEntry %s [%s]%s\n", at[0], gm->GetName(), gm->GetTitle());
2977 legM->AddEntry(gm, gm->GetTitle(), "pl");
2979 PutTrendValue(Form("%s_%s", fgPerformanceName[kMCtrack], at[0]), gm->GetMean(2));
2980 PutTrendValue(Form("%s_%sRMS", fgPerformanceName[kMCtrack], at[0]), gm->GetRMS(2));
2983 if(!nPlots) return kFALSE;
2991 //____________________________________________________________________
2992 Bool_t AliTRDresolution::FitTrack(const Int_t np, AliTrackPoint *points, Float_t param[10])
2995 // Fit track with a staight line using the "np" clusters stored in the array "points".
2996 // The following particularities are stored in the clusters from points:
2997 // 1. pad tilt as cluster charge
2998 // 2. pad row cross or vertex constrain as fake cluster with cluster type 1
2999 // The parameters of the straight line fit are stored in the array "param" in the following order :
3000 // param[0] - x0 reference radial position
3001 // param[1] - y0 reference r-phi position @ x0
3002 // param[2] - z0 reference z position @ x0
3003 // param[3] - slope dy/dx
3004 // param[4] - slope dz/dx
3007 // Function should be used to refit tracks for B=0T
3011 if(AliLog::GetDebugLevel("PWG1", "AliTRDresolution")>1) printf("D-AliTRDresolution::FitTrack: Not enough clusters to fit a track [%d].", np);
3014 TLinearFitter yfitter(2, "pol1"), zfitter(2, "pol1");
3017 for(Int_t ip(0); ip<np; ip++) x0+=points[ip].GetX();
3020 Double_t x, y, z, dx, tilt(0.);
3021 for(Int_t ip(0); ip<np; ip++){
3022 x = points[ip].GetX(); z = points[ip].GetZ();
3024 zfitter.AddPoint(&dx, z, points[ip].GetClusterType()?1.e-3:1.);
3026 if(zfitter.Eval() != 0) return kFALSE;
3028 Double_t z0 = zfitter.GetParameter(0);
3029 Double_t dzdx = zfitter.GetParameter(1);
3030 for(Int_t ip(0); ip<np; ip++){
3031 if(points[ip].GetClusterType()) continue;
3032 x = points[ip].GetX();
3034 y = points[ip].GetY();
3035 z = points[ip].GetZ();
3036 tilt = points[ip].GetCharge();
3037 y -= tilt*(-dzdx*dx + z - z0);
3038 Float_t xyz[3] = {x, y, z}; points[ip].SetXYZ(xyz);
3039 yfitter.AddPoint(&dx, y, 1.);
3041 if(yfitter.Eval() != 0) return kFALSE;
3042 Double_t y0 = yfitter.GetParameter(0);
3043 Double_t dydx = yfitter.GetParameter(1);
3045 param[0] = x0; param[1] = y0; param[2] = z0; param[3] = dydx; param[4] = dzdx;
3046 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);
3050 //____________________________________________________________________
3051 Bool_t AliTRDresolution::UseTrack(const Int_t np, AliTrackPoint *points, Float_t param[10])
3054 // Global selection mechanism of tracksbased on cluster to fit residuals
3055 // The parameters are the same as used ni function FitTrack().
3057 const Float_t kS(0.6), kM(0.2);
3058 TH1S h("h1", "", 100, -5.*kS, 5.*kS);
3059 Float_t dy, dz, s, m;
3060 for(Int_t ip(0); ip<np; ip++){
3061 if(points[ip].GetClusterType()) continue;
3062 Float_t x0(points[ip].GetX())
3063 ,y0(param[1] + param[3] * (x0 - param[0]))
3064 ,z0(param[2] + param[4] * (x0 - param[0]));
3065 dy=points[ip].GetY() - y0; h.Fill(dy);
3066 dz=points[ip].GetZ() - z0;
3068 TF1 fg("fg", "gaus", -5.*kS, 5.*kS);
3069 fg.SetParameter(1, 0.);
3070 fg.SetParameter(2, 2.e-2);
3072 m=fg.GetParameter(1); s=fg.GetParameter(2);
3073 if(s>kS || TMath::Abs(m)>kM) return kFALSE;
3077 //________________________________________________________
3078 void AliTRDresolution::GetLandauMpvFwhm(TF1 * const f, Float_t &mpv, Float_t &xm, Float_t &xM)
3081 // Get the most probable value and the full width half mean
3082 // of a Landau distribution
3085 const Float_t dx = 1.;
3086 mpv = f->GetParameter(1);
3087 Float_t fx, max = f->Eval(mpv);
3090 while((fx = f->Eval(xm))>.5*max){
3099 while((fx = f->Eval(xM))>.5*max) xM += dx;
3103 //________________________________________________________
3104 void AliTRDresolution::SetSegmentationLevel(Int_t l)
3106 // Setting the segmentation level to "l"
3109 UShort_t const lNcomp[kNprojs] = {
3111 fgkNresYsegm[fSegmentLevel], 2, //2,
3112 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3113 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3114 2*fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3116 fgkNresYsegm[fSegmentLevel], 2, //2,
3117 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, //5,
3118 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3119 fgkNresYsegm[fSegmentLevel], 2, 2, 2, 1, 1, 1, 1, 11, 11, 11, //11
3120 6*fgkNresYsegm[fSegmentLevel], 6*2, 6*2, 6*2, 6, 6, 6, 6, 6*11, 6*11, 6*11 //11
3122 memcpy(fNcomp, lNcomp, kNprojs*sizeof(UShort_t));
3124 Char_t const *lAxTitle[kNprojs][4] = {
3126 {"Impv", "x [cm]", "I_{mpv}", "x/x_{0}"}
3127 ,{"dI/Impv", "x/x_{0}", "#delta I/I_{mpv}", "x[cm]"}
3128 // Clusters to Kalman
3129 ,{"Cluster2Track residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3130 ,{"Cluster2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3131 // TRD tracklet to Kalman fit
3132 ,{"Tracklet2Track Y residuals", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3133 ,{"Tracklet2Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3134 ,{"Tracklet2Track Z residuals", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3135 ,{"Tracklet2Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3136 ,{"Tracklet2Track Phi residuals", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3137 // TRDin 2 first TRD tracklet
3138 ,{"Tracklet2Track Y residuals @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3139 ,{"Tracklet2Track YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3140 ,{"Tracklet2Track Z residuals @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3141 ,{"Tracklet2Track Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3142 ,{"Tracklet2Track Phi residuals @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3143 // TRDout 2 first TRD tracklet
3144 ,{"Tracklet2Track Y residuals @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3145 ,{"Tracklet2Track YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3146 ,{"Tracklet2Track Z residuals @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3147 ,{"Tracklet2Track Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3148 ,{"Tracklet2Track Phi residuals @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3150 ,{"MC Cluster Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3151 ,{"MC Cluster YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3153 ,{"MC Tracklet Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3154 ,{"MC Tracklet YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3155 ,{"MC Tracklet Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3156 ,{"MC Tracklet Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3157 ,{"MC Tracklet Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3159 ,{"MC Y resolution @ TRDin", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3160 ,{"MC YZ pulls @ TRDin", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3161 ,{"MC Z resolution @ TRDin", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3162 ,{"MC Z pulls @ TRDin", "tg(#theta)", "z", "#sigma_{z}"}
3163 ,{"MC #Phi resolution @ TRDin", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3164 ,{"MC SNP pulls @ TRDin", "tg(#phi)", "SNP", "#sigma_{snp}"}
3165 ,{"MC #Theta resolution @ TRDin", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3166 ,{"MC TGL pulls @ TRDin", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3167 ,{"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}) [%]"}
3168 ,{"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}"}
3169 ,{"MC P resolution @ TRDin", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3171 ,{"MC Y resolution @ TRDout", "tg(#phi)", "y [#mum]", "#sigma_{y}[#mum]"}
3172 ,{"MC YZ pulls @ TRDout", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3173 ,{"MC Z resolution @ TRDout", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3174 ,{"MC Z pulls @ TRDout", "tg(#theta)", "z", "#sigma_{z}"}
3175 ,{"MC #Phi resolution @ TRDout", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3176 ,{"MC SNP pulls @ TRDout", "tg(#phi)", "SNP", "#sigma_{snp}"}
3177 ,{"MC #Theta resolution @ TRDout", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3178 ,{"MC TGL pulls @ TRDout", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3179 ,{"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}) [%]"}
3180 ,{"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}"}
3181 ,{"MC P resolution @ TRDout", "p^{MC} [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
3183 ,{"MC Track Y resolution", "tg(#phi)", "y [#mum]", "#sigma_{y} [#mum]"}
3184 ,{"MC Track YZ pulls", fgkResYsegmName[fSegmentLevel], "y / z", "#sigma_{y}"}
3185 ,{"MC Track Z resolution", "tg(#theta)", "z [#mum]", "#sigma_{z} [#mum]"}
3186 ,{"MC Track Z pulls", "tg(#theta)", "z", "#sigma_{z}"}
3187 ,{"MC Track #Phi resolution", "tg(#phi)", "#phi [mrad]", "#sigma_{#phi} [mrad]"}
3188 ,{"MC Track SNP pulls", "tg(#phi)", "SNP", "#sigma_{snp}"}
3189 ,{"MC Track #Theta resolution", "tg(#theta)", "#theta [mrad]", "#sigma_{#theta} [mrad]"}
3190 ,{"MC Track TGL pulls", "tg(#theta)", "TGL", "#sigma_{tgl}"}
3191 ,{"MC P_{t} resolution", "p_{t} [GeV/c]", "(p_{t}^{REC}-p_{t}^{MC})/p_{t}^{MC} [%]", "#sigma(#Deltap_{t}/p_{t}^{MC}) [%]"}
3192 ,{"MC 1/P_{t} pulls", "1/p_{t}^{MC} [c/GeV]", "1/p_{t}^{REC} - 1/p_{t}^{MC}", "#sigma_{1/p_{t}}"}
3193 ,{"MC P resolution", "p [GeV/c]", "(p^{REC}-p^{MC})/p^{MC} [%]", "#sigma(#Deltap/p^{MC}) [%]"}
3195 memcpy(fAxTitle, lAxTitle, 4*kNprojs*sizeof(Char_t*));