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 ////////////////////////////////////////////////////////////////////////////
56 #include <TObjArray.h>
65 #include <TGraphErrors.h>
66 #include <TGraphAsymmErrors.h>
70 #include "TTreeStream.h"
71 #include "TGeoManager.h"
73 #include "AliAnalysisManager.h"
74 #include "AliTrackReference.h"
75 #include "AliTrackPointArray.h"
76 #include "AliCDBManager.h"
79 #include "AliTRDcalibDB.h"
80 #include "AliTRDCommonParam.h"
81 #include "AliTRDSimParam.h"
82 #include "AliTRDgeometry.h"
83 #include "AliTRDpadPlane.h"
84 #include "AliTRDcluster.h"
85 #include "AliTRDseedV1.h"
86 #include "AliTRDtrackV1.h"
87 #include "AliTRDtrackerV1.h"
88 #include "AliTRDReconstructor.h"
89 #include "AliTRDrecoParam.h"
91 #include "info/AliTRDclusterInfo.h"
92 #include "info/AliTRDtrackInfo.h"
93 #include "AliTRDresolution.h"
95 ClassImp(AliTRDresolution)
96 UChar_t AliTRDresolution::fNElements[kNhistos] = {
100 Char_t* AliTRDresolution::fPerformanceName[kNhistos] = {
111 Char_t *AliTRDresolution::fAxTitle[46][4] = {
113 {"Impv", "x [cm]", "I_{mpv}", "x/x_{0}"}
114 ,{"dI/Impv", "x/x_{0}", "#delta I/I_{mpv}", "x[cm]"}
115 // Clusters to Kalman
116 ,{"Pos", "tg(#phi)", "#mu_{y}^{cl} [#mum]", "#sigma_{y}^{cl} [#mum]"}
117 ,{"Pulls", "tg(#phi)", "PULL: #mu_{y}^{cl}", "PULL: #sigma_{y}^{cl}"}
118 // TRD tracklet to Kalman fit
119 ,{"PosY", "tg(#phi)", "#mu_{y}^{trklt} [#mum]", "#sigma_{y}^{trklt} [#mum]"}
120 ,{"PullsY", "tg(#phi)", "PULL: #mu_{y}^{trklt}", "PULL: #sigma_{y}^{trklt}"}
121 ,{"PosZ", "tg(#theta)", "#mu_{z}^{trklt} [#mum]", "#sigma_{z}^{trklt} [#mum]"}
122 ,{"PullsZ", "tg(#theta)", "PULL: #mu_{z}^{trklt}", "PULL: #sigma_{z}^{trklt}"}
123 ,{"Phi", "tg(#phi)", "#mu_{#phi}^{trklt} [mrad]", "#sigma_{#phi}^{trklt} [mrad]"}
124 // TPC track 2 first TRD tracklet
125 ,{"PosY", "tg(#phi)", "#mu_{y}^{TPC trklt} [#mum]", "#sigma_{y}^{TPC trklt} [#mum]"}
126 ,{"PullsY", "tg(#phi)", "PULL: #mu_{y}^{TPC trklt}", "PULL: #sigma_{y}^{TPC trklt}"}
127 ,{"PosZ", "tg(#theta)", "#mu_{z}^{TPC trklt} [#mum]", "#sigma_{z}^{TPC trklt} [#mum]"}
128 ,{"PullsZ", "tg(#theta)", "PULL: #mu_{z}^{TPC trklt}", "PULL: #sigma_{z}^{TPC trklt}"}
129 ,{"Phi", "tg(#phi)", "#mu_{#phi}^{TPC trklt} [mrad]", "#sigma_{#phi}^{TPC trklt} [mrad]"}
131 ,{"Pos", "tg(#phi)", "MC: #mu_{y}^{cl} [#mum]", "MC: #sigma_{y}^{cl} [#mum]"}
132 ,{"Pulls", "tg(#phi)", "MC PULL: #mu_{y}^{cl}", "MC PULL: #sigma_{y}^{cl}"}
134 ,{"PosY", "tg(#phi)", "MC: #mu_{y}^{trklt} [#mum]", "MC: #sigma_{y}^{trklt} [#mum]"}
135 ,{"PullsY", "tg(#phi)", "MC PULL: #mu_{y}^{trklt}", "MC PULL: #sigma_{y}^{trklt}"}
136 ,{"PosZ", "tg(#theta)", "MC: #mu_{z}^{trklt} [#mum]", "MC: #sigma_{z}^{trklt} [#mum]"}
137 ,{"PullsZ", "tg(#theta)", "MC PULL: #mu_{z}^{trklt}", "MC PULL: #sigma_{z}^{trklt}"}
138 ,{"Phi", "tg(#phi)", "MC: #mu_{#phi}^{trklt} [mrad]", "MC: #sigma_{#phi}^{trklt} [mrad]"}
140 ,{"PosY", "tg(#phi)", "MC: #mu_{y}^{TPC} [#mum]", "MC: #sigma_{y}^{TPC} [#mum]"}
141 ,{"PullsY", "tg(#phi)", "MC PULL: #mu_{y}^{TPC}", "MC PULL: #sigma_{y}^{TPC}"}
142 ,{"PosZ", "tg(#theta)", "MC: #mu_{z}^{TPC} [#mum]", "MC: #sigma_{z}^{TPC} [#mum]"}
143 ,{"PullsZ", "tg(#theta)", "MC PULL: #mu_{z}^{TPC}", "MC PULL: #sigma_{z}^{TPC}"}
144 ,{"Phi", "tg(#phi)", "MC: #mu_{#phi}^{TPC} [mrad]", "MC: #sigma_{#phi}^{TPC} [mrad]"}
145 ,{"PullsSNP", "tg(#phi)", "MC PULL: #mu_{snp}^{TPC}", "MC PULL: #sigma_{snp}^{TPC}"}
146 ,{"Theta", "tg(#theta)", "MC: #mu_{#theta}^{TPC} [mrad]", "MC: #sigma_{#theta}^{TPC} [mrad]"}
147 ,{"PullsTGL", "tg(#theta)", "MC PULL: #mu_{tgl}^{TPC}", "MC PULL: #sigma_{tgl}^{TPC}"}
148 ,{"Pt", "p_{t}^{MC} [GeV/c]", "MC: #mu^{TPC}(#Deltap_{t}/p_{t}^{MC}) [%]", "MC: #sigma^{TPC}(#Deltap_{t}/p_{t}^{MC}) [%]"}
149 ,{"Pulls1Pt", "1/p_{t}^{MC} [c/GeV]", "MC PULL: #mu_{1/p_{t}}^{TPC}", "MC PULL: #sigma_{1/p_{t}}^{TPC}"}
150 ,{"P", "p^{MC} [GeV/c]", "MC: #mu^{TPC}(#Deltap/p^{MC}) [%]", "MC: #sigma^{TPC}(#Deltap/p^{MC}) [%]"}
151 ,{"PullsP", "p^{MC} [GeV/c]", "MC PULL: #mu^{TPC}(#Deltap/#sigma_{p})", "MC PULL: #sigma^{TPC}(#Deltap/#sigma_{p})"}
153 ,{"PosZ", "tg(#theta)", "MC: #mu_{z}^{TOF} [#mum]", "MC: #sigma_{z}^{TOF} [#mum]"}
154 ,{"PullsZ", "tg(#theta)", "MC PULL: #mu_{z}^{TOF}", "MC PULL: #sigma_{z}^{TOF}"}
156 ,{"PosY", "tg(#phi)", "MC: #mu_{y}^{Trk} [#mum]", "MC: #sigma_{y}^{Trk} [#mum]"}
157 ,{"PullsY", "tg(#phi)", "MC PULL: #mu_{y}^{Trk}", "MC PULL: #sigma_{y}^{Trk}"}
158 ,{"PosZ", "tg(#theta)", "MC: #mu_{z}^{Trk} [#mum]", "MC: #sigma_{z}^{Trk} [#mum]"}
159 ,{"PullsZ", "tg(#theta)", "MC PULL: #mu_{z}^{Trk}", "MC PULL: #sigma_{z}^{Trk}"}
160 ,{"Phi", "tg(#phi)", "MC: #mu_{#phi}^{Trk} [mrad]", "MC: #sigma_{#phi}^{Trk} [mrad]"}
161 ,{"PullsSNP", "tg(#phi)", "MC PULL: #mu_{snp}^{Trk}", "MC PULL: #sigma_{snp}^{Trk}"}
162 ,{"Theta", "tg(#theta)", "MC: #mu_{#theta}^{Trk} [mrad]", "MC: #sigma_{#theta}^{Trk} [mrad]"}
163 ,{"PullsTGL", "tg(#theta)", "MC PULL: #mu_{tgl}^{Trk}", "MC PULL: #sigma_{tgl}^{Trk}"}
164 ,{"Pt", "p_{t}^{MC} [GeV/c]", "MC: #mu^{Trk}(#Deltap_{t}/p_{t}^{MC}) [%]", "MC: #sigma^{Trk}(#Deltap_{t}/p_{t}^{MC}) [%]"}
165 ,{"Pulls1Pt", "1/p_{t}^{MC} [c/GeV]", "MC PULL: #mu_{1/p_{t}}^{Trk}", "MC PULL: #sigma_{1/p_{t}}^{Trk}"}
166 ,{"P", "p^{MC} [GeV/c]", "MC: #mu^{Trk}(#Deltap/p^{MC}) [%]", "MC: #sigma^{Trk}(#Deltap/p^{MC}) [%]"}
169 //________________________________________________________
170 AliTRDresolution::AliTRDresolution()
171 :AliTRDrecoTask("resolution", "Spatial and momentum TRD resolution checker")
183 fReconstructor = new AliTRDReconstructor();
184 fReconstructor->SetRecoParam(AliTRDrecoParam::GetLowFluxParam());
185 fGeo = new AliTRDgeometry();
189 DefineOutput(1, TObjArray::Class()); // cluster2track
190 DefineOutput(2, TObjArray::Class()); // tracklet2track
191 DefineOutput(3, TObjArray::Class()); // cluster2mc
192 DefineOutput(4, TObjArray::Class()); // tracklet2mc
195 //________________________________________________________
196 AliTRDresolution::~AliTRDresolution()
198 if(fGraphS){fGraphS->Delete(); delete fGraphS;}
199 if(fGraphM){fGraphM->Delete(); delete fGraphM;}
201 delete fReconstructor;
202 if(gGeoManager) delete gGeoManager;
203 if(fCl){fCl->Delete(); delete fCl;}
204 if(fTrklt){fTrklt->Delete(); delete fTrklt;}
205 if(fMCcl){fMCcl->Delete(); delete fMCcl;}
206 if(fMCtrklt){fMCtrklt->Delete(); delete fMCtrklt;}
210 //________________________________________________________
211 void AliTRDresolution::CreateOutputObjects()
213 // spatial resolution
214 OpenFile(0, "RECREATE");
216 fContainer = Histos();
218 fCl = new TObjArray();
219 fCl->SetOwner(kTRUE);
220 fTrklt = new TObjArray();
221 fTrklt->SetOwner(kTRUE);
222 fMCcl = new TObjArray();
223 fMCcl->SetOwner(kTRUE);
224 fMCtrklt = new TObjArray();
225 fMCtrklt->SetOwner(kTRUE);
228 //________________________________________________________
229 void AliTRDresolution::Exec(Option_t *opt)
236 AliTRDrecoTask::Exec(opt);
241 PostData(4, fMCtrklt);
244 //________________________________________________________
245 TH1* AliTRDresolution::PlotCharge(const AliTRDtrackV1 *track)
247 if(track) fTrack = track;
249 AliWarning("No Track defined.");
252 TObjArray *arr = 0x0;
253 if(!(arr = ((TObjArray*)fContainer->At(kCharge)))){
254 AliWarning("No output container defined.");
259 AliTRDseedV1 *fTracklet = 0x0;
260 AliTRDcluster *c = 0x0;
261 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
262 if(!(fTracklet = fTrack->GetTracklet(ily))) continue;
263 if(!fTracklet->IsOK()) continue;
264 Float_t x0 = fTracklet->GetX0();
266 for(Int_t itb=AliTRDseedV1::kNtb; itb--;){
267 if(!(c = fTracklet->GetClusters(itb))){
268 if(!(c = fTracklet->GetClusters(AliTRDseedV1::kNtb+itb))) continue;
270 dq = fTracklet->GetdQdl(itb, &dl);
271 dl /= 0.15; // dl/dl0, dl0 = 1.5 mm for nominal vd
272 (h = (TH3S*)arr->At(0))->Fill(dl, x0-c->GetX(), dq);
275 // if(!HasMCdata()) continue;
277 // Float_t pt0, y0, z0, dydx0, dzdx0;
278 // if(!fMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
285 //________________________________________________________
286 TH1* AliTRDresolution::PlotCluster(const AliTRDtrackV1 *track)
288 if(track) fTrack = track;
290 AliWarning("No Track defined.");
293 TObjArray *arr = 0x0;
294 if(!(arr = ((TObjArray*)fContainer->At(kCluster)))){
295 AliWarning("No output container defined.");
300 Float_t x0, y0, z0, dy, dydx, dzdx;
301 AliTRDseedV1 *fTracklet = 0x0;
302 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
303 if(!(fTracklet = fTrack->GetTracklet(ily))) continue;
304 if(!fTracklet->IsOK()) continue;
305 x0 = fTracklet->GetX0();
307 // retrive the track angle with the chamber
308 y0 = fTracklet->GetYref(0);
309 z0 = fTracklet->GetZref(0);
310 dydx = fTracklet->GetYref(1);
311 dzdx = fTracklet->GetZref(1);
312 fTracklet->GetCovRef(cov);
313 Float_t tilt = fTracklet->GetTilt();
314 AliTRDcluster *c = 0x0;
315 fTracklet->ResetClusterIter(kFALSE);
316 while((c = fTracklet->PrevCluster())){
317 Float_t xc = c->GetX();
318 Float_t yc = c->GetY();
319 Float_t zc = c->GetZ();
320 Float_t dx = x0 - xc;
321 Float_t yt = y0 - dx*dydx;
322 Float_t zt = z0 - dx*dzdx;
323 yc -= tilt*(zc-zt); // tilt correction
326 //Float_t sx2 = dydx*c->GetSX(c->GetLocalTimeBin()); sx2*=sx2;
327 Float_t sy2 = c->GetSigmaY2();
328 if(sy2<=0.) continue;
329 ((TH2I*)arr->At(0))->Fill(dydx, dy);
330 ((TH2I*)arr->At(1))->Fill(dydx, dy/TMath::Sqrt(cov[0] /*+ sx2*/ + sy2));
333 // Get z-position with respect to anode wire
334 //AliTRDSimParam *simParam = AliTRDSimParam::Instance();
335 Int_t istk = fGeo->GetStack(c->GetDetector());
336 AliTRDpadPlane *pp = fGeo->GetPadPlane(ily, istk);
337 Float_t row0 = pp->GetRow0();
338 Float_t d = row0 - zt + pp->GetAnodeWireOffset();
339 d -= ((Int_t)(2 * d)) / 2.0;
340 if (d > 0.25) d = 0.5 - d;
342 /* AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
344 clInfo->SetCluster(c);
345 clInfo->SetGlobalPosition(yt, zt, dydx, dzdx);
346 clInfo->SetResolution(dy);
347 clInfo->SetAnisochronity(d);
348 clInfo->SetDriftLength(dx);
349 (*fDebugStream) << "ClusterResiduals"
350 <<"clInfo.=" << clInfo
355 return (TH2I*)arr->At(0);
359 //________________________________________________________
360 TH1* AliTRDresolution::PlotTracklet(const AliTRDtrackV1 *track)
362 // Plot normalized residuals for tracklets to track.
364 // We start from the result that if X=N(|m|, |Cov|)
366 // (Cov^{-1})^{1/2}X = N((Cov^{-1})^{1/2}*|m|, |1|)
368 // in our case X=(y_trklt - y_trk z_trklt - z_trk) and |Cov| = |Cov_trklt| + |Cov_trk| at the radial
369 // reference position.
370 if(track) fTrack = track;
372 AliWarning("No Track defined.");
375 TObjArray *arr = 0x0;
376 if(!(arr = (TObjArray*)fContainer->At(kTrackTRD ))){
377 AliWarning("No output container defined.");
381 Double_t cov[3], covR[7]/*, sqr[3], inv[3]*/;
382 Float_t x, dx, dy, dz;
383 AliTRDseedV1 *fTracklet = 0x0;
384 for(Int_t il=AliTRDgeometry::kNlayer; il--;){
385 if(!(fTracklet = fTrack->GetTracklet(il))) continue;
386 if(!fTracklet->IsOK()) continue;
387 x = fTracklet->GetX();
388 dx = fTracklet->GetX0() - x;
389 // compute dy^2 and dz^2
390 dy = fTracklet->GetYref(0)-dx*fTracklet->GetYref(1) - fTracklet->GetY();
391 dz = fTracklet->GetZref(0)-dx*fTracklet->GetZref(1) - fTracklet->GetZ();
392 // compute covariance matrix
393 fTracklet->GetCovAt(x, cov);
394 fTracklet->GetCovRef(covR);
395 cov[0] += covR[0]; cov[1] += covR[1]; cov[2] += covR[2];
396 /* // Correct PULL calculation by considering off
397 // diagonal elements in the covariance matrix
398 // compute square root matrix
399 if(AliTRDseedV1::GetCovInv(cov, inv)==0.) continue;
400 if(AliTRDseedV1::GetCovSqrt(inv, sqr)<0.) continue;
401 Double_t y = sqr[0]*dy+sqr[1]*dz;
402 Double_t z = sqr[1]*dy+sqr[2]*dz;
403 ((TH3*)h)->Fill(y, z, fTracklet->GetYref(1));*/
405 ((TH2I*)arr->At(0))->Fill(fTracklet->GetYref(1), dy);
406 ((TH2I*)arr->At(1))->Fill(fTracklet->GetYref(1), dy/TMath::Sqrt(cov[0]));
407 ((TH2I*)arr->At(4))->Fill(fTracklet->GetYref(1), TMath::ATan((fTracklet->GetYref(1)-fTracklet->GetYfit(1))/(1-fTracklet->GetYref(1)*fTracklet->GetYfit(1))));
408 if(!fTracklet->IsRowCross()) continue;
409 ((TH2I*)arr->At(2))->Fill(fTracklet->GetZref(1), dz);
410 ((TH2I*)arr->At(3))->Fill(fTracklet->GetZref(1), dz/TMath::Sqrt(cov[2]));
414 return (TH2I*)arr->At(0);
418 //________________________________________________________
419 TH1* AliTRDresolution::PlotTrackTPC(const AliTRDtrackV1 *track)
421 // Store resolution/pulls of Kalman before updating with the TRD information
422 // at the radial position of the first tracklet. The following points are used
424 // - the (y,z,snp) of the first TRD tracklet
425 // - the (y, z, snp, tgl, pt) of the MC track reference
427 // Additionally the momentum resolution/pulls are calculated for usage in the
430 if(track) fTrack = track;
432 AliWarning("No Track defined.");
435 AliExternalTrackParam *tin = 0x0;
436 if(!(tin = fTrack->GetTrackLow())){
437 AliWarning("Track did not entered TRD fiducial volume.");
442 Double_t x = tin->GetX();
443 AliTRDseedV1 *tracklet = 0x0;
444 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
445 if(!(tracklet = fTrack->GetTracklet(ily))) continue;
448 if(!tracklet || TMath::Abs(x-tracklet->GetX())>1.e-3){
449 AliWarning("Tracklet did not match TRD entrance.");
452 const Int_t kNPAR(5);
453 Double_t parR[kNPAR]; memcpy(parR, tin->GetParameter(), kNPAR*sizeof(Double_t));
454 Double_t covR[3*kNPAR]; memcpy(covR, tin->GetCovariance(), 3*kNPAR*sizeof(Double_t));
455 Double_t cov[3]; tracklet->GetCovAt(x, cov);
457 // define sum covariances
458 TMatrixDSym COV(kNPAR); TVectorD PAR(kNPAR);
459 Double_t *pc = &covR[0], *pp = &parR[0];
460 for(Int_t ir=0; ir<kNPAR; ir++, pp++){
462 for(Int_t ic = 0; ic<=ir; ic++,pc++){
463 COV(ir,ic) = (*pc); COV(ic,ir) = (*pc);
466 PAR[4] = TMath::Abs(PAR[4]); // remove sign of pt !!
467 //COV.Print(); PAR.Print();
469 //TODO Double_t dydx = TMath::Sqrt(1.-parR[2]*parR[2])/parR[2];
470 Double_t dy = parR[0] - tracklet->GetY();
471 TObjArray *arr = (TObjArray*)fContainer->At(kTrackTPC);
472 ((TH2I*)arr->At(0))->Fill(tracklet->GetYref(1), dy);
473 ((TH2I*)arr->At(1))->Fill(tracklet->GetYref(1), dy/TMath::Sqrt(COV(0,0)+cov[0]));
474 if(tracklet->IsRowCross()){
475 Double_t dz = parR[1] - tracklet->GetZ();
476 ((TH2I*)arr->At(2))->Fill(tracklet->GetZref(1), dz);
477 ((TH2I*)arr->At(3))->Fill(tracklet->GetZref(1), dz/TMath::Sqrt(COV(1,1)+cov[2]));
479 Double_t dphi = TMath::ASin(PAR[2])-TMath::ATan(tracklet->GetYfit(1)); ((TH2I*)arr->At(4))->Fill(tracklet->GetYref(1), dphi);
482 // register reference histo for mini-task
483 h = (TH2I*)arr->At(0);
486 (*fDebugStream) << "trackIn"
492 Double_t y = tracklet->GetY();
493 Double_t z = tracklet->GetZ();
494 (*fDebugStream) << "trackletIn"
504 if(!HasMCdata()) return h;
506 Float_t dx, pt0, x0=tracklet->GetX0(), y0, z0, dydx0, dzdx0;
507 if(!fMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) return h;
508 // translate to reference radial position
509 dx = x0 - x; y0 -= dx*dydx0; z0 -= dx*dzdx0;
510 Float_t norm = 1./TMath::Sqrt(1.+dydx0*dydx0); // 1/sqrt(1+tg^2(phi))
512 TVectorD PARMC(kNPAR);
513 PARMC[0]=y0; PARMC[1]=z0;
514 PARMC[2]=dydx0*norm; PARMC[3]=dzdx0*norm;
517 // TMatrixDSymEigen eigen(COV);
518 // TVectorD evals = eigen.GetEigenValues();
519 // TMatrixDSym evalsm(kNPAR);
520 // for(Int_t ir=0; ir<kNPAR; ir++) for(Int_t ic=0; ic<kNPAR; ic++) evalsm(ir,ic) = (ir==ic ? evals(ir): 0.);
521 // TMatrixD evecs = eigen.GetEigenVectors();
522 // TMatrixD sqrcov(evecs, TMatrixD::kMult, TMatrixD(evalsm, TMatrixD::kMult, evecs.T()));
525 arr = (TObjArray*)fContainer->At(kMCtrackTPC);
526 // y resolution/pulls
527 ((TH2I*)arr->At(0))->Fill(dydx0, PARMC[0]-PAR[0]);
528 ((TH2I*)arr->At(1))->Fill(dydx0, (PARMC[0]-PAR[0])/TMath::Sqrt(COV(0,0)));
529 // z resolution/pulls
530 ((TH2I*)arr->At(2))->Fill(dzdx0, PARMC[1]-PAR[1]);
531 ((TH2I*)arr->At(3))->Fill(dzdx0, (PARMC[1]-PAR[1])/TMath::Sqrt(COV(1,1)));
532 // phi resolution/snp pulls
533 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ASin(PARMC[2])-TMath::ASin(PAR[2]));
534 ((TH2I*)arr->At(5))->Fill(dydx0, (PARMC[2]-PAR[2])/TMath::Sqrt(COV(2,2)));
535 // theta resolution/tgl pulls
536 ((TH2I*)arr->At(6))->Fill(dzdx0, TMath::ATan((PARMC[3]-PAR[3])/(1-PARMC[3]*PAR[3])));
537 ((TH2I*)arr->At(7))->Fill(dzdx0, (PARMC[3]-PAR[3])/TMath::Sqrt(COV(3,3)));
538 // pt resolution\\1/pt pulls\\p resolution/pull
539 for(Int_t is=AliPID::kSPECIES; is--;){
540 if(TMath::Abs(fMC->GetPDG())!=AliPID::ParticleCode(is)) continue;
541 ((TH3S*)arr->At(8))->Fill(pt0, PARMC[4]/PAR[4]-1., is);
542 ((TH3S*)arr->At(9))->Fill(PARMC[4], (PARMC[4]-PAR[4])/TMath::Sqrt(COV(4,4)), is);
544 Double_t p0 = TMath::Sqrt(1.+ PARMC[3]*PARMC[3])*pt0, p;
546 p = tracklet->GetMomentum(&sp);
547 ((TH3S*)arr->At(10))->Fill(p0, p/p0-1., is);
548 ((TH3S*)arr->At(11))->Fill(p0, (p0-p)/sp, is);
554 (*fDebugStream) << "trackInMC"
561 //________________________________________________________
562 TH1* AliTRDresolution::PlotMC(const AliTRDtrackV1 *track)
565 AliWarning("No MC defined. Results will not be available.");
568 if(track) fTrack = track;
570 AliWarning("No Track defined.");
573 TObjArray *arr = 0x0;
576 Int_t pdg = fMC->GetPDG(), det=-1;
577 Int_t label = fMC->GetLabel();
578 Double_t xAnode, x, y, z, pt, dydx, dzdx, dzdl;
579 Float_t pt0, x0, y0, z0, dx, dy, dz, dydx0, dzdx0;
580 Double_t covR[7]/*, cov[3]*/;
583 Double_t DX[12], DY[12], DZ[12], DPt[12], COV[12][15];
584 fMC->PropagateKalman(DX, DY, DZ, DPt, COV);
585 (*fDebugStream) << "MCkalman"
602 AliTRDReconstructor rec;
603 AliTRDseedV1 *fTracklet = 0x0;
604 for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
605 if(!(fTracklet = fTrack->GetTracklet(ily)))/* ||
606 !fTracklet->IsOK())*/ continue;
608 det = fTracklet->GetDetector();
609 x0 = fTracklet->GetX0();
610 //radial shift with respect to the MC reference (radial position of the pad plane)
611 x= fTracklet->GetX();
612 if(!fMC->GetDirections(x0, y0, z0, dydx0, dzdx0, pt0, s)) continue;
613 xAnode = fTracklet->GetX0();
615 // MC track position at reference radial position
618 (*fDebugStream) << "MC"
629 Float_t ymc = y0 - dx*dydx0;
630 Float_t zmc = z0 - dx*dzdx0;
631 //p = pt0*TMath::Sqrt(1.+dzdx0*dzdx0); // pt -> p
633 // Kalman position at reference radial position
635 dydx = fTracklet->GetYref(1);
636 dzdx = fTracklet->GetZref(1);
637 dzdl = fTracklet->GetTgl();
638 y = fTracklet->GetYref(0) - dx*dydx;
640 z = fTracklet->GetZref(0) - dx*dzdx;
642 pt = TMath::Abs(fTracklet->GetPt());
643 fTracklet->GetCovRef(covR);
645 arr = (TObjArray*)fContainer->At(kMCtrackTRD);
646 // y resolution/pulls
647 ((TH2I*)arr->At(0))->Fill(dydx0, dy);
648 ((TH2I*)arr->At(1))->Fill(dydx0, dy/TMath::Sqrt(covR[0]));
649 // z resolution/pulls
650 ((TH2I*)arr->At(2))->Fill(dzdx0, dz);
651 ((TH2I*)arr->At(3))->Fill(dzdx0, dz/TMath::Sqrt(covR[2]));
652 // phi resolution/ snp pulls
653 Double_t dtgp = (dydx - dydx0)/(1.- dydx*dydx0);
654 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dtgp));
655 Double_t dsnp = dydx/TMath::Sqrt(1.+dydx*dydx) - dydx0/TMath::Sqrt(1.+dydx0*dydx0);
656 ((TH2I*)arr->At(5))->Fill(dydx0, dsnp/TMath::Sqrt(covR[3]));
657 // theta resolution/ tgl pulls
658 Double_t dzdl0 = dzdx0/TMath::Sqrt(1.+dydx0*dydx0),
659 dtgl = (dzdl - dzdl0)/(1.- dzdl*dzdl0);
660 ((TH2I*)arr->At(6))->Fill(dzdl0,
662 ((TH2I*)arr->At(7))->Fill(dzdl0, (dzdl - dzdl0)/TMath::Sqrt(covR[4]));
663 // pt resolution \\ 1/pt pulls \\ p resolution for PID
664 for(Int_t is=AliPID::kSPECIES; is--;){
665 if(TMath::Abs(pdg)!=AliPID::ParticleCode(is)) continue;
666 ((TH3S*)((TObjArray*)arr->At(8))->At(ily))->Fill(pt0, pt/pt0-1., is);
667 ((TH3S*)((TObjArray*)arr->At(9))->At(ily))->Fill(1./pt0, (1./pt-1./pt0)/TMath::Sqrt(covR[6]), is);
668 Double_t p0 = TMath::Sqrt(1.+ dzdl0*dzdl0)*pt0,
669 p = TMath::Sqrt(1.+ dzdl*dzdl)*pt;
670 ((TH3S*)((TObjArray*)arr->At(10))->At(ily))->Fill(p0, p/p0-1., is);
674 // Fill Debug stream for Kalman track
676 (*fDebugStream) << "MCtrack"
688 // recalculate tracklet based on the MC info
689 AliTRDseedV1 tt(*fTracklet);
690 tt.SetZref(0, z0 - (x0-xAnode)*dzdx0);
691 tt.SetZref(1, dzdx0);
692 tt.SetReconstructor(&rec);
693 tt.Fit(kTRUE, kTRUE);
694 x= tt.GetX();y= tt.GetY();z= tt.GetZ();
695 dydx = tt.GetYfit(1);
699 Bool_t rc = tt.IsRowCross();
701 // add tracklet residuals for y and dydx
702 arr = (TObjArray*)fContainer->At(kMCtracklet);
706 Float_t dphi = (dydx - dydx0);
707 dphi /= (1.- dydx*dydx0);
709 ((TH2I*)arr->At(0))->Fill(dydx0, dy);
710 if(tt.GetS2Y()>0.) ((TH2I*)arr->At(1))->Fill(dydx0, dy/TMath::Sqrt(tt.GetS2Y()));
711 ((TH2I*)arr->At(4))->Fill(dydx0, TMath::ATan(dphi));
713 // add tracklet residuals for z
715 ((TH2I*)arr->At(2))->Fill(dzdl0, dz);
716 if(tt.GetS2Z()>0.) ((TH2I*)arr->At(3))->Fill(dzdl0, dz/TMath::Sqrt(tt.GetS2Z()));
719 // Fill Debug stream for tracklet
721 Float_t s2y = tt.GetS2Y();
722 Float_t s2z = tt.GetS2Z();
723 (*fDebugStream) << "MCtracklet"
734 Int_t istk = AliTRDgeometry::GetStack(det);
735 AliTRDpadPlane *pp = fGeo->GetPadPlane(ily, istk);
736 Float_t zr0 = pp->GetRow0() + pp->GetAnodeWireOffset();
737 Float_t tilt = fTracklet->GetTilt();
738 //Double_t exb = AliTRDCommonParam::Instance()->GetOmegaTau(1.5);
740 arr = (TObjArray*)fContainer->At(kMCcluster);
741 AliTRDcluster *c = 0x0;
742 fTracklet->ResetClusterIter(kFALSE);
743 while((c = fTracklet->PrevCluster())){
744 Float_t q = TMath::Abs(c->GetQ());
745 x = c->GetX(); y = c->GetY();z = c->GetZ();
749 dy = ymc - (y - tilt*(z-zmc));
752 ((TH2I*)arr->At(0))->Fill(dydx0, dy);
753 ((TH2I*)arr->At(1))->Fill(dydx0, dy/TMath::Sqrt(c->GetSigmaY2()));
756 // Fill calibration container
757 Float_t d = zr0 - zmc;
758 d -= ((Int_t)(2 * d)) / 2.0;
759 if (d > 0.25) d = 0.5 - d;
760 AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
762 clInfo->SetCluster(c);
763 clInfo->SetMC(pdg, label);
764 clInfo->SetGlobalPosition(ymc, zmc, dydx0, dzdx0);
765 clInfo->SetResolution(dy);
766 clInfo->SetAnisochronity(d);
767 clInfo->SetDriftLength(((c->GetPadTime()+0.5)*.1)*1.5);
768 //dx-.5*AliTRDgeometry::CamHght());
769 clInfo->SetTilt(tilt);
774 (*fDebugStream) << "MCcluster"
775 <<"clInfo.=" << clInfo
784 //________________________________________________________
785 Bool_t AliTRDresolution::GetRefFigure(Int_t ifig)
787 Float_t xy[4] = {0., 0., 0., 0.};
789 AliWarning("Please provide a canvas to draw results.");
792 TList *l = 0x0; TVirtualPad *pad=0x0;
795 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
796 ((TVirtualPad*)l->At(0))->cd();
797 ((TGraphAsymmErrors*)((TObjArray*)fGraphM->At(kCharge))->At(0))->Draw("apl");
798 ((TVirtualPad*)l->At(1))->cd();
799 ((TGraphErrors*)((TObjArray*)fGraphS->At(kCharge))->At(0))->Draw("apl");
802 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
803 xy[0] = -.3; xy[1] = -200.; xy[2] = .3; xy[3] = 1000.;
804 ((TVirtualPad*)l->At(0))->cd();
805 if(!GetGraphPlot(&xy[0], kCluster, 0)) break;
806 xy[0] = -.3; xy[1] = -0.5; xy[2] = .3; xy[3] = 2.5;
807 ((TVirtualPad*)l->At(1))->cd();
808 if(!GetGraphPlot(&xy[0], kCluster, 1)) break;
811 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
812 xy[0] = -.3; xy[1] = -500.; xy[2] = .3; xy[3] = 1500.;
813 ((TVirtualPad*)l->At(0))->cd();
814 if(!GetGraphPlot(&xy[0], kTrackTRD , 0)) break;
815 xy[0] = -.3; xy[1] = -0.5; xy[2] = .3; xy[3] = 2.5;
816 ((TVirtualPad*)l->At(1))->cd();
817 if(!GetGraphPlot(&xy[0], kTrackTRD , 1)) break;
819 case 3: // kTrackTRD z
820 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
821 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
822 ((TVirtualPad*)l->At(0))->cd();
823 if(!GetGraphPlot(&xy[0], kTrackTRD , 2)) break;
824 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
825 ((TVirtualPad*)l->At(1))->cd();
826 if(!GetGraphPlot(&xy[0], kTrackTRD , 3)) break;
828 case 4: // kTrackTRD phi
829 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
830 if(GetGraphPlot(&xy[0], kTrackTRD , 4)) return kTRUE;
832 case 5: // kTrackTPC y
833 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
834 xy[0] = -.3; xy[1] = -500.; xy[2] = .3; xy[3] = 1500.;
835 pad = ((TVirtualPad*)l->At(0)); pad->cd();
836 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
837 if(!GetGraphPlot(&xy[0], kTrackTPC, 0)) break;
838 xy[0] = -.3; xy[1] = -0.5; xy[2] = .3; xy[3] = 2.5;
839 pad=((TVirtualPad*)l->At(1)); pad->cd();
840 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
841 if(!GetGraphPlot(&xy[0], kTrackTPC, 1)) break;
843 case 6: // kTrackTPC z
844 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
845 xy[0] = -1.; xy[1] = -1000.; xy[2] = 1.; xy[3] = 4000.;
846 pad = ((TVirtualPad*)l->At(0)); pad->cd();
847 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
848 if(!GetGraphPlot(&xy[0], kTrackTPC, 2)) break;
849 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
850 pad = ((TVirtualPad*)l->At(1)); pad->cd();
851 pad->SetMargin(0.1, 0.1, 0.1, 0.01);
852 if(!GetGraphPlot(&xy[0], kTrackTPC, 3)) break;
854 case 7: // kTrackTPC phi
855 xy[0] = -.3; xy[1] = -5.; xy[2] = .3; xy[3] = 50.;
856 if(GetGraphPlot(&xy[0], kTrackTPC, 4)) return kTRUE;
858 case 8: // kMCcluster
859 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
860 xy[0]=-.3; xy[1]=-50.; xy[2]=.3; xy[3]=650.;
861 ((TVirtualPad*)l->At(0))->cd();
862 if(!GetGraphPlot(&xy[0], kMCcluster, 0)) break;
863 xy[0] = -.3; xy[1] = -0.5; xy[2] = .3; xy[3] = 2.5;
864 ((TVirtualPad*)l->At(1))->cd();
865 if(!GetGraphPlot(&xy[0], kMCcluster, 1)) break;
867 case 9: //kMCtracklet [y]
868 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
869 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =250.;
870 ((TVirtualPad*)l->At(0))->cd();
871 if(!GetGraphPlot(&xy[0], kMCtracklet, 0)) break;
872 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
873 ((TVirtualPad*)l->At(1))->cd();
874 if(!GetGraphPlot(&xy[0], kMCtracklet, 1)) break;
876 case 10: //kMCtracklet [z]
877 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
878 xy[0]=-1.; xy[1]=-100.; xy[2]=1.; xy[3] =2500.;
879 ((TVirtualPad*)l->At(0))->cd();
880 if(!GetGraphPlot(&xy[0], kMCtracklet, 2)) break;
881 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
882 ((TVirtualPad*)l->At(1))->cd();
883 if(!GetGraphPlot(&xy[0], kMCtracklet, 3)) break;
885 case 11: //kMCtracklet [phi]
886 xy[0]=-.3; xy[1]=-3.; xy[2]=.3; xy[3] =25.;
887 if(!GetGraphPlot(&xy[0], kMCtracklet, 4)) break;
889 case 12: //kMCtrackTRD [y]
890 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
891 xy[0]=-.2; xy[1]=-50.; xy[2]=.2; xy[3] =200.;
892 ((TVirtualPad*)l->At(0))->cd();
893 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 0)) break;
894 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
895 ((TVirtualPad*)l->At(1))->cd();
896 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 1)) break;
898 case 13: //kMCtrackTRD [z]
899 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
900 xy[0]=-1.; xy[1]=-700.; xy[2]=1.; xy[3] =1500.;
901 ((TVirtualPad*)l->At(0))->cd();
902 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 2)) break;
903 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
904 ((TVirtualPad*)l->At(1))->cd();
905 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 3)) break;
907 case 14: //kMCtrackTRD [phi/snp]
908 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
909 xy[0]=-.2; xy[1]=-0.2; xy[2]=.2; xy[3] =2.;
910 ((TVirtualPad*)l->At(0))->cd();
911 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 4)) break;
912 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
913 ((TVirtualPad*)l->At(1))->cd();
914 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 5)) break;
916 case 15: //kMCtrackTRD [theta/tgl]
917 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
918 xy[0]=-1.; xy[1]=-0.5; xy[2]=1.; xy[3] =5.;
919 ((TVirtualPad*)l->At(0))->cd();
920 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 6)) break;
921 xy[0] = -.2; xy[1] = -0.5; xy[2] = .2; xy[3] = 2.5;
922 ((TVirtualPad*)l->At(1))->cd();
923 if(!GetGraphPlot(&xy[0], kMCtrackTRD, 7)) break;
925 case 16: //kMCtrackTRD [pt]
926 xy[0] = 0.; xy[1] = -5.; xy[2] = 12.; xy[3] = 7.;
927 gPad->Divide(2, 3, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
928 for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
929 pad = (TVirtualPad*)l->At(il); pad->cd();
930 pad->SetMargin(0.07, 0.07, 0.1, 0.);
931 if(!GetGraphTrack(&xy[0], 8, il)) break;
934 case 17: //kMCtrackTRD [1/pt] pulls
935 xy[0] = 0.; xy[1] = -1.5; xy[2] = 2.; xy[3] = 2.;
936 gPad->Divide(2, 3, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
937 for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
938 pad = (TVirtualPad*)l->At(il); pad->cd();
939 pad->SetMargin(0.07, 0.07, 0.1, 0.);
940 if(!GetGraphTrack(&xy[0], 9, il)) break;
943 case 18: //kMCtrackTRD [p]
944 xy[0] = 0.; xy[1] = -7.5; xy[2] = 12.; xy[3] = 10.5;
945 gPad->Divide(2, 3, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
946 for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
947 pad = (TVirtualPad*)l->At(il); pad->cd();
948 pad->SetMargin(0.07, 0.07, 0.1, 0.);
949 if(!GetGraphTrack(&xy[0], 10, il)) break;
952 case 19: // kMCtrackTPC [y]
953 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
954 xy[0]=-.25; xy[1]=-50.; xy[2]=.25; xy[3] =800.;
955 ((TVirtualPad*)l->At(0))->cd();
956 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 0)) break;
957 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 2.5;
958 ((TVirtualPad*)l->At(1))->cd();
959 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 1)) break;
961 case 20: // kMCtrackTPC [z]
962 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
963 xy[0]=-1.; xy[1]=-500.; xy[2]=1.; xy[3] =800.;
964 ((TVirtualPad*)l->At(0))->cd();
965 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 2)) break;
966 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 2.5;
967 ((TVirtualPad*)l->At(1))->cd();
968 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 3)) break;
970 case 21: // kMCtrackTPC [phi|snp]
971 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
972 xy[0]=-.25; xy[1]=-0.5; xy[2]=.25; xy[3] =2.5;
973 ((TVirtualPad*)l->At(0))->cd();
974 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 4)) break;
975 xy[0] = -.25; xy[1] = -0.5; xy[2] = .25; xy[3] = 1.5;
976 ((TVirtualPad*)l->At(1))->cd();
977 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 5)) break;
979 case 22: // kMCtrackTPC [theta|tgl]
980 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
981 xy[0]=-1.; xy[1]=-1.; xy[2]=1.; xy[3] =4.;
982 ((TVirtualPad*)l->At(0))->cd();
983 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 6)) break;
984 xy[0] = -1.; xy[1] = -0.5; xy[2] = 1.; xy[3] = 1.5;
985 ((TVirtualPad*)l->At(1))->cd();
986 if(!GetGraphPlot(&xy[0], kMCtrackTPC, 7)) break;
988 case 23: // kMCtrackTPC [pt]
989 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
990 xy[0] = 0.; xy[1] = -.8; xy[2] = 12.; xy[3] = 2.3;
991 ((TVirtualPad*)l->At(0))->cd();
992 if(!GetGraphTrackTPC(xy, 8)) break;
993 xy[0]=0.; xy[1]=-0.5; xy[2]=2.; xy[3] =2.5;
994 ((TVirtualPad*)l->At(1))->cd();
995 if(!GetGraphTrackTPC(xy, 9)) break;
997 case 24: // kMCtrackTPC [p]
998 gPad->Divide(2, 1, 1.e-5, 1.e-5); l=gPad->GetListOfPrimitives();
999 xy[0] = 0.; xy[1] = -.8; xy[2] = 12.; xy[3] = 2.3;
1000 pad = ((TVirtualPad*)l->At(0));pad->cd();
1001 pad->SetMargin(0.12, 0.12, 0.1, 0.04);
1002 if(!GetGraphTrackTPC(xy, 10)) break;
1003 xy[0]=0.; xy[1]=-1.5; xy[2]=12.; xy[3] =2.5;
1004 pad = ((TVirtualPad*)l->At(1)); pad->cd();
1005 pad->SetMargin(0.12, 0.12, 0.1, 0.04);
1006 if(!GetGraphTrackTPC(xy, 11)) break;
1008 case 25: // kMCtrackTOF [z]
1011 AliWarning(Form("Reference plot [%d] missing result", ifig));
1016 //________________________________________________________
1017 Bool_t AliTRDresolution::PostProcess()
1019 //fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));
1021 AliError("ERROR: list not available");
1024 TGraph *gm= 0x0, *gs= 0x0;
1025 if(!fGraphS && !fGraphM){
1026 TObjArray *aM(0x0), *aS(0x0), *a(0x0);
1027 Int_t n = fContainer->GetEntriesFast();
1028 fGraphS = new TObjArray(n); fGraphS->SetOwner();
1029 fGraphM = new TObjArray(n); fGraphM->SetOwner();
1030 for(Int_t ig=0; ig<n; ig++){
1031 fGraphM->AddAt(aM = new TObjArray(fNElements[ig]), ig);
1032 fGraphS->AddAt(aS = new TObjArray(fNElements[ig]), ig);
1034 for(Int_t ic=0; ic<fNElements[ig]; ic++){
1035 if(ig==kMCtrackTPC&&(ic>=8&&ic<=12)){ // TPC momentum plot
1036 aS->AddAt(a = new TObjArray(AliPID::kSPECIES), ic);
1037 for(Int_t is=AliPID::kSPECIES; is--;){
1038 a->AddAt(gs = new TGraphErrors(), is);
1039 gs->SetMarkerStyle(23);
1040 gs->SetMarkerColor(is ? kRed : kMagenta);
1041 gs->SetLineStyle(is);
1042 gs->SetLineColor(is ? kRed : kMagenta);
1043 gs->SetLineWidth(is ? 1 : 3);
1044 gs->SetNameTitle(Form("s_%d%02d%d", ig, ic, is), "");
1046 aM->AddAt(a = new TObjArray(AliPID::kSPECIES), ic);
1047 for(Int_t is=AliPID::kSPECIES; is--;){
1048 a->AddAt(gm = new TGraphErrors(), is);
1049 gm->SetLineColor(is ? kBlack : kBlue);
1050 gm->SetLineStyle(is);
1051 gm->SetMarkerStyle(7);
1052 gm->SetMarkerColor(is ? kBlack : kBlue);
1053 gm->SetLineWidth(is ? 1 : 3);
1054 gm->SetNameTitle(Form("m_%d%02d%d", ig, ic, is), "");
1057 } else if(ig==kMCtrackTRD&&(ic==8||ic==9||ic==10)){ // TRD momentum plot
1058 TObjArray *aaS, *aaM;
1059 aS->AddAt(aaS = new TObjArray(AliTRDgeometry::kNlayer), ic);
1060 aM->AddAt(aaM = new TObjArray(AliTRDgeometry::kNlayer), ic);
1061 for(Int_t il=AliTRDgeometry::kNlayer; il--;){
1062 aaS->AddAt(a = new TObjArray(AliPID::kSPECIES), il);
1063 for(Int_t is=AliPID::kSPECIES; is--;){
1064 a->AddAt(gs = new TGraphErrors(), is);
1065 gs->SetMarkerStyle(23);
1066 gs->SetMarkerColor(is ? kRed : kMagenta);
1067 gs->SetLineStyle(is);
1068 gs->SetLineColor(is ? kRed : kMagenta);
1069 gs->SetLineWidth(is ? 1 : 3);
1070 gs->SetNameTitle(Form("s_%d%02d%d%d", ig, ic, is, il), "");
1072 aaM->AddAt(a = new TObjArray(AliPID::kSPECIES), il);
1073 for(Int_t is=AliPID::kSPECIES; is--;){
1074 a->AddAt(gm = new TGraphErrors(), is);
1075 gm->SetMarkerStyle(7);
1076 gm->SetMarkerColor(is ? kBlack : kBlue);
1077 gm->SetLineStyle(is);
1078 gm->SetLineColor(is ? kBlack : kBlue);
1079 gm->SetLineWidth(is ? 1 : 3);
1080 gm->SetNameTitle(Form("m_%d%02d%d%d", ig, ic, is, il), "");
1086 aS->AddAt(gs = new TGraphErrors(), ic);
1087 gs->SetMarkerStyle(23);
1088 gs->SetMarkerColor(kRed);
1089 gs->SetLineColor(kRed);
1090 gs->SetNameTitle(Form("s_%d%02d", ig, ic), "");
1092 aM->AddAt(gm = ig ? (TGraph*)new TGraphErrors() : (TGraph*)new TGraphAsymmErrors(), ic);
1093 gm->SetLineColor(kBlack);
1094 gm->SetMarkerStyle(7);
1095 gm->SetMarkerColor(kBlack);
1096 gm->SetNameTitle(Form("m_%d%02d", ig, ic), "");
1101 /* printf("\n\n\n"); fGraphS->ls();
1102 printf("\n\n\n"); fGraphM->ls();*/
1107 TF1 fg("fGauss", "gaus", -.5, .5);
1108 // Landau for charge resolution
1109 TF1 fl("fLandau", "landau", 0., 1000.);
1111 //PROCESS EXPERIMENTAL DISTRIBUTIONS
1112 // Charge resolution
1113 //Process3DL(kCharge, 0, &fl);
1114 // Clusters residuals
1115 Process2D(kCluster, 0, &fg, 1.e4);
1116 Process2D(kCluster, 1, &fg);
1118 // Tracklet residual/pulls
1119 Process2D(kTrackTRD , 0, &fg, 1.e4);
1120 Process2D(kTrackTRD , 1, &fg);
1121 Process2D(kTrackTRD , 2, &fg, 1.e4);
1122 Process2D(kTrackTRD , 3, &fg);
1123 Process2D(kTrackTRD , 4, &fg, 1.e3);
1125 // TPC track residual/pulls
1126 Process2D(kTrackTPC, 0, &fg, 1.e4);
1127 Process2D(kTrackTPC, 1, &fg);
1128 Process2D(kTrackTPC, 2, &fg, 1.e4);
1129 Process2D(kTrackTPC, 3, &fg);
1130 Process2D(kTrackTPC, 4, &fg, 1.e3);
1133 if(!HasMCdata()) return kTRUE;
1136 //PROCESS MC RESIDUAL DISTRIBUTIONS
1138 // CLUSTER Y RESOLUTION/PULLS
1139 Process2D(kMCcluster, 0, &fg, 1.e4);
1140 Process2D(kMCcluster, 1, &fg);
1143 // TRACKLET RESOLUTION/PULLS
1144 Process2D(kMCtracklet, 0, &fg, 1.e4); // y
1145 Process2D(kMCtracklet, 1, &fg); // y pulls
1146 Process2D(kMCtracklet, 2, &fg, 1.e4); // z
1147 Process2D(kMCtracklet, 3, &fg); // z pulls
1148 Process2D(kMCtracklet, 4, &fg, 1.e3); // phi
1151 // TRACK RESOLUTION/PULLS
1152 Process2D(kMCtrackTRD, 0, &fg, 1.e4); // y
1153 Process2D(kMCtrackTRD, 1, &fg); // y PULL
1154 Process2D(kMCtrackTRD, 2, &fg, 1.e4); // z
1155 Process2D(kMCtrackTRD, 3, &fg); // z PULL
1156 Process2D(kMCtrackTRD, 4, &fg, 1.e3); // phi
1157 Process2D(kMCtrackTRD, 5, &fg); // snp PULL
1158 Process2D(kMCtrackTRD, 6, &fg, 1.e3); // theta
1159 Process2D(kMCtrackTRD, 7, &fg); // tgl PULL
1160 Process4D(kMCtrackTRD, 8, &fg, 1.e2); // pt resolution
1161 Process4D(kMCtrackTRD, 9, &fg); // 1/pt pulls
1162 Process4D(kMCtrackTRD, 10, &fg, 1.e2); // p resolution
1165 // TRACK TPC RESOLUTION/PULLS
1166 Process2D(kMCtrackTPC, 0, &fg, 1.e4);// y resolution
1167 Process2D(kMCtrackTPC, 1, &fg); // y pulls
1168 Process2D(kMCtrackTPC, 2, &fg, 1.e4);// z resolution
1169 Process2D(kMCtrackTPC, 3, &fg); // z pulls
1170 Process2D(kMCtrackTPC, 4, &fg, 1.e3);// phi resolution
1171 Process2D(kMCtrackTPC, 5, &fg); // snp pulls
1172 Process2D(kMCtrackTPC, 6, &fg, 1.e3);// theta resolution
1173 Process2D(kMCtrackTPC, 7, &fg); // tgl pulls
1174 Process3D(kMCtrackTPC, 8, &fg, 1.e2);// pt resolution
1175 Process3D(kMCtrackTPC, 9, &fg); // 1/pt pulls
1176 Process3D(kMCtrackTPC, 10, &fg, 1.e2);// p resolution
1177 Process3D(kMCtrackTPC, 11, &fg); // p pulls
1180 // TRACK HMPID RESOLUTION/PULLS
1181 Process2D(kMCtrackTOF, 0, &fg, 1.e4); // z towards TOF
1182 Process2D(kMCtrackTOF, 1, &fg); // z towards TOF
1189 //________________________________________________________
1190 void AliTRDresolution::Terminate(Option_t *)
1193 delete fDebugStream;
1197 if(HasPostProcess()) PostProcess();
1200 //________________________________________________________
1201 void AliTRDresolution::AdjustF1(TH1 *h, TF1 *f)
1203 // Helper function to avoid duplication of code
1204 // Make first guesses on the fit parameters
1206 // find the intial parameters of the fit !! (thanks George)
1207 Int_t nbinsy = Int_t(.5*h->GetNbinsX());
1209 for(Int_t jbin=nbinsy-4; jbin<=nbinsy+4; jbin++) sum+=h->GetBinContent(jbin); sum/=9.;
1210 f->SetParLimits(0, 0., 3.*sum);
1211 f->SetParameter(0, .9*sum);
1212 Double_t rms = h->GetRMS();
1213 f->SetParLimits(1, -rms, rms);
1214 f->SetParameter(1, h->GetMean());
1216 f->SetParLimits(2, 0., 2.*rms);
1217 f->SetParameter(2, rms);
1218 if(f->GetNpar() <= 4) return;
1220 f->SetParLimits(3, 0., sum);
1221 f->SetParameter(3, .1*sum);
1223 f->SetParLimits(4, -.3, .3);
1224 f->SetParameter(4, 0.);
1226 f->SetParLimits(5, 0., 1.e2);
1227 f->SetParameter(5, 2.e-1);
1230 //________________________________________________________
1231 TObjArray* AliTRDresolution::Histos()
1233 if(fContainer) return fContainer;
1235 fContainer = new TObjArray(kNhistos);
1236 //fContainer->SetOwner(kTRUE);
1238 TObjArray *arr = 0x0;
1240 // cluster to track residuals/pulls
1241 fContainer->AddAt(arr = new TObjArray(fNElements[kCharge]), kCharge);
1242 arr->SetName("Charge");
1243 if(!(h = (TH3S*)gROOT->FindObject("hCharge"))){
1244 h = new TH3S("hCharge", "Charge Resolution", 20, 1., 2., 24, 0., 3.6, 100, 0., 500.);
1245 h->GetXaxis()->SetTitle("dx/dx_{0}");
1246 h->GetYaxis()->SetTitle("x_{d} [cm]");
1247 h->GetZaxis()->SetTitle("dq/dx [ADC/cm]");
1251 // cluster to track residuals/pulls
1252 fContainer->AddAt(arr = new TObjArray(fNElements[kCluster]), kCluster);
1254 if(!(h = (TH2I*)gROOT->FindObject("hCl"))){
1255 h = new TH2I("hCl", "Cluster Residuals", 21, -.33, .33, 100, -.5, .5);
1256 h->GetXaxis()->SetTitle("tg(#phi)");
1257 h->GetYaxis()->SetTitle("#Delta y [cm]");
1258 h->GetZaxis()->SetTitle("entries");
1261 if(!(h = (TH2I*)gROOT->FindObject("hClpull"))){
1262 h = new TH2I("hClpull", "Cluster Pulls", 21, -.33, .33, 100, -4.5, 4.5);
1263 h->GetXaxis()->SetTitle("tg(#phi)");
1264 h->GetYaxis()->SetTitle("#Delta y/#sigma_{y}");
1265 h->GetZaxis()->SetTitle("entries");
1269 // tracklet to track residuals/pulls in y direction
1270 fContainer->AddAt(arr = new TObjArray(fNElements[kTrackTRD ]), kTrackTRD );
1271 arr->SetName("Trklt");
1272 if(!(h = (TH2I*)gROOT->FindObject("hTrkltY"))){
1273 h = new TH2I("hTrkltY", "Tracklet Y Residuals", 21, -.33, .33, 100, -.5, .5);
1274 h->GetXaxis()->SetTitle("#tg(#phi)");
1275 h->GetYaxis()->SetTitle("#Delta y [cm]");
1276 h->GetZaxis()->SetTitle("entries");
1279 if(!(h = (TH2I*)gROOT->FindObject("hTrkltYpull"))){
1280 h = new TH2I("hTrkltYpull", "Tracklet Y Pulls", 21, -.33, .33, 100, -4.5, 4.5);
1281 h->GetXaxis()->SetTitle("#tg(#phi)");
1282 h->GetYaxis()->SetTitle("#Delta y/#sigma_{y}");
1283 h->GetZaxis()->SetTitle("entries");
1286 // tracklet to track residuals/pulls in z direction
1287 if(!(h = (TH2I*)gROOT->FindObject("hTrkltZ"))){
1288 h = new TH2I("hTrkltZ", "Tracklet Z Residuals", 50, -1., 1., 100, -1.5, 1.5);
1289 h->GetXaxis()->SetTitle("#tg(#theta)");
1290 h->GetYaxis()->SetTitle("#Delta z [cm]");
1291 h->GetZaxis()->SetTitle("entries");
1294 if(!(h = (TH2I*)gROOT->FindObject("hTrkltZpull"))){
1295 h = new TH2I("hTrkltZpull", "Tracklet Z Pulls", 50, -1., 1., 100, -5.5, 5.5);
1296 h->GetXaxis()->SetTitle("#tg(#theta)");
1297 h->GetYaxis()->SetTitle("#Delta z/#sigma_{z}");
1298 h->GetZaxis()->SetTitle("entries");
1301 // tracklet to track phi residuals
1302 if(!(h = (TH2I*)gROOT->FindObject("hTrkltPhi"))){
1303 h = new TH2I("hTrkltPhi", "Tracklet #phi Residuals", 21, -.33, .33, 100, -.5, .5);
1304 h->GetXaxis()->SetTitle("tg(#phi)");
1305 h->GetYaxis()->SetTitle("#Delta phi [rad]");
1306 h->GetZaxis()->SetTitle("entries");
1311 // tracklet to TPC track residuals/pulls in y direction
1312 fContainer->AddAt(arr = new TObjArray(fNElements[kTrackTPC]), kTrackTPC);
1313 arr->SetName("TrkTPC");
1314 if(!(h = (TH2I*)gROOT->FindObject("hTrkTPCY"))){
1315 h = new TH2I("hTrkTPCY", "Track[TPC] Y Residuals", 21, -.33, .33, 100, -.5, .5);
1316 h->GetXaxis()->SetTitle("#tg(#phi)");
1317 h->GetYaxis()->SetTitle("#Delta y [cm]");
1318 h->GetZaxis()->SetTitle("entries");
1321 if(!(h = (TH2I*)gROOT->FindObject("hTrkTPCYpull"))){
1322 h = new TH2I("hTrkTPCYpull", "Track[TPC] Y Pulls", 21, -.33, .33, 100, -4.5, 4.5);
1323 h->GetXaxis()->SetTitle("#tg(#phi)");
1324 h->GetYaxis()->SetTitle("#Delta y/#sigma_{y}");
1325 h->GetZaxis()->SetTitle("entries");
1328 // tracklet to TPC track residuals/pulls in z direction
1329 if(!(h = (TH2I*)gROOT->FindObject("hTrkTPCZ"))){
1330 h = new TH2I("hTrkTPCZ", "Track[TPC] Z Residuals", 50, -1., 1., 100, -1.5, 1.5);
1331 h->GetXaxis()->SetTitle("#tg(#theta)");
1332 h->GetYaxis()->SetTitle("#Delta z [cm]");
1333 h->GetZaxis()->SetTitle("entries");
1336 if(!(h = (TH2I*)gROOT->FindObject("hTrkTPCZpull"))){
1337 h = new TH2I("hTrkTPCZpull", "Track[TPC] Z Pulls", 50, -1., 1., 100, -5.5, 5.5);
1338 h->GetXaxis()->SetTitle("#tg(#theta)");
1339 h->GetYaxis()->SetTitle("#Delta z/#sigma_{z}");
1340 h->GetZaxis()->SetTitle("entries");
1343 // tracklet to TPC track phi residuals
1344 if(!(h = (TH2I*)gROOT->FindObject("hTrkTPCPhi"))){
1345 h = new TH2I("hTrkTPCPhi", "Track[TPC] #phi Residuals", 21, -.33, .33, 100, -.5, .5);
1346 h->GetXaxis()->SetTitle("tg(#phi)");
1347 h->GetYaxis()->SetTitle("#Delta phi [rad]");
1348 h->GetZaxis()->SetTitle("entries");
1353 // Resolution histos
1354 if(!HasMCdata()) return fContainer;
1356 // cluster y resolution [0]
1357 fContainer->AddAt(arr = new TObjArray(fNElements[kMCcluster]), kMCcluster);
1358 arr->SetName("McCl");
1359 if(!(h = (TH2I*)gROOT->FindObject("hMcCl"))){
1360 h = new TH2I("hMcCl", "Cluster Resolution", 48, -.48, .48, 100, -.3, .3);
1361 h->GetXaxis()->SetTitle("tg(#phi)");
1362 h->GetYaxis()->SetTitle("#Delta y [cm]");
1363 h->GetZaxis()->SetTitle("entries");
1366 if(!(h = (TH2I*)gROOT->FindObject("hMcClPull"))){
1367 h = new TH2I("hMcClPull", "Cluster Pulls", 48, -.48, .48, 100, -4.5, 4.5);
1368 h->GetXaxis()->SetTitle("tg(#phi)");
1369 h->GetYaxis()->SetTitle("#Deltay/#sigma_{y}");
1370 h->GetZaxis()->SetTitle("entries");
1375 // TRACKLET RESOLUTION
1376 fContainer->AddAt(arr = new TObjArray(fNElements[kMCtracklet]), kMCtracklet);
1377 arr->SetName("McTrklt");
1378 // tracklet y resolution
1379 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkltY"))){
1380 h = new TH2I("hMcTrkltY", "Tracklet Resolution (Y)", 48, -.48, .48, 100, -.2, .2);
1381 h->GetXaxis()->SetTitle("tg(#phi)");
1382 h->GetYaxis()->SetTitle("#Delta y [cm]");
1383 h->GetZaxis()->SetTitle("entries");
1387 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkltYPull"))){
1388 h = new TH2I("hMcTrkltYPull", "Tracklet Pulls (Y)", 48, -.48, .48, 100, -4.5, 4.5);
1389 h->GetXaxis()->SetTitle("tg(#phi)");
1390 h->GetYaxis()->SetTitle("#Delta y / #sigma_{y}");
1391 h->GetZaxis()->SetTitle("entries");
1394 // tracklet z resolution
1395 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkltZ"))){
1396 h = new TH2I("hMcTrkltZ", "Tracklet Resolution (Z)", 100, -1., 1., 100, -1., 1.);
1397 h->GetXaxis()->SetTitle("tg(#theta)");
1398 h->GetYaxis()->SetTitle("#Delta z [cm]");
1399 h->GetZaxis()->SetTitle("entries");
1403 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkltZPull"))){
1404 h = new TH2I("hMcTrkltZPull", "Tracklet Pulls (Z)", 100, -1., 1., 100, -3.5, 3.5);
1405 h->GetXaxis()->SetTitle("tg(#theta)");
1406 h->GetYaxis()->SetTitle("#Delta z / #sigma_{z}");
1407 h->GetZaxis()->SetTitle("entries");
1410 // tracklet phi resolution
1411 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkltPhi"))){
1412 h = new TH2I("hMcTrkltPhi", "Tracklet Resolution (#Phi)", 48, -.48, .48, 100, -.15, .15);
1413 h->GetXaxis()->SetTitle("tg(#phi)");
1414 h->GetYaxis()->SetTitle("#Delta #phi [rad]");
1415 h->GetZaxis()->SetTitle("entries");
1420 // KALMAN TRACK RESOLUTION
1421 fContainer->AddAt(arr = new TObjArray(fNElements[kMCtrackTRD]), kMCtrackTRD);
1422 arr->SetName("McTrkTRD");
1423 // Kalman track y resolution
1424 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkY"))){
1425 h = new TH2I("hMcTrkY", "Track Y Resolution", 48, -.48, .48, 100, -.2, .2);
1426 h->GetXaxis()->SetTitle("tg(#phi)");
1427 h->GetYaxis()->SetTitle("#Delta y [cm]");
1428 h->GetZaxis()->SetTitle("entries");
1431 // Kalman track y pulls
1432 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkYPull"))){
1433 h = new TH2I("hMcTrkYPull", "Track Y Pulls", 48, -.48, .48, 100, -4., 4.);
1434 h->GetXaxis()->SetTitle("tg(#phi)");
1435 h->GetYaxis()->SetTitle("#Delta y / #sigma_{y}");
1436 h->GetZaxis()->SetTitle("entries");
1440 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkZ"))){
1441 h = new TH2I("hMcTrkZ", "Track Z Resolution", 100, -1., 1., 100, -1., 1.);
1442 h->GetXaxis()->SetTitle("tg(#theta)");
1443 h->GetYaxis()->SetTitle("#Delta z [cm]");
1444 h->GetZaxis()->SetTitle("entries");
1447 // Kalman track Z pulls
1448 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkZPull"))){
1449 h = new TH2I("hMcTrkZPull", "Track Z Pulls", 100, -1., 1., 100, -4.5, 4.5);
1450 h->GetXaxis()->SetTitle("tg(#theta)");
1451 h->GetYaxis()->SetTitle("#Delta z / #sigma_{z}");
1452 h->GetZaxis()->SetTitle("entries");
1456 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkSNP"))){
1457 h = new TH2I("hMcTrkSNP", "Track Phi Resolution", 60, -.3, .3, 100, -5e-3, 5e-3);
1458 h->GetXaxis()->SetTitle("tg(#phi)");
1459 h->GetYaxis()->SetTitle("#Delta #phi [rad]");
1460 h->GetZaxis()->SetTitle("entries");
1463 // Kalman track SNP pulls
1464 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkSNPPull"))){
1465 h = new TH2I("hMcTrkSNPPull", "Track SNP Pulls", 60, -.3, .3, 100, -4.5, 4.5);
1466 h->GetXaxis()->SetTitle("tg(#phi)");
1467 h->GetYaxis()->SetTitle("#Delta(sin(#phi)) / #sigma_{sin(#phi)}");
1468 h->GetZaxis()->SetTitle("entries");
1472 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTGL"))){
1473 h = new TH2I("hMcTrkTGL", "Track Theta Resolution", 100, -1., 1., 100, -5e-3, 5e-3);
1474 h->GetXaxis()->SetTitle("tg(#theta)");
1475 h->GetYaxis()->SetTitle("#Delta#theta [rad]");
1476 h->GetZaxis()->SetTitle("entries");
1479 // Kalman track TGL pulls
1480 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTGLPull"))){
1481 h = new TH2I("hMcTrkTGLPull", "Track TGL Pulls", 100, -1., 1., 100, -4.5, 4.5);
1482 h->GetXaxis()->SetTitle("tg(#theta)");
1483 h->GetYaxis()->SetTitle("#Delta(tg(#theta)) / #sigma_{tg(#theta)}");
1484 h->GetZaxis()->SetTitle("entries");
1487 // Kalman track Pt resolution
1488 const Int_t n = AliPID::kSPECIES;
1489 TObjArray *arr2 = 0x0; TH3S* h3=0x0;
1490 arr->AddAt(arr2 = new TObjArray(AliTRDgeometry::kNlayer), 8);
1491 arr2->SetName("Track Pt Resolution");
1492 for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
1493 if(!(h3 = (TH3S*)gROOT->FindObject(Form("hMcTrkPt%d", il)))){
1494 h3 = new TH3S(Form("hMcTrkPt%d", il), "Track Pt Resolution", 40, 0., 20., 150, -.1, .2, n, -.5, n-.5);
1495 h3->GetXaxis()->SetTitle("p_{t} [GeV/c]");
1496 h3->GetYaxis()->SetTitle("#Delta p_{t}/p_{t}^{MC}");
1497 h3->GetZaxis()->SetTitle("SPECIES");
1499 arr2->AddAt(h3, il);
1501 // Kalman track Pt pulls
1502 arr->AddAt(arr2 = new TObjArray(AliTRDgeometry::kNlayer), 9);
1503 arr2->SetName("Track 1/Pt Pulls");
1504 for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
1505 if(!(h3 = (TH3S*)gROOT->FindObject(Form("hMcTrkPtPulls%d", il)))){
1506 h3 = new TH3S(Form("hMcTrkPtPulls%d", il), "Track 1/Pt Pulls", 40, 0., 2., 100, -4., 4., n, -.5, n-.5);
1507 h3->GetXaxis()->SetTitle("1/p_{t}^{MC} [c/GeV]");
1508 h3->GetYaxis()->SetTitle("#Delta(1/p_{t})/#sigma(1/p_{t}) ");
1509 h3->GetZaxis()->SetTitle("SPECIES");
1511 arr2->AddAt(h3, il);
1513 // Kalman track P resolution
1514 arr->AddAt(arr2 = new TObjArray(AliTRDgeometry::kNlayer), 10);
1515 arr2->SetName("Track P Resolution [PID]");
1516 for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
1517 if(!(h3 = (TH3S*)gROOT->FindObject(Form("hMcTrkP%d", il)))){
1518 h3 = new TH3S(Form("hMcTrkP%d", il), "Track P Resolution", 40, 0., 20., 150, -.15, .35, n, -.5, n-.5);
1519 h3->GetXaxis()->SetTitle("p [GeV/c]");
1520 h3->GetYaxis()->SetTitle("#Delta p/p^{MC}");
1521 h3->GetZaxis()->SetTitle("SPECIES");
1523 arr2->AddAt(h3, il);
1526 // TPC TRACK RESOLUTION
1527 fContainer->AddAt(arr = new TObjArray(fNElements[kMCtrackTPC]), kMCtrackTPC);
1528 arr->SetName("McTrkTPC");
1530 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCY"))){
1531 h = new TH2I("hMcTrkTPCY", "Track[TPC] Y Resolution", 60, -.3, .3, 100, -.5, .5);
1532 h->GetXaxis()->SetTitle("tg(#phi)");
1533 h->GetYaxis()->SetTitle("#Delta y [cm]");
1534 h->GetZaxis()->SetTitle("entries");
1537 // Kalman track Y pulls
1538 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCYPull"))){
1539 h = new TH2I("hMcTrkTPCYPull", "Track[TPC] Y Pulls", 60, -.3, .3, 100, -4.5, 4.5);
1540 h->GetXaxis()->SetTitle("tg(#phi)");
1541 h->GetYaxis()->SetTitle("#Delta y / #sigma_{y}");
1542 h->GetZaxis()->SetTitle("entries");
1546 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCZ"))){
1547 h = new TH2I("hMcTrkTPCZ", "Track[TPC] Z Resolution", 100, -1., 1., 100, -1., 1.);
1548 h->GetXaxis()->SetTitle("tg(#theta)");
1549 h->GetYaxis()->SetTitle("#Delta z [cm]");
1550 h->GetZaxis()->SetTitle("entries");
1553 // Kalman track Z pulls
1554 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCZPull"))){
1555 h = new TH2I("hMcTrkTPCZPull", "Track[TPC] Z Pulls", 100, -1., 1., 100, -4.5, 4.5);
1556 h->GetXaxis()->SetTitle("tg(#theta)");
1557 h->GetYaxis()->SetTitle("#Delta z / #sigma_{z}");
1558 h->GetZaxis()->SetTitle("entries");
1562 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCSNP"))){
1563 h = new TH2I("hMcTrkTPCSNP", "Track[TPC] Phi Resolution", 60, -.3, .3, 100, -5e-3, 5e-3);
1564 h->GetXaxis()->SetTitle("tg(#phi)");
1565 h->GetYaxis()->SetTitle("#Delta #phi [rad]");
1566 h->GetZaxis()->SetTitle("entries");
1569 // Kalman track SNP pulls
1570 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCSNPPull"))){
1571 h = new TH2I("hMcTrkTPCSNPPull", "Track[TPC] SNP Pulls", 60, -.3, .3, 100, -4.5, 4.5);
1572 h->GetXaxis()->SetTitle("tg(#phi)");
1573 h->GetYaxis()->SetTitle("#Delta(sin(#phi)) / #sigma_{sin(#phi)}");
1574 h->GetZaxis()->SetTitle("entries");
1578 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCTGL"))){
1579 h = new TH2I("hMcTrkTPCTGL", "Track[TPC] Theta Resolution", 100, -1., 1., 100, -5e-3, 5e-3);
1580 h->GetXaxis()->SetTitle("tg(#theta)");
1581 h->GetYaxis()->SetTitle("#Delta#theta [rad]");
1582 h->GetZaxis()->SetTitle("entries");
1585 // Kalman track TGL pulls
1586 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTPCTGLPull"))){
1587 h = new TH2I("hMcTrkTPCTGLPull", "Track[TPC] TGL Pulls", 100, -1., 1., 100, -4.5, 4.5);
1588 h->GetXaxis()->SetTitle("tg(#theta)");
1589 h->GetYaxis()->SetTitle("#Delta(tg(#theta)) / #sigma_{tg(#theta)}");
1590 h->GetZaxis()->SetTitle("entries");
1593 // Kalman track Pt resolution
1594 if(!(h3 = (TH3S*)gROOT->FindObject("hMcTrkTPCPt"))){
1595 h3 = new TH3S("hMcTrkTPCPt", "Track[TPC] Pt Resolution", 80, 0., 20., 150, -.1, .2, n, -.5, n-.5);
1596 h3->GetXaxis()->SetTitle("p_{t} [GeV/c]");
1597 h3->GetYaxis()->SetTitle("#Delta p_{t}/p_{t}^{MC}");
1598 h3->GetZaxis()->SetTitle("SPECIES");
1601 // Kalman track Pt pulls
1602 if(!(h3 = (TH3S*)gROOT->FindObject("hMcTrkTPCPtPulls"))){
1603 h3 = new TH3S("hMcTrkTPCPtPulls", "Track[TPC] 1/Pt Pulls", 80, 0., 2., 100, -4., 4., n, -.5, n-.5);
1604 h3->GetXaxis()->SetTitle("1/p_{t}^{MC} [c/GeV]");
1605 h3->GetYaxis()->SetTitle("#Delta(1/p_{t})/#sigma(1/p_{t}) ");
1606 h3->GetZaxis()->SetTitle("SPECIES");
1609 // Kalman track P resolution
1610 if(!(h3 = (TH3S*)gROOT->FindObject("hMcTrkTPCP"))){
1611 h3 = new TH3S("hMcTrkTPCP", "Track[TPC] P Resolution", 80, 0., 20., 150, -.15, .35, n, -.5, n-.5);
1612 h3->GetXaxis()->SetTitle("p [GeV/c]");
1613 h3->GetYaxis()->SetTitle("#Delta p/p^{MC}");
1614 h3->GetZaxis()->SetTitle("SPECIES");
1617 // Kalman track Pt pulls
1618 if(!(h3 = (TH3S*)gROOT->FindObject("hMcTrkTPCPPulls"))){
1619 h3 = new TH3S("hMcTrkTPCPPulls", "Track[TPC] P Pulls", 80, 0., 20., 100, -5., 5., n, -.5, n-.5);
1620 h3->GetXaxis()->SetTitle("p^{MC} [GeV/c]");
1621 h3->GetYaxis()->SetTitle("#Deltap/#sigma_{p}");
1622 h3->GetZaxis()->SetTitle("SPECIES");
1628 // Kalman track Z resolution [TOF]
1629 fContainer->AddAt(arr = new TObjArray(fNElements[kMCtrackTOF]), kMCtrackTOF);
1630 arr->SetName("McTrkTOF");
1631 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTOFZ"))){
1632 h = new TH2I("hMcTrkTOFZ", "Track[TOF] Z Resolution", 100, -1., 1., 100, -1., 1.);
1633 h->GetXaxis()->SetTitle("tg(#theta)");
1634 h->GetYaxis()->SetTitle("#Delta z [cm]");
1635 h->GetZaxis()->SetTitle("entries");
1638 // Kalman track Z pulls
1639 if(!(h = (TH2I*)gROOT->FindObject("hMcTrkTOFZPull"))){
1640 h = new TH2I("hMcTrkTOFZPull", "Track[TOF] Z Pulls", 100, -1., 1., 100, -4.5, 4.5);
1641 h->GetXaxis()->SetTitle("tg(#theta)");
1642 h->GetYaxis()->SetTitle("#Delta z / #sigma_{z}");
1643 h->GetZaxis()->SetTitle("entries");
1650 //________________________________________________________
1651 Bool_t AliTRDresolution::Process(TH2* h2, TF1 *f, Float_t k, TGraphErrors **g)
1653 Char_t pn[10]; sprintf(pn, "p%02d", fIdxPlot);
1655 if((n=g[0]->GetN())) for(;n--;) g[0]->RemovePoint(n);
1656 if((n=g[1]->GetN())) for(;n--;) g[1]->RemovePoint(n);
1658 for(Int_t ibin = 1; ibin <= h2->GetNbinsX(); ibin++){
1659 Double_t x = h2->GetXaxis()->GetBinCenter(ibin);
1660 TH1D *h = h2->ProjectionY(pn, ibin, ibin);
1661 if(h->GetEntries()<100) continue;
1666 Int_t ip = g[0]->GetN();
1667 g[0]->SetPoint(ip, x, k*f->GetParameter(1));
1668 g[0]->SetPointError(ip, 0., k*f->GetParError(1));
1669 g[1]->SetPoint(ip, x, k*f->GetParameter(2));
1670 g[1]->SetPointError(ip, 0., k*f->GetParError(2));
1673 g[0]->SetPoint(ip, x, k*h->GetMean());
1674 g[0]->SetPointError(ip, 0., k*h->GetMeanError());
1675 g[1]->SetPoint(ip, x, k*h->GetRMS());
1676 g[1]->SetPointError(ip, 0., k*h->GetRMSError());*/
1682 //________________________________________________________
1683 Bool_t AliTRDresolution::Process2D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
1685 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
1687 // retrive containers
1688 TH2I *h2 = idx<0 ? (TH2I*)(fContainer->At(plot)) : (TH2I*)((TObjArray*)(fContainer->At(plot)))->At(idx);
1689 if(!h2) return kFALSE;
1691 if(!(g[0] = idx<0 ? (TGraphErrors*)fGraphM->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
1693 if(!(g[1] = idx<0 ? (TGraphErrors*)fGraphS->At(plot) : (TGraphErrors*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
1695 return Process(h2, f, k, g);
1698 //________________________________________________________
1699 Bool_t AliTRDresolution::Process3D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
1701 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
1703 // retrive containers
1704 TH3S *h3 = idx<0 ? (TH3S*)(fContainer->At(plot)) : (TH3S*)((TObjArray*)(fContainer->At(plot)))->At(idx);
1705 if(!h3) return kFALSE;
1708 if(!(gm = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
1709 if(!(gs = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
1712 TAxis *az = h3->GetZaxis();
1713 for(Int_t iz=1; iz<=az->GetNbins(); iz++){
1714 if(!(g[0] = (TGraphErrors*)gm->At(iz-1))) return kFALSE;
1715 if(!(g[1] = (TGraphErrors*)gs->At(iz-1))) return kFALSE;
1716 az->SetRange(iz, iz);
1717 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
1723 //________________________________________________________
1724 Bool_t AliTRDresolution::Process3DL(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
1726 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
1728 // retrive containers
1729 TH3S *h3 = (TH3S*)((TObjArray*)fContainer->At(plot))->At(idx);
1730 if(!h3) return kFALSE;
1732 TGraphAsymmErrors *gm;
1734 if(!(gm = (TGraphAsymmErrors*)((TObjArray*)fGraphM->At(plot))->At(0))) return kFALSE;
1735 if(!(gs = (TGraphErrors*)((TObjArray*)fGraphS->At(plot)))) return kFALSE;
1737 Float_t x, r, mpv, xM, xm;
1738 TAxis *ay = h3->GetYaxis();
1739 for(Int_t iy=1; iy<=h3->GetNbinsY(); iy++){
1740 ay->SetRange(iy, iy);
1741 x = ay->GetBinCenter(iy);
1742 TH2F *h2=(TH2F*)h3->Project3D("zx");
1743 TAxis *ax = h2->GetXaxis();
1744 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
1745 r = ax->GetBinCenter(ix);
1746 TH1D *h1 = h2->ProjectionY("py", ix, ix);
1747 if(h1->Integral()<50) continue;
1750 GetLandauMpvFwhm(f, mpv, xm, xM);
1751 Int_t ip = gm->GetN();
1752 gm->SetPoint(ip, x, k*mpv);
1753 gm->SetPointError(ip, 0., 0., k*xm, k*xM);
1754 gs->SetPoint(ip, r, k*(xM-xm)/mpv);
1755 gs->SetPointError(ip, 0., 0.);
1762 //________________________________________________________
1763 Bool_t AliTRDresolution::Process4D(ETRDresolutionPlot plot, Int_t idx, TF1 *f, Float_t k)
1765 if(!fContainer || !fGraphS || !fGraphM) return kFALSE;
1767 // retrive containers
1768 TObjArray *arr = (TObjArray*)((TObjArray*)(fContainer->At(plot)))->At(idx);
1769 if(!arr) return kFALSE;
1772 TObjArray *gm[2], *gs[2];
1773 if(!(gm[0] = (TObjArray*)((TObjArray*)(fGraphM->At(plot)))->At(idx))) return kFALSE;
1774 if(!(gs[0] = (TObjArray*)((TObjArray*)(fGraphS->At(plot)))->At(idx))) return kFALSE;
1779 for(Int_t ix=0; ix<arr->GetEntriesFast(); ix++){
1780 if(!(h3 = (TH3S*)arr->At(ix))) return kFALSE;
1781 if(!(gm[1] = (TObjArray*)gm[0]->At(ix))) return kFALSE;
1782 if(!(gs[1] = (TObjArray*)gs[0]->At(ix))) return kFALSE;
1783 TAxis *az = h3->GetZaxis();
1784 for(Int_t iz=1; iz<=az->GetNbins(); iz++){
1785 if(!(g[0] = (TGraphErrors*)gm[1]->At(iz-1))) return kFALSE;
1786 if(!(g[1] = (TGraphErrors*)gs[1]->At(iz-1))) return kFALSE;
1787 az->SetRange(iz, iz);
1788 if(!Process((TH2*)h3->Project3D("yx"), f, k, g)) return kFALSE;
1795 //________________________________________________________
1796 Bool_t AliTRDresolution::GetGraphPlot(Float_t *bb, ETRDresolutionPlot ip, Int_t idx)
1798 if(!fGraphS || !fGraphM) return kFALSE;
1799 TGraphErrors *gm = idx<0 ? (TGraphErrors*)fGraphM->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphM->At(ip)))->At(idx);
1800 if(!gm) return kFALSE;
1801 TGraphErrors *gs = idx<0 ? (TGraphErrors*)fGraphS->At(ip) : (TGraphErrors*)((TObjArray*)(fGraphS->At(ip)))->At(idx);
1802 if(!gs) return kFALSE;
1803 gs->Draw("apl"); gm->Draw("pl");
1807 for(Int_t jp=0; jp<(Int_t)ip; jp++) nref+=fNElements[jp];
1808 UChar_t jdx = idx<0?0:idx;
1809 for(Int_t jc=0; jc<TMath::Min(jdx,fNElements[ip]-1); jc++) nref++;
1810 Char_t **at = fAxTitle[nref];
1812 PutTrendValue(Form("%s_%sMean", fPerformanceName[ip], at[0]), gm->GetMean(2), gm->GetRMS(2));
1813 gs->Sort(&TGraph::CompareY); Int_t n = gs->GetN();
1814 PutTrendValue(Form("%s_%sSigMin", fPerformanceName[ip], at[0]), gs->GetY()[0], 0.);
1815 PutTrendValue(Form("%s_%sSigMax", fPerformanceName[ip], at[0]), gs->GetY()[n-1], 0.);
1816 gs->Sort(&TGraph::CompareX);
1821 ax = gs->GetHistogram()->GetXaxis();
1822 ax->SetRangeUser(bb[0], bb[2]);
1823 ax->SetTitle(at[1]);ax->CenterTitle();
1825 ax = gs->GetHistogram()->GetYaxis();
1826 ax->SetRangeUser(bb[1], bb[3]);
1827 ax->SetTitleOffset(1.1);
1828 ax->SetTitle(at[2]);ax->CenterTitle();
1831 gax = new TGaxis(bb[2], bb[1], bb[2], bb[3], bb[1], bb[3], 510, "+U");
1832 gax->SetLineColor(kRed);gax->SetLineWidth(2);gax->SetTextColor(kRed);
1833 //gax->SetVertical();
1834 gax->CenterTitle(); gax->SetTitleOffset(.7);
1835 gax->SetTitle(at[3]); gax->Draw();
1838 TBox *b = new TBox(-.15, bb[1], .15, bb[3]);
1839 b->SetFillStyle(3002);b->SetLineColor(0);
1840 b->SetFillColor(ip<=Int_t(kMCcluster)?kGreen:kBlue);
1846 //________________________________________________________
1847 Bool_t AliTRDresolution::GetGraphTrack(Float_t *bb, Int_t idx, Int_t il)
1849 if(!fGraphS || !fGraphM) return kFALSE;
1851 // axis titles look up
1853 for(Int_t jp=0; jp<Int_t(kMCtrackTRD); jp++) nref+=fNElements[jp];
1854 for(Int_t jc=0; jc<idx; jc++) nref++;
1855 Char_t **at = fAxTitle[nref];
1857 TGraphErrors *gm = 0x0, *gs = 0x0;
1858 TObjArray *a0 = fGraphS, *a1 = 0x0;
1859 a1 = (TObjArray*)a0->At(kMCtrackTRD); a0 = a1;
1860 a1 = (TObjArray*)a0->At(idx); a0 = a1;
1861 a1 = (TObjArray*)a0->At(il); a0 = a1;
1862 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1863 if(!(gs = (TGraphErrors*)a0->At(is))) return kFALSE;
1864 if(!gs->GetN()) continue;
1865 gs->Draw(is ? "pl" : "apl");
1866 gs->Sort(&TGraph::CompareY); Int_t n = gs->GetN();
1867 PutTrendValue(Form("%s_%sSigMin%s", fPerformanceName[kMCtrackTRD], at[0], AliPID::ParticleShortName(is)), gs->GetY()[0], 0.);
1868 PutTrendValue(Form("%s_%sSigMax%s", fPerformanceName[kMCtrackTRD], at[0], AliPID::ParticleShortName(is)), gs->GetY()[n-1], 0.);
1869 gs->Sort(&TGraph::CompareX);
1871 gs = (TGraphErrors*)a0->At(0);
1874 TAxis *ax = gs->GetHistogram()->GetXaxis();
1875 ax->SetRangeUser(bb[0], bb[2]);
1876 ax->SetTitle(at[1]);ax->CenterTitle();
1878 ax = gs->GetHistogram()->GetYaxis();
1879 ax->SetRangeUser(bb[1], bb[3]);
1880 ax->SetTitleOffset(.5);ax->SetTitleSize(.06);
1881 ax->SetTitle(at[2]);ax->CenterTitle();
1884 gax = new TGaxis(bb[2], bb[1], bb[2], bb[3], bb[1], bb[3], 510, "+U");
1885 gax->SetLineColor(kRed);gax->SetLineWidth(2);gax->SetTextColor(kRed);
1886 //gax->SetVertical();
1887 gax->CenterTitle(); gax->SetTitleOffset(.5);gax->SetTitleSize(.06);
1888 gax->SetTitle(at[3]); gax->Draw();
1892 a1 = (TObjArray*)a0->At(kMCtrackTRD); a0 = a1;
1893 a1 = (TObjArray*)a0->At(idx); a0 = a1;
1894 a1 = (TObjArray*)a0->At(il); a0 = a1;
1895 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1896 if(!(gm = (TGraphErrors*)a0->At(is))) return kFALSE;
1897 if(!gm->GetN()) continue;
1899 PutTrendValue(Form("%s_%sMean%s", fPerformanceName[kMCtrackTRD], at[0], AliPID::ParticleShortName(is)), gm->GetMean(2), gm->GetRMS(2));
1906 //________________________________________________________
1907 Bool_t AliTRDresolution::GetGraphTrackTPC(Float_t *bb, Int_t sel)
1909 if(!fGraphS || !fGraphM) return kFALSE;
1911 // axis titles look up
1913 for(Int_t jp=0; jp<Int_t(kMCtrackTPC); jp++) nref+=fNElements[jp];
1914 for(Int_t jc=0; jc<sel; jc++) nref++;
1915 Char_t **at = fAxTitle[nref];
1917 TGraphErrors *gm = 0x0, *gs = 0x0;
1918 TObjArray *a0 = fGraphS, *a1 = 0x0;
1919 a1 = (TObjArray*)a0->At(kMCtrackTPC); a0 = a1;
1920 a1 = (TObjArray*)a0->At(sel); a0 = a1;
1921 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1922 if(!(gs = (TGraphErrors*)a0->At(is))) return kFALSE;
1923 if(!gs->GetN()) continue;
1924 gs->Draw(is ? "pl" : "apl");
1925 gs->Sort(&TGraph::CompareY); Int_t n = gs->GetN();
1926 PutTrendValue(Form("%s_%sSigMin%s", fPerformanceName[kMCtrackTPC], at[0], AliPID::ParticleShortName(is)), gs->GetY()[0], 0.);
1927 PutTrendValue(Form("%s_%sSigMax%s", fPerformanceName[kMCtrackTPC], at[0], AliPID::ParticleShortName(is)), gs->GetY()[n-1], 0.);
1928 gs->Sort(&TGraph::CompareX);
1930 gs = (TGraphErrors*)a0->At(0);
1932 TAxis *ax = gs->GetHistogram()->GetXaxis();
1933 ax->SetRangeUser(bb[0], bb[2]);
1934 ax->SetTitle(at[1]);ax->CenterTitle();
1936 ax = gs->GetHistogram()->GetYaxis();
1937 ax->SetRangeUser(bb[1], bb[3]);
1938 ax->SetTitleOffset(1.);ax->SetTitleSize(0.05);
1939 ax->SetTitle(at[2]);ax->CenterTitle();
1942 gax = new TGaxis(bb[2], bb[1], bb[2], bb[3], bb[1], bb[3], 510, "+U");
1943 gax->SetLineColor(kRed);gax->SetLineWidth(2);gax->SetTextColor(kRed);
1944 //gax->SetVertical();
1945 gax->CenterTitle(); gax->SetTitleOffset(.7);gax->SetTitleSize(0.05);
1946 gax->SetTitle(at[3]); gax->Draw();
1950 a1 = (TObjArray*)a0->At(kMCtrackTPC); a0 = a1;
1951 a1 = (TObjArray*)a0->At(sel); a0 = a1;
1952 for(Int_t is=0; is<AliPID::kSPECIES; is++){
1953 if(!(gm = (TGraphErrors*)a0->At(is))) return kFALSE;
1954 if(!gm->GetN()) continue;
1956 PutTrendValue(Form("%s_%sMean%s", fPerformanceName[kMCtrackTPC], at[0], AliPID::ParticleShortName(is)), gm->GetMean(2), gm->GetRMS(2));
1962 //________________________________________________________
1963 void AliTRDresolution::GetLandauMpvFwhm(TF1 *f, Float_t &mpv, Float_t &xm, Float_t &xM)
1965 const Float_t dx = 1.;
1966 mpv = f->GetParameter(1);
1967 Float_t fx, max = f->Eval(mpv);
1970 while((fx = f->Eval(xm))>.5*max){
1979 while((fx = f->Eval(xM))>.5*max) xM += dx;
1983 //________________________________________________________
1984 void AliTRDresolution::SetRecoParam(AliTRDrecoParam *r)
1987 fReconstructor->SetRecoParam(r);