]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/qaRec/AliTRDtrackingResolution.cxx
propagate cluster error parametrization
[u/mrichter/AliRoot.git] / TRD / qaRec / AliTRDtrackingResolution.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
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 **************************************************************************/
15
16 /* $Id: AliTRDtrackingResolution.cxx 27496 2008-07-22 08:35:45Z cblume $ */
17
18 ////////////////////////////////////////////////////////////////////////////
19 //                                                                        //
20 //  TRD tracking resolution                                               //
21 //
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
27 // 
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
31 // 
32 // For stand alone usage please refer to the following example: 
33 // {  
34 //   gSystem->Load("libANALYSIS.so");
35 //   gSystem->Load("libTRDqaRec.so");
36 //   AliTRDtrackingResolution *res = new AliTRDtrackingResolution();
37 //   //res->SetMCdata();
38 //   //res->SetVerbose();
39 //   //res->SetVisual();
40 //   res->Load("TRD.TaskResolution.root");
41 //   if(!res->PostProcess()) return;
42 //   res->GetRefFigure(0);
43 // }  
44 //
45 //  Authors:                                                              //
46 //    Alexandru Bercuci <A.Bercuci@gsi.de>                                //
47 //    Markus Fasel <M.Fasel@gsi.de>                                       //
48 //                                                                        //
49 ////////////////////////////////////////////////////////////////////////////
50
51 #include <cstring>
52
53 #include <TROOT.h>
54 #include <TSystem.h>
55 #include <TObjArray.h>
56 #include <TH2.h>
57 #include <TH1.h>
58 #include <TF1.h>
59 #include <TCanvas.h>
60 #include <TBox.h>
61 #include <TProfile.h>
62 #include <TGraphErrors.h>
63 #include <TMath.h>
64 #include "TTreeStream.h"
65 #include "TGeoManager.h"
66
67 #include "AliAnalysisManager.h"
68 #include "AliTrackReference.h"
69 #include "AliTrackPointArray.h"
70 #include "AliCDBManager.h"
71
72 #include "AliTRDSimParam.h"
73 #include "AliTRDgeometry.h"
74 #include "AliTRDpadPlane.h"
75 #include "AliTRDcluster.h"
76 #include "AliTRDseedV1.h"
77 #include "AliTRDtrackV1.h"
78 #include "AliTRDtrackerV1.h"
79 #include "AliTRDReconstructor.h"
80 #include "AliTRDrecoParam.h"
81
82 #include "AliTRDtrackInfo/AliTRDclusterInfo.h"
83 #include "AliTRDtrackInfo/AliTRDtrackInfo.h"
84 #include "AliTRDtrackingResolution.h"
85
86 ClassImp(AliTRDtrackingResolution)
87
88 //________________________________________________________
89 AliTRDtrackingResolution::AliTRDtrackingResolution()
90   :AliTRDrecoTask("Resolution", "Tracking Resolution")
91   ,fStatus(0)
92   ,fReconstructor(0x0)
93   ,fGeo(0x0)
94   ,fGraphS(0x0)
95   ,fGraphM(0x0)
96   ,fClResiduals(0x0)
97   ,fTrkltResiduals(0x0)
98   ,fTrkltPhiResiduals(0x0)
99   ,fClResolution(0x0)
100   ,fTrkltResolution(0x0)
101 {
102   fReconstructor = new AliTRDReconstructor();
103   fReconstructor->SetRecoParam(AliTRDrecoParam::GetLowFluxParam());
104   fGeo = new AliTRDgeometry();
105
106   InitFunctorList();
107
108   DefineOutput(1+kClusterResidual, TObjArray::Class());
109   DefineOutput(1+kTrackletYResidual, TObjArray::Class());
110   DefineOutput(1+kTrackletPhiResidual, TObjArray::Class());
111   DefineOutput(1+kClusterResolution, TObjArray::Class());
112   DefineOutput(1+kTrackletYResolution, TObjArray::Class());
113 }
114
115 //________________________________________________________
116 AliTRDtrackingResolution::~AliTRDtrackingResolution()
117 {
118   if(fGraphS){fGraphS->Delete(); delete fGraphS;}
119   if(fGraphM){fGraphM->Delete(); delete fGraphM;}
120   delete fGeo;
121   delete fReconstructor;
122   if(gGeoManager) delete gGeoManager;
123   if(fClResiduals){fClResiduals->Delete(); delete fClResiduals;}
124   if(fTrkltResiduals){fTrkltResiduals->Delete(); delete fTrkltResiduals;}
125   if(fTrkltPhiResiduals){fTrkltPhiResiduals->Delete(); delete fTrkltPhiResiduals;}
126   if(fClResolution){
127     fClResolution->Delete(); 
128     delete fClResolution;
129   }
130   if(fTrkltResolution){fTrkltResolution->Delete(); delete fTrkltResolution;}
131 }
132
133
134 //________________________________________________________
135 void AliTRDtrackingResolution::CreateOutputObjects()
136 {
137   // spatial resolution
138   OpenFile(0, "RECREATE");
139
140   fContainer = Histos();
141
142   fClResiduals = new TObjArray();
143   fClResiduals->SetOwner(kTRUE);
144   fTrkltResiduals = new TObjArray();
145   fTrkltResiduals->SetOwner(kTRUE);
146   fTrkltPhiResiduals = new TObjArray();
147   fTrkltPhiResiduals->SetOwner(kTRUE);
148   fClResolution = new TObjArray();
149   fClResolution->SetOwner(kTRUE);
150   fTrkltResolution = new TObjArray();
151   fTrkltResolution->SetOwner(kTRUE);
152 }
153
154 //________________________________________________________
155 void AliTRDtrackingResolution::Exec(Option_t *opt)
156 {
157   fClResiduals->Delete();
158   fTrkltResiduals->Delete();
159   fTrkltPhiResiduals->Delete();
160   fClResolution->Delete();
161   fTrkltResolution->Delete();
162
163   AliTRDrecoTask::Exec(opt);
164
165   PostData(1+kClusterResidual, fClResiduals);
166   PostData(1+kTrackletYResidual, fTrkltResiduals);
167   PostData(1+kTrackletPhiResidual, fTrkltPhiResiduals);
168   PostData(1+kClusterResolution, fClResolution);
169   PostData(1+kTrackletYResolution, fTrkltResolution);
170 }
171
172 //________________________________________________________
173 TH1* AliTRDtrackingResolution::PlotClusterResiduals(const AliTRDtrackV1 *track)
174 {
175   if(track) fTrack = track;
176   if(!fTrack){
177     AliWarning("No Track defined.");
178     return 0x0;
179   }
180   TH1 *h = 0x0;
181   if(!(h = ((TH2I*)fContainer->At(kClusterResidual)))){
182     AliWarning("No output histogram defined.");
183     return 0x0;
184   }
185
186   Float_t x0, y0, z0, dy, dydx, dzdx;
187   AliTRDseedV1 *fTracklet = 0x0;  
188   for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
189     if(!(fTracklet = fTrack->GetTracklet(ily))) continue;
190     if(!fTracklet->IsOK()) continue;
191     x0 = fTracklet->GetX0();
192
193     // retrive the track angle with the chamber
194     y0   = fTracklet->GetYref(0);
195     z0   = fTracklet->GetZref(0);
196     dydx = fTracklet->GetYref(1);
197     dzdx = fTracklet->GetZref(1);
198     Float_t tilt = fTracklet->GetTilt();
199     AliTRDcluster *c = 0x0;
200     fTracklet->ResetClusterIter(kFALSE);
201     while((c = fTracklet->PrevCluster())){
202       Float_t xc = c->GetX();
203       Float_t yc = c->GetY();
204       Float_t zc = c->GetZ();
205       Float_t dx = x0 - xc; 
206       Float_t yt = y0 - dx*dydx;
207       Float_t zt = z0 - dx*dzdx; 
208       dy = yt - (yc - tilt*(zc-zt));
209
210       //dy = trklt.GetYat(c->GetX()) - c->GetY();
211       h->Fill(dydx, dy);
212   
213       if(fDebugLevel>=1){
214         // Get z-position with respect to anode wire
215         AliTRDSimParam    *simParam    = AliTRDSimParam::Instance();
216         Int_t istk = fGeo->GetStack(c->GetDetector());
217         AliTRDpadPlane *pp = fGeo->GetPadPlane(ily, istk);
218         Float_t row0 = pp->GetRow0();
219         Float_t d  =  row0 - zt + simParam->GetAnodeWireOffset();
220         d -= ((Int_t)(2 * d)) / 2.0;
221         if (d > 0.25) d  = 0.5 - d;
222
223 /*        AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
224         fClResiduals->Add(clInfo);
225         clInfo->SetCluster(c);
226         clInfo->SetGlobalPosition(yt, zt, dydx, dzdx);
227         clInfo->SetResolution(dy);
228         clInfo->SetAnisochronity(d);
229         clInfo->SetDriftLength(dx);
230         (*fDebugStream) << "ClusterResiduals"
231           <<"clInfo.=" << clInfo
232           << "\n";*/
233       }
234     }
235   }
236   return h;
237 }
238
239
240 //________________________________________________________
241 TH1* AliTRDtrackingResolution::PlotTrackletResiduals(const AliTRDtrackV1 *track)
242 {
243   if(track) fTrack = track;
244   if(!fTrack){
245     AliWarning("No Track defined.");
246     return 0x0;
247   }
248   TH1 *h = 0x0;
249   if(!(h = ((TH2I*)fContainer->At(kTrackletYResidual)))){
250     AliWarning("No output histogram defined.");
251     return 0x0;
252   }
253
254   AliTRDseedV1 *tracklet = 0x0;
255   for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
256     if(!(tracklet = fTrack->GetTracklet(il))) continue;
257     if(!tracklet->IsOK()) continue;
258     h->Fill(tracklet->GetYref(1), tracklet->GetYref(0)-tracklet->GetYfit(0));
259   }
260   return h;
261
262   // refit the track
263 //   AliRieman fRim(fTrack->GetNumberOfClusters());
264 //   Float_t x[AliTRDgeometry::kNlayer] = {-1., -1., -1., -1., -1., -1.}, y[AliTRDgeometry::kNlayer], dydx[AliTRDgeometry::kNlayer];
265
266 //     AliTRDcluster *c = 0x0;
267 //     tracklet->ResetClusterIter(kFALSE);
268 //     while((c = tracklet->PrevCluster())){
269 //       Float_t xc = c->GetX();
270 //       Float_t yc = c->GetY();
271 //       Float_t zc = c->GetZ();
272 //       Float_t zt = tracklet->GetZref(0) - (tracklet->GetX0()-xc)*tracklet->GetZref(1); 
273 //       yc -= tracklet->GetTilt()*(zc-zt);
274 //       fRim.AddPoint(xc, yc, zc, 1, 10);
275 //     }
276 //     tracklet->Fit(kTRUE);
277 // 
278 //     x[il] = tracklet->GetX0();
279 //     y[il] = tracklet->GetYfit(0)-tracklet->GetYfit(1)*(tracklet->GetX0()-x[il]);
280 //     dydx[il] = tracklet->GetYref(1);
281
282
283 //   fRim.Update();
284
285 //   for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
286 //     if(x[il] < 0.) continue;
287 //     Float_t dy = y[il]-fRim.GetYat(x[il])/*/sigma_track*/;
288 //     h->Fill(dydx[il], dy);
289 // 
290 //     if(fDebugLevel>=1){
291 //       Double_t sigmay = fRim.GetErrY(x[il]);
292 //       Float_t yt = fRim.GetYat(x[il]);
293 //       (*fDebugStream) << "TrkltResiduals"
294 //         << "layer="  << il
295 //         << "x="      << x[il]
296 //         << "y="      << y[il]
297 //         << "yt="     << yt
298 //         << "dydx="   << dydx[il]
299 //         << "dy="     << dy
300 //         << "sigmay=" << sigmay
301 //         << "\n";
302 //     }
303 //   }
304 }
305
306 //________________________________________________________
307 TH1* AliTRDtrackingResolution::PlotTrackletPhiResiduals(const AliTRDtrackV1 *track)
308 {
309   if(track) fTrack = track;
310   if(!fTrack){
311     AliWarning("No Track defined.");
312     return 0x0;
313   }
314   TH1 *h = 0x0;
315   if(!(h = ((TH2I*)fContainer->At(kTrackletPhiResidual)))){
316     AliWarning("No output histogram defined.");
317     return 0x0;
318   }
319
320   AliTRDseedV1 *tracklet = 0x0;
321   for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
322     if(!(tracklet = fTrack->GetTracklet(il))) continue;
323     if(!tracklet->IsOK()) continue;
324     h->Fill(tracklet->GetYref(1), TMath::ATan(tracklet->GetYref(1))-TMath::ATan(tracklet->GetYfit(1)));
325   }
326   return h;
327
328 //   // refit the track
329 //   AliRieman fRim(fTrack->GetNumberOfClusters());
330 //   Float_t x[AliTRDgeometry::kNlayer] = {-1., -1., -1., -1., -1., -1.}, y[AliTRDgeometry::kNlayer], dydx[AliTRDgeometry::kNlayer];
331 //   Float_t dydx_ref=0, dydx_fit=0, phiref=0, phifit=0, phidiff=0;
332 //   AliTRDseedV1 *tracklet = 0x0;
333 //   for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
334 //     if(!(tracklet = fTrack->GetTracklet(il))) continue;
335 //     if(!tracklet->IsOK()) continue;
336 //     AliTRDcluster *c = 0x0;
337 //     tracklet->ResetClusterIter(kFALSE);
338 //     while((c = tracklet->PrevCluster())){
339 //       Float_t xc = c->GetX();
340 //       Float_t yc = c->GetY();
341 //       Float_t zc = c->GetZ();
342 //       Float_t zt = tracklet->GetZref(0) - (tracklet->GetX0()-xc)*tracklet->GetZref(1); 
343 //       yc -= tracklet->GetTilt()*(zc-zt);
344 //       fRim.AddPoint(xc, yc, zc, 1, 10);
345 //     }
346 //     tracklet->Fit(kTRUE);
347 // 
348 //     x[il] = tracklet->GetX0();
349 //     y[il] = tracklet->GetYfit(0)-tracklet->GetYfit(1)*(tracklet->GetX0()-x[il]);
350 //     dydx[il] = tracklet->GetYref(1);
351 //   }
352 //   fRim.Update();
353 // 
354 //   for(Int_t il=0; il<AliTRDgeometry::kNlayer; il++){
355 //     if(x[il] < 0.) continue;
356 //     if(!(tracklet = fTrack->GetTracklet(il))) continue;
357 //     if(!tracklet->IsOK()) continue;
358 // 
359 //     dydx_ref = fRim.GetDYat(x[il]); 
360 //     dydx_fit = tracklet->GetYfit(1);
361 // 
362 //     phiref = TMath::ATan(dydx_ref);//*TMath::RadToDeg();
363 //     phifit = TMath::ATan(dydx_fit);//*TMath::RadToDeg();
364 //     
365 //     phidiff = phiref-phifit; /*/sigma_phi*/;
366 // 
367 //     h->Fill(dydx_ref, phidiff);
368 // 
369 // 
370 //     if(fDebugLevel>=1){
371 //       (*fDebugStream) << "TrkltPhiResiduals"
372 //         << "layer="  << il
373 //         << "dydx_fit="   << dydx_fit
374 //         << "dydx_ref="   << dydx_ref
375 //         << "phiref="     << phiref
376 //         << "phifit="     << phifit
377 //         << "phidiff="     << phidiff
378 //         << "\n";
379 //     }
380 //   }
381 }
382
383
384 //________________________________________________________
385 TH1* AliTRDtrackingResolution::PlotResolution(const AliTRDtrackV1 *track)
386 {
387   if(!HasMCdata()){ 
388     AliWarning("No MC defined. Results will not be available.");
389     return 0x0;
390   }
391   if(track) fTrack = track;
392   if(!fTrack){
393     AliWarning("No Track defined.");
394     return 0x0;
395   }
396   TH1 *h = 0x0;
397   if(!(h = ((TH2I*)fContainer->At(kClusterResolution)))){
398     AliWarning("No output histogram defined.");
399     return 0x0;
400   }
401   if(!(h = ((TH2I*)fContainer->At(kTrackletYResolution)))){
402     AliWarning("No output histogram defined.");
403     return 0x0;
404   }
405   if(!(h = ((TH2I*)fContainer->At(kTrackletZResolution)))){
406     AliWarning("No output histogram defined.");
407     return 0x0;
408   }
409   if(!(h = ((TH2I*)fContainer->At(kTrackletAngleResolution)))){
410     AliWarning("No output histogram defined.");
411     return 0x0;
412   }
413   //printf("called for %d tracklets ... \n", fTrack->GetNumberOfTracklets());
414   UChar_t s;
415   Int_t pdg = fMC->GetPDG(), det=-1;
416   Int_t label = fMC->GetLabel();
417   Float_t x0, y0, z0, dx, dy, dydx, dzdx;
418   AliTRDseedV1 *fTracklet = 0x0;  
419   for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){
420     if(!(fTracklet = fTrack->GetTracklet(ily))) continue;
421     if(!fTracklet->IsOK()) continue;
422     //printf("process layer[%d]\n", ily);
423     // retrive the track position and direction within the chamber
424     det = fTracklet->GetDetector();
425     x0  = fTracklet->GetX0();
426     dx = 0.;//radial shift with respect to the MC reference (radial position of the pad plane)
427     if(!fMC->GetDirections(x0, y0, z0, dydx, dzdx, s)) continue; 
428     Float_t yt = y0 - dx*dydx;
429     Float_t zt = z0 - dx*dzdx;
430
431     // calculate position of Kalman fit at reference radial position
432     Float_t yr = fTracklet->GetYref(0) - (fTracklet->GetX0() - x0 + dx)*dydx;
433     Float_t zr = fTracklet->GetZref(0) - (fTracklet->GetX0() - x0 + dx)*dzdx;
434     // Fill Histograms
435     ((TH2I*)fContainer->At(kTrackYResolution))->Fill(dydx, yt-yr);
436     ((TH2I*)fContainer->At(kTrackZResolution))->Fill(dzdx, zt-zr);
437
438
439     // recalculate tracklet based on the MC info
440     AliTRDseedV1 tt(*fTracklet);
441     tt.SetZref(0, z0);
442     tt.SetZref(1, dzdx); 
443     if(!tt.Fit(kTRUE)) continue;
444     //tt.Update();
445
446     Float_t yf = tt.GetYfit(0) - (fTracklet->GetX0() - x0 + dx)*dydx;
447     dy = yf-yt;
448     Float_t dphi   = TMath::ATan(tt.GetYfit(1)) - TMath::ATan(dydx);
449     Float_t dz = 100.;
450     Bool_t  cross = fTracklet->GetNChange();
451     if(cross){
452       Double_t *xyz = tt.GetCrossXYZ();
453       dz = xyz[2] - (z0 - (x0 - xyz[0])*dzdx) ;
454       ((TH2I*)fContainer->At(kTrackletZResolution))->Fill(dzdx, dz);
455     }
456   
457     // Fill Histograms
458     ((TH2I*)fContainer->At(kTrackletYResolution))->Fill(dydx, dy);
459     ((TH2I*)fContainer->At(kTrackletAngleResolution))->Fill(dydx, dphi*TMath::RadToDeg());
460
461     // Fill Debug stream
462     if(fDebugLevel>=1){
463       Float_t p = fMC->GetTrackRef() ? fMC->GetTrackRef()->P() : -1.;
464       (*fDebugStream) << "TrkltResolution"
465         << "det="                 << det
466         << "pdg="     << pdg
467         << "p="       << p
468         << "ymc="     << y0
469         << "zmc="     << z0
470         << "dydx="    << dydx
471         << "dzdx="    << dzdx
472         << "cross="   << cross
473         << "dy="                  << dy
474         << "dz="                  << dz
475         << "dphi="              << dphi
476         << "\n";
477     }
478
479     Int_t istk = AliTRDgeometry::GetStack(det); 
480     AliTRDpadPlane *pp = fGeo->GetPadPlane(ily, istk);
481     Float_t zr0 = pp->GetRow0() + AliTRDSimParam::Instance()->GetAnodeWireOffset();
482     Float_t tilt = fTracklet->GetTilt();
483
484     Double_t x,y;
485     AliTRDcluster *c = 0x0;
486     fTracklet->ResetClusterIter(kFALSE);
487     while((c = fTracklet->PrevCluster())){
488       Float_t  q = TMath::Abs(c->GetQ());
489       AliTRDseedV1::GetClusterXY(c,x,y);
490       Float_t xc = x;
491       Float_t yc = y;
492       Float_t zc = c->GetZ();
493       dx = x0 - xc; 
494       Float_t yt = y0 - dx*dydx;
495       Float_t zt = z0 - dx*dzdx; 
496       dy = yt - (yc - tilt*(zc-zt));
497
498       // Fill Histograms
499       if(q>20. && q<250.) ((TH2I*)fContainer->At(kClusterResolution))->Fill(dydx, dy);
500       
501       // Fill Debug Tree
502       if(fDebugLevel>=1){
503         Float_t d = zr0 - zt;
504         d -= ((Int_t)(2 * d)) / 2.0;
505         if (d > 0.25) d  = 0.5 - d;
506
507         AliTRDclusterInfo *clInfo = new AliTRDclusterInfo;
508         fClResolution->Add(clInfo);
509         clInfo->SetCluster(c);
510         clInfo->SetMC(pdg, label);
511         clInfo->SetGlobalPosition(yt, zt, dydx, dzdx);
512         clInfo->SetResolution(dy);
513         clInfo->SetAnisochronity(d);
514         clInfo->SetDriftLength(dx);
515         clInfo->SetTilt(tilt);
516         //clInfo->Print();
517         (*fDebugStream) << "ClusterResolution"
518           <<"clInfo.=" << clInfo
519           << "\n";
520       }
521     }
522   }
523   return h;
524 }
525
526
527 //________________________________________________________
528 Bool_t AliTRDtrackingResolution::GetRefFigure(Int_t ifig)
529 {
530   TBox *b = 0x0;
531   TAxis *ax = 0x0;
532   TGraphErrors *g = 0x0;
533   switch(ifig){
534   case kClusterResidual:
535     if(!(g = (TGraphErrors*)fGraphS->At(ifig))) break;
536     g->Draw("apl");
537     ax = g->GetHistogram()->GetYaxis();
538     ax->SetRangeUser(-.5, 2.5);
539     ax->SetTitle("Clusters Y Residuals #sigma/#mu [mm]");
540     ax = g->GetHistogram()->GetXaxis();
541     ax->SetTitle("tg(#phi)");
542     if(!(g = (TGraphErrors*)fGraphM->At(ifig))) break;
543     g->Draw("pl");
544     b = new TBox(-.15, -.5, .15, 1.);
545     b->SetFillStyle(3002);b->SetFillColor(kGreen);
546     b->SetLineColor(0); b->Draw();
547     return kTRUE;
548   case kTrackletYResidual:
549     if(!(g = (TGraphErrors*)fGraphS->At(ifig))) break;
550     g->Draw("apl");
551     ax = g->GetHistogram()->GetYaxis();
552     ax->SetRangeUser(-.5, 3.);
553     ax->SetTitle("Tracklet Y Residuals #sigma/#mu [mm]");
554     ax = g->GetHistogram()->GetXaxis();
555     ax->SetTitle("tg(#phi)");
556     if(!(g = (TGraphErrors*)fGraphM->At(ifig))) break;
557     g->Draw("pl");
558     b = new TBox(-.15, -.5, .15, 1.);
559     b->SetFillStyle(3002);b->SetFillColor(kGreen);
560     b->SetLineColor(0); b->Draw();
561     return kTRUE;
562   case kTrackletPhiResidual:
563     if(!(g = (TGraphErrors*)fGraphS->At(ifig))) break;
564     g->Draw("apl");
565     ax = g->GetHistogram()->GetYaxis();
566     ax->SetRangeUser(-.5, 2.);
567     ax->SetTitle("Tracklet Phi Residuals #sigma/#mu [rad]");
568     ax = g->GetHistogram()->GetXaxis();
569     ax->SetTitle("tg(#phi)");
570     if(!(g = (TGraphErrors*)fGraphM->At(ifig))) break;
571     g->Draw("pl");
572     b = new TBox(-.15, -.5, .15, 1.);
573     b->SetFillStyle(3002);b->SetFillColor(kGreen);
574     b->SetLineColor(0); b->Draw();
575     return kTRUE;
576   case kClusterResolution:
577     if(!(g = (TGraphErrors*)fGraphS->At(ifig))) break;
578     ax = g->GetHistogram()->GetYaxis();
579     ax->SetRangeUser(-.5, 1.);
580     ax->SetTitle("Cluster Y Resolution #sigma/#mu [mm]");
581     ax = g->GetHistogram()->GetXaxis();
582     ax->SetTitle("tg(#phi)");
583     g->Draw("apl");
584     if(!(g = (TGraphErrors*)fGraphM->At(ifig))) break;
585     g->Draw("pl");
586     b = new TBox(-.15, -.5, .15, 1.);
587     b->SetFillStyle(3002);b->SetFillColor(kGreen);
588     b->SetLineColor(0); b->Draw();
589     return kTRUE;
590   case kTrackletYResolution:
591     if(!(g = (TGraphErrors*)fGraphS->At(ifig))) break;
592     ax = g->GetHistogram()->GetYaxis();
593     ax->SetRangeUser(-.5, 1.);
594     ax->SetTitle("Tracklet Y Resolution #sigma/#mu [mm]");
595     ax = g->GetHistogram()->GetXaxis();
596     ax->SetTitle("tg(#phi)");
597     g->Draw("apl");
598     if(!(g = (TGraphErrors*)fGraphM->At(ifig))) break;
599     g->Draw("pl");
600     return kTRUE;
601   case kTrackletZResolution:
602     if(!(g = (TGraphErrors*)fGraphS->At(ifig))) break;
603     ax = g->GetHistogram()->GetYaxis();
604     ax->SetRangeUser(-.5, 1.);
605     ax->SetTitle("Tracklet Z Resolution #sigma/#mu [mm]");
606     ax = g->GetHistogram()->GetXaxis();
607     ax->SetTitle("tg(#theta)");
608     g->Draw("apl");
609     if(!(g = (TGraphErrors*)fGraphM->At(ifig))) break;
610     g->Draw("pl");
611     return kTRUE;
612   case kTrackletAngleResolution:
613     if(!(g = (TGraphErrors*)fGraphS->At(ifig))) break;
614     ax = g->GetHistogram()->GetYaxis();
615     ax->SetRangeUser(-.05, .2);
616     ax->SetTitle("Tracklet Angular Resolution #sigma/#mu [deg]");
617     ax = g->GetHistogram()->GetXaxis();
618     ax->SetTitle("tg(#phi)");
619     g->Draw("apl");
620     if(!(g = (TGraphErrors*)fGraphM->At(ifig))) break;
621     g->Draw("pl");
622     return kTRUE;
623   case kTrackYResolution:
624     return kTRUE;
625   case kTrackZResolution:
626     return kTRUE;
627   default:
628     AliInfo(Form("Reference plot [%d] not implemented yet", ifig));
629     return kFALSE;
630   }
631   AliInfo(Form("Reference plot [%d] missing result", ifig));
632   return kFALSE;
633 }
634
635
636 //________________________________________________________
637 Bool_t AliTRDtrackingResolution::PostProcess()
638 {
639   //fContainer = dynamic_cast<TObjArray*>(GetOutputData(0));
640   if (!fContainer) {
641     Printf("ERROR: list not available");
642     return kFALSE;
643   }
644   fNRefFigures = fContainer->GetEntriesFast();
645   if(!fGraphS){ 
646     fGraphS = new TObjArray(fNRefFigures);
647     fGraphS->SetOwner();
648   }
649   if(!fGraphM){ 
650     fGraphM = new TObjArray(fNRefFigures);
651     fGraphM->SetOwner();
652   }
653
654   TH2I *h2 = 0x0;
655   TH1D *h = 0x0;
656   TGraphErrors *gm = 0x0, *gs = 0x0;
657
658   // define models
659   TF1 f("f1", "gaus", -.5, .5);  
660
661   TF1 fb("fb", "[0]*exp(-0.5*((x-[1])/[2])**2)+[3]", -.5, .5);
662
663   TF1 fc("fc", "[0]*exp(-0.5*((x-[1])/[2])**2)+[3]*exp(-0.5*((x-[4])/[5])**2)", -.5, .5);
664
665   TCanvas *c = 0x0;
666   if(IsVisual()) c = new TCanvas("c", Form("%s Visual", GetName()), 500, 500);
667   char opt[5];
668   sprintf(opt, "%c%c", IsVerbose() ? ' ' : 'Q', IsVisual() ? ' ': 'N');
669
670
671   //PROCESS RESIDUAL DISTRIBUTIONS
672
673   // Clusters residuals
674   h2 = (TH2I *)(fContainer->At(kClusterResidual));
675   gm = new TGraphErrors();
676   gm->SetLineColor(kBlue);
677   gm->SetMarkerStyle(7);
678   gm->SetMarkerColor(kBlue);
679   gm->SetNameTitle("clm", "");
680   fGraphM->AddAt(gm, kClusterResidual);
681   gs = new TGraphErrors();
682   gs->SetLineColor(kRed);
683   gs->SetMarkerStyle(23);
684   gs->SetMarkerColor(kRed);
685   gs->SetNameTitle("cls", "");
686   fGraphS->AddAt(gs, kClusterResidual);
687   for(Int_t ibin = 1; ibin <= h2->GetNbinsX(); ibin++){
688     Double_t phi = h2->GetXaxis()->GetBinCenter(ibin);
689     h = h2->ProjectionY("py", ibin, ibin);
690     if(h->GetEntries()<100) continue;
691     AdjustF1(h, &f);
692
693     if(IsVisual()){c->cd(); c->SetLogy();}
694     h->Fit(&f, opt, "", -0.5, 0.5);
695     if(IsVisual()){c->Modified(); c->Update(); gSystem->Sleep(500);}
696     
697     Int_t ip = gm->GetN();
698     gm->SetPoint(ip, phi, 10.*f.GetParameter(1));
699     gm->SetPointError(ip, 0., 10.*f.GetParError(1));
700     gs->SetPoint(ip, phi, 10.*f.GetParameter(2));
701     gs->SetPointError(ip, 0., 10.*f.GetParError(2));
702   }
703
704   // Tracklet y residuals
705   h2 = (TH2I *)(fContainer->At(kTrackletYResidual));
706   gm = new TGraphErrors();
707   gm->SetLineColor(kBlue);
708   gm->SetMarkerStyle(7);
709   gm->SetMarkerColor(kBlue);
710   gm->SetNameTitle("tktm", "");
711   fGraphM->AddAt(gm, kTrackletYResidual);
712   gs = new TGraphErrors();
713   gs->SetLineColor(kRed);
714   gs->SetMarkerStyle(23);
715   gs->SetMarkerColor(kRed);
716   gs->SetNameTitle("tkts", "");
717   fGraphS->AddAt(gs, kTrackletYResidual);
718   for(Int_t ibin = 1; ibin <= h2->GetNbinsX(); ibin++){
719     Double_t phi = h2->GetXaxis()->GetBinCenter(ibin);
720     h = h2->ProjectionY("py", ibin, ibin);
721     if(h->GetEntries()<100) continue;
722     AdjustF1(h, &f);
723
724     if(IsVisual()){c->cd(); c->SetLogy();}
725     h->Fit(&f, opt, "", -0.5, 0.5);
726     if(IsVisual()){c->Modified(); c->Update(); gSystem->Sleep(500);}
727     
728     Int_t ip = gm->GetN();
729     gm->SetPoint(ip, phi, 10.*f.GetParameter(1));
730     gm->SetPointError(ip, 0., 10.*f.GetParError(1));
731     gs->SetPoint(ip, phi, 10.*f.GetParameter(2));
732     gs->SetPointError(ip, 0., 10.*f.GetParError(2));
733   }
734
735   // Tracklet phi residuals
736   h2 = (TH2I *)(fContainer->At(kTrackletPhiResidual));
737   gm = new TGraphErrors();
738   gm->SetLineColor(kBlue);
739   gm->SetMarkerStyle(7);
740   gm->SetMarkerColor(kBlue);
741   gm->SetNameTitle("tktphim", "");
742   fGraphM->AddAt(gm, kTrackletPhiResidual);
743   gs = new TGraphErrors();
744   gs->SetLineColor(kRed);
745   gs->SetMarkerStyle(23);
746   gs->SetMarkerColor(kRed);
747   gs->SetNameTitle("tktphis", "");
748   fGraphS->AddAt(gs, kTrackletPhiResidual);
749   for(Int_t ibin = 1; ibin <= h2->GetNbinsX(); ibin++){
750     Double_t phi = h2->GetXaxis()->GetBinCenter(ibin);
751     h = h2->ProjectionY("py", ibin, ibin);
752     if(h->GetEntries()<100) continue;
753     AdjustF1(h, &f);
754
755     if(IsVisual()){c->cd(); c->SetLogy();}
756     h->Fit(&f, opt, "", -0.5, 0.5);
757     if(IsVisual()){c->Modified(); c->Update(); gSystem->Sleep(500);}
758     
759     Int_t ip = gm->GetN();
760     gm->SetPoint(ip, phi, 10.*f.GetParameter(1));
761     gm->SetPointError(ip, 0., 10.*f.GetParError(1));
762     gs->SetPoint(ip, phi, 10.*f.GetParameter(2));
763     gs->SetPointError(ip, 0., 10.*f.GetParError(2));
764   }
765
766
767   //PROCESS RESOLUTION DISTRIBUTIONS
768
769   if(HasMCdata()){
770     // cluster y resolution
771     h2 = (TH2I*)fContainer->At(kClusterResolution);
772     gm = new TGraphErrors();
773     gm->SetLineColor(kBlue);
774     gm->SetMarkerStyle(7);
775     gm->SetMarkerColor(kBlue);
776     gm->SetNameTitle("clym", "");
777     fGraphM->AddAt(gm, kClusterResolution);
778     gs = new TGraphErrors();
779     gs->SetLineColor(kRed);
780     gs->SetMarkerStyle(23);
781     gs->SetMarkerColor(kRed);
782     gs->SetNameTitle("clys", "");
783     fGraphS->AddAt(gs, kClusterResolution);
784     for(Int_t iphi=1; iphi<=h2->GetNbinsX(); iphi++){
785       h = h2->ProjectionY("py", iphi, iphi);
786       if(h->GetEntries()<100) continue;
787       AdjustF1(h, &f);
788
789       if(IsVisual()){c->cd(); c->SetLogy();}
790       h->Fit(&f, opt, "", -0.5, 0.5);
791       if(IsVerbose()){
792         printf("phi[%d] mean[%e] sigma[%e]\n\n", iphi, 10.*f.GetParameter(1), 10.*f.GetParameter(2));
793       }
794       if(IsVisual()){c->Modified(); c->Update(); gSystem->Sleep(500);}
795
796       Double_t phi = h2->GetXaxis()->GetBinCenter(iphi);
797       Int_t ip = gm->GetN();
798       gm->SetPoint(ip, phi, 10.*f.GetParameter(1));
799       gm->SetPointError(ip, 0., 10.*f.GetParError(1));
800       gs->SetPoint(ip, phi, 10.*f.GetParameter(2));
801       gs->SetPointError(ip, 0., 10.*f.GetParError(2));
802     }
803   
804     // tracklet y resolution
805     h2 = (TH2I*)fContainer->At(kTrackletYResolution);
806     gm = new TGraphErrors();
807     gm->SetLineColor(kBlue);
808     gm->SetMarkerStyle(7);
809     gm->SetMarkerColor(kBlue);
810     gm->SetNameTitle("trkltym", "");
811     fGraphM->AddAt(gm, kTrackletYResolution);
812     gs = new TGraphErrors();
813     gs->SetLineColor(kRed);
814     gs->SetMarkerStyle(23);
815     gs->SetMarkerColor(kRed);
816     gs->SetNameTitle("trkltys", "");
817     fGraphS->AddAt(gs, kTrackletYResolution);
818     for(Int_t iphi=1; iphi<=h2->GetNbinsX(); iphi++){
819       h = h2->ProjectionY("py", iphi, iphi);
820       if(h->GetEntries()<100) continue;
821       AdjustF1(h, &f);
822
823       if(IsVisual()){c->cd(); c->SetLogy();}
824       h->Fit(&f, opt, "", -0.5, 0.5);
825       if(IsVisual()){c->Modified(); c->Update(); gSystem->Sleep(500);}
826
827       Double_t phi = h2->GetXaxis()->GetBinCenter(iphi);
828       Int_t ip = gm->GetN();
829       gm->SetPoint(ip, phi, 10.*f.GetParameter(1));
830       gm->SetPointError(ip, 0., 10.*f.GetParError(1));
831       gs->SetPoint(ip, phi, 10.*f.GetParameter(2));
832       gs->SetPointError(ip, 0., 10.*f.GetParError(2));
833     }
834   
835     // tracklet z resolution
836     h2 = (TH2I*)fContainer->At(kTrackletZResolution);
837     gm = new TGraphErrors();
838     gm->SetLineColor(kBlue);
839     gm->SetMarkerStyle(7);
840     gm->SetMarkerColor(kBlue);
841     gm->SetNameTitle("trkltzm", "");
842     fGraphM->AddAt(gm, kTrackletZResolution);
843     gs = new TGraphErrors();
844     gs->SetLineColor(kRed);
845     gs->SetMarkerStyle(23);
846     gs->SetMarkerColor(kRed);
847     gs->SetNameTitle("trkltzs", "");
848     fGraphS->AddAt(gs, kTrackletZResolution);
849     for(Int_t iphi=1; iphi<=h2->GetNbinsX(); iphi++){
850       h = h2->ProjectionY("py", iphi, iphi);
851       if(h->GetEntries()<100) continue;
852       AdjustF1(h, &fb);
853
854       if(IsVisual()){c->cd(); c->SetLogy();}
855       h->Fit(&fb, opt, "", -0.5, 0.5);
856       if(IsVisual()){c->Modified(); c->Update(); gSystem->Sleep(500);}
857
858       Double_t phi = h2->GetXaxis()->GetBinCenter(iphi);
859       Int_t ip = gm->GetN();
860       gm->SetPoint(ip, phi, 10.*fb.GetParameter(1));
861       gm->SetPointError(ip, 0., 10.*fb.GetParError(1));
862       gs->SetPoint(ip, phi, 10.*fb.GetParameter(2));
863       gs->SetPointError(ip, 0., 10.*fb.GetParError(2));
864     }
865   
866     //tracklet phi resolution
867     h2 = (TH2I*)fContainer->At(kTrackletAngleResolution);
868     gm = new TGraphErrors();
869     gm->SetLineColor(kBlue);
870     gm->SetMarkerStyle(7);
871     gm->SetMarkerColor(kBlue);
872     gm->SetNameTitle("trkltym", "");
873     fGraphM->AddAt(gm, kTrackletAngleResolution);
874     gs = new TGraphErrors();
875     gs->SetLineColor(kRed);
876     gs->SetMarkerStyle(23);
877     gs->SetMarkerColor(kRed);
878     gs->SetNameTitle("trkltys", "");
879     fGraphS->AddAt(gs, kTrackletAngleResolution);
880     for(Int_t iphi=1; iphi<=h2->GetNbinsX(); iphi++){
881       h = h2->ProjectionY("py", iphi, iphi);
882       if(h->GetEntries()<100) continue;
883
884       if(IsVisual()){c->cd(); c->SetLogy();}
885       h->Fit(&f, opt, "", -0.5, 0.5);
886       if(IsVisual()){c->Modified(); c->Update(); gSystem->Sleep(500);}
887
888       Double_t phi = h2->GetXaxis()->GetBinCenter(iphi);
889       Int_t ip = gm->GetN();
890       gm->SetPoint(ip, phi, f.GetParameter(1));
891       gm->SetPointError(ip, 0., f.GetParError(1));
892       gs->SetPoint(ip, phi, f.GetParameter(2));
893       gs->SetPointError(ip, 0., f.GetParError(2));
894     }
895   }
896   if(c) delete c;
897
898   return kTRUE;
899 }
900
901
902 //________________________________________________________
903 void AliTRDtrackingResolution::Terminate(Option_t *)
904 {
905   if(fDebugStream){ 
906     delete fDebugStream;
907     fDebugStream = 0x0;
908     fDebugLevel = 0;
909   }
910   if(HasPostProcess()) PostProcess();
911 }
912
913 //________________________________________________________
914 void AliTRDtrackingResolution::AdjustF1(TH1 *h, TF1 *f)
915 {
916 // Helper function to avoid duplication of code
917 // Make first guesses on the fit parameters
918
919   // find the intial parameters of the fit !! (thanks George)
920   Int_t nbinsy = Int_t(.5*h->GetNbinsX());
921   Double_t sum = 0.;
922   for(Int_t jbin=nbinsy-4; jbin<=nbinsy+4; jbin++) sum+=h->GetBinContent(jbin); sum/=9.;
923   f->SetParLimits(0, 0., 3.*sum);
924   f->SetParameter(0, .9*sum);
925
926   f->SetParLimits(1, -.2, .2);
927   f->SetParameter(1, -0.1);
928
929   f->SetParLimits(2, 0., 4.e-1);
930   f->SetParameter(2, 2.e-2);
931   if(f->GetNpar() <= 4) return;
932
933   f->SetParLimits(3, 0., sum);
934   f->SetParameter(3, .1*sum);
935
936   f->SetParLimits(4, -.3, .3);
937   f->SetParameter(4, 0.);
938
939   f->SetParLimits(5, 0., 1.e2);
940   f->SetParameter(5, 2.e-1);
941 }
942
943 //________________________________________________________
944 TObjArray* AliTRDtrackingResolution::Histos()
945 {
946   if(fContainer) return fContainer;
947
948   fContainer  = new TObjArray(9);
949   //fContainer->SetOwner(kTRUE);
950
951   TH1 *h = 0x0;
952   // cluster to tracklet residuals [2]
953   if(!(h = (TH2I*)gROOT->FindObject("fYCl"))){
954     h = new TH2I("fYCl", "Clusters Residuals", 21, -.33, .33, 100, -.5, .5);
955     h->GetXaxis()->SetTitle("tg(#phi)");
956     h->GetYaxis()->SetTitle("#Delta y [cm]");
957     h->GetZaxis()->SetTitle("entries");
958   } else h->Reset();
959   fContainer->AddAt(h, kClusterResidual);
960
961   // tracklet to track residuals [2]
962   if(!(h = (TH2I*)gROOT->FindObject("hTrkltYRez"))){ 
963     h = new TH2I("hTrkltYRez", "Tracklets", 21, -.33, .33, 100, -.5, .5);
964     h->GetXaxis()->SetTitle("tg(#phi)");
965     h->GetYaxis()->SetTitle("#Delta y [cm]");
966     h->GetZaxis()->SetTitle("entries");
967   } else h->Reset();
968   fContainer->AddAt(h, kTrackletYResidual);
969
970   // tracklet to track residuals angular [2]
971   if(!(h = (TH2I*)gROOT->FindObject("hTrkltPhiRez"))){ 
972     h = new TH2I("hTrkltPhiRez", "Tracklets", 21, -.33, .33, 100, -.5, .5);
973     h->GetXaxis()->SetTitle("tg(#phi)");
974     h->GetYaxis()->SetTitle("#Delta phi [#circ]");
975     h->GetZaxis()->SetTitle("entries");
976   } else h->Reset();
977   fContainer->AddAt(h, kTrackletPhiResidual);
978
979
980   // Resolution histos
981   if(!HasMCdata()) return fContainer;
982
983   // cluster y resolution [0]
984   if(!(h = (TH2I*)gROOT->FindObject("fYClMC"))){
985     h = new TH2I("fYClMC", "Cluster Resolution", 31, -.48, .48, 100, -.5, .5);
986     h->GetXaxis()->SetTitle("tg(#phi)");
987     h->GetYaxis()->SetTitle("#Delta y [cm]");
988     h->GetZaxis()->SetTitle("entries");
989   } else h->Reset();
990   fContainer->AddAt(h, kClusterResolution);
991
992   // tracklet y resolution [0]
993   if(!(h = (TH2I*)gROOT->FindObject("fYTrkltMC"))){
994     h = new TH2I("fYTrkltMC", "Tracklet Resolution (Y)", 31, -.48, .48, 100, -.5, .5);
995     h->GetXaxis()->SetTitle("tg(#phi)");
996     h->GetYaxis()->SetTitle("#Delta y [cm]");
997     h->GetZaxis()->SetTitle("entries");
998   } else h->Reset();
999   fContainer->AddAt(h, kTrackletYResolution);
1000
1001   // tracklet y resolution [0]
1002   if(!(h = (TH2I*)gROOT->FindObject("fZTrkltMC"))){
1003     h = new TH2I("fZTrkltMC", "Tracklet Resolution (Z)", 31, -.48, .48, 100, -.5, .5);
1004     h->GetXaxis()->SetTitle("tg(#theta)");
1005     h->GetYaxis()->SetTitle("#Delta z [cm]");
1006     h->GetZaxis()->SetTitle("entries");
1007   } else h->Reset();
1008   fContainer->AddAt(h, kTrackletZResolution);
1009
1010   // tracklet angular resolution [1]
1011   if(!(h = (TH2I*)gROOT->FindObject("fPhiTrkltMC"))){
1012     h = new TH2I("fPhiTrkltMC", "Tracklet Resolution (Angular)", 31, -.48, .48, 100, -10., 10.);
1013     h->GetXaxis()->SetTitle("tg(#phi)");
1014     h->GetYaxis()->SetTitle("#Delta #phi [deg]");
1015     h->GetZaxis()->SetTitle("entries");
1016   } else h->Reset();
1017   fContainer->AddAt(h, kTrackletAngleResolution);
1018
1019   // Kalman track y resolution
1020   if(!(h = (TH2I*)gROOT->FindObject("fYTrkMC"))){
1021     h = new TH2I("fYTrkMC", "Kalman Track Resolution (Y)", 31, -.48, .48, 100, -.5, .5);
1022     h->GetXaxis()->SetTitle("tg(#phi)");
1023     h->GetYaxis()->SetTitle("#Delta y [cm]");
1024     h->GetZaxis()->SetTitle("entries");
1025   } else h->Reset();
1026   fContainer->AddAt(h, kTrackYResolution);
1027
1028   // Kalman track Z resolution
1029   if(!(h = (TH2I*)gROOT->FindObject("fZTrkMC"))){
1030     h = new TH2I("fZTrkMC", "Kalman Track Resolution (Z)", 20, -1., 1., 100, -1.5, 1.5);
1031     h->GetXaxis()->SetTitle("tg(#theta)");
1032     h->GetYaxis()->SetTitle("#Delta z [cm]");
1033     h->GetZaxis()->SetTitle("entries");
1034   } else h->Reset();
1035   fContainer->AddAt(h, kTrackZResolution);
1036
1037   return fContainer;
1038 }
1039
1040
1041 //________________________________________________________
1042 void AliTRDtrackingResolution::SetRecoParam(AliTRDrecoParam *r)
1043 {
1044
1045   fReconstructor->SetRecoParam(r);
1046 }