]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWG1/TRD/AliTRDclusterResolution.cxx
trigger names changed (Markus)
[u/mrichter/AliRoot.git] / PWG1 / TRD / AliTRDclusterResolution.cxx
CommitLineData
1ee39b3a 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: AliTRDclusterResolution.cxx */
17
18///////////////////////////////////////////////////////////////////////////////
19// //
20// TRD cluster error parameterization //
21// //
22// This class is designed to produce the reference plots for a detailed study//
23// and parameterization of TRD cluster errors. The following effects are taken//
24// into account : //
25// - dependence with the total charge of the cluster //
26// - dependence with the distance from the center pad. This is monitored
27// for each layer individually since the pad size varies with layer
28// - dependence with the drift length - here the influence of anisochronity
29// and diffusion are searched
30// - dependence with the distance to the anode wire - anisochronity effects
31// - dependence with track angle (for y resolution)
32// The correlation between effects is taken into account.
33//
34// Since magnetic field plays a very important role in the TRD measurement
35// the ExB correction is forced by the setter function SetExB(Int_t). The
36// argument is the detector index, if none is specified all will be
37// considered.
38//
39// Two cases are of big importance.
40// - comparison with MC
41// - comparison with Kalman fit. In this case the covariance matrix of the
42// Kalman fit are needed.
43//
44// The functionalities implemented in this class are based on the storage
45// class AliTRDclusterInfo.
46//
47// The Method
48// ----------
49//
50// The method to disentangle s_y and s_x is based on the relation (see also fig.)
51// BEGIN_LATEX
52// #sigma^{2} = #sigma^{2}_{y} + tg^{2}(#alpha_{L})*#sigma^{2}_{x_{d}} + tg^{2}(#phi-#alpha_{L})*(#sigma^{2}_{x_{d}}+#sigma^{2}_{x_{c}})
53// END_LATEX
54// with
55// BEGIN_LATEX
56// #sigma^{2}_{x_{c}} #approx 0
57// END_LATEX
58// we suppose the chamber is well calibrated for t_{0} and aligned in
59// radial direction.
60//
61// Clusters can be radially shifted due to three causes:
62// - globally shifted - due to residual misalignment/miscalibration(t0)
63// - locally shifted - due to different local drift velocity from the mean
64// - randomly shifted - due to neighboring (radial direction) clusters
65// charge induced by asymmetry of the TRF.
66//
67// We estimate this effects by the relations:
68// BEGIN_LATEX
69// #mu_{y} = tg(#alpha_{L})*#Delta x_{d}(...) + tg(#phi-#alpha_{L})*(#Delta x_{c}(...) + #Delta x_{d}(...))
70// END_LATEX
71// where
72// BEGIN_LATEX
73// #Delta x_{d}(...) = (<v_{d}> + #delta v_{d}(x_{d}, d)) * (t + t^{*}(Q))
74// END_LATEX
75// and we specified explicitely the variation of drift velocity parallel
76// with the track (x_{d}) and perpendicular to it due to anisochronity (d).
77//
78// For estimating the contribution from asymmetry of TRF the following
79// parameterization is being used
80// BEGIN_LATEX
81// t^{*}(Q) = #delta_{0} * #frac{Q_{t+1} - Q_{t-1}}{Q_{t-1} + Q_{t} + Q_{t+1}}
82// END_LATEX
83//
84//
85// Clusters can also be r-phi shifted due to:
86// - wrong PRF or wrong cuts at digits level
87//The following correction is applied :
88// BEGIN_LATEX
89// <#Delta y> = a + b * sin(c*y_{pw})
90// END_LATEX
91
92// The Models
93//
94// Parameterization against total charge
95//
96// Obtained for B=0T at phi=0. All other effects integrated out.
97// BEGIN_LATEX
98// #sigma^{2}_{y}(Q) = #sigma^{2}_{y}(...) + b(#frac{1}{Q} - #frac{1}{Q_{0}})
99// END_LATEX
100// For B diff 0T the error of the average ExB correction error has to be subtracted !!
101//
102// Parameterization Sx
103//
104// The parameterization of the error in the x direction can be written as
105// BEGIN_LATEX
106// #sigma_{x} = #sigma_{x}^{||} + #sigma_{x}^{#perp}
107// END_LATEX
108//
109// where the parallel component is given mainly by the TRF width while
110// the perpendicular component by the anisochronity. The model employed for
111// the parallel is gaus(0)+expo(3) with the following parameters
112// 1 C 5.49018e-01 1.23854e+00 3.84540e-04 -8.21084e-06
113// 2 M 7.82999e-01 6.22531e-01 2.71272e-04 -6.88485e-05
114// 3 S 2.74451e-01 1.13815e+00 2.90667e-04 1.13493e-05
115// 4 E1 2.53596e-01 1.08646e+00 9.95591e-05 -2.11625e-05
116// 5 E2 -2.40078e-02 4.26520e-01 4.67153e-05 -2.35392e-04
117//
118// and perpendicular to the track is pol2 with the parameters
119//
120// Par_0 = 0.190676 +/- 0.41785
121// Par_1 = -3.9269 +/- 7.49862
122// Par_2 = 14.7851 +/- 27.8012
123//
124// Parameterization Sy
125//
126// The parameterization of the error in the y direction along track uses
127// BEGIN_LATEX
128// #sigma_{y}^{||} = #sigma_{y}^{0} -a*exp(1/(x-b))
129// END_LATEX
130//
131// with following values for the parameters:
132// 1 sy0 2.60967e-01 2.99652e-03 7.82902e-06 -1.89636e-04
133// 2 a -7.68941e+00 1.87883e+00 3.84539e-04 9.38268e-07
134// 3 b -3.41160e-01 7.72850e-02 1.63231e-05 2.51602e-05
135//
136//==========================================================================
137// Example how to retrive reference plots from the task
138// void steerClErrParam(Int_t fig=0)
139// {
140// gSystem->Load("libANALYSIS.so");
141// gSystem->Load("libTRDqaRec.so");
142//
143// // initialize DB manager
144// AliCDBManager *cdb = AliCDBManager::Instance();
145// cdb->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
146// cdb->SetRun(0);
147// // initialize magnetic field.
148// AliMagFCheb *field=new AliMagFCheb("Maps","Maps", 2, 1., 10., AliMagFCheb::k5kG);
149// AliTracker::SetFieldMap(field, kTRUE);
150//
151// AliTRDclusterResolution *res = new AliTRDclusterResolution();
152// res->SetMCdata();
153// res->Load("TRD.TaskClErrParam.root");
154// res->SetExB();
155// res->SetVisual();
156// //res->SetSaveAs();
157// res->SetProcessCharge(kFALSE);
158// res->SetProcessCenterPad(kFALSE);
159// //res->SetProcessMean(kFALSE);
160// res->SetProcessSigma(kFALSE);
161// if(!res->PostProcess()) return;
162// new TCanvas;
163// res->GetRefFigure(fig);
164// }
165//
166// Authors: //
167// Alexandru Bercuci <A.Bercuci@gsi.de> //
168////////////////////////////////////////////////////////////////////////////
169
170#include "AliTRDclusterResolution.h"
5468a262 171#include "AliTRDresolution.h"
172#include "AliTRDinfoGen.h"
1ee39b3a 173#include "info/AliTRDclusterInfo.h"
5468a262 174
175#include "AliTRDcalibDB.h"
176#include "Cal/AliTRDCalROC.h"
177#include "Cal/AliTRDCalDet.h"
178#include "AliTRDCommonParam.h"
1ee39b3a 179#include "AliTRDgeometry.h"
801d4d50 180#include "AliTRDpadPlane.h"
1ee39b3a 181#include "AliTRDcluster.h"
5935a6da 182#include "AliTRDseedV1.h"
1ee39b3a 183
801d4d50 184#include "AliESDEvent.h"
1ee39b3a 185#include "AliCDBManager.h"
186
187#include "TROOT.h"
5468a262 188#include "TSystem.h"
189#include "TMath.h"
190#include "TLinearFitter.h"
191#include "TGeoGlobalMagField.h"
192#include <TGeoMatrix.h>
1ee39b3a 193#include "TObjArray.h"
5468a262 194#include "TTree.h"
195#include "TH2I.h"
196#include "TH3S.h"
1ee39b3a 197#include "TAxis.h"
198#include "TF1.h"
5468a262 199#include "TCanvas.h"
1ee39b3a 200#include "TLegend.h"
201#include "TGraphErrors.h"
202#include "TLine.h"
1ee39b3a 203
204ClassImp(AliTRDclusterResolution)
205
206const Float_t AliTRDclusterResolution::fgkTimeBinLength = 1./ AliTRDCommonParam::Instance()->GetSamplingFrequency();
207//_______________________________________________________
f8f46e4d 208AliTRDclusterResolution::AliTRDclusterResolution()
209 : AliTRDrecoTask()
705f8b0a 210 ,fCanvas(NULL)
211 ,fInfo(NULL)
212 ,fResults(NULL)
56f313bd 213 ,fSubTaskMap(0)
214 ,fUseCalib(7)
f8f46e4d 215 ,fDet(-1)
801d4d50 216 ,fCol(-1)
217 ,fRow(-1)
f8f46e4d 218 ,fExB(0.)
bce4b27e 219 ,fDt(0.)
220 ,fDl(0.)
e3147647 221 ,fVdrift(1.5)
5935a6da 222 ,fT0(0.)
e3147647 223 ,fGain(1.)
5468a262 224 ,fXch(0.)
225 ,fZch(0.)
226 ,fH(0.)
563d1b38 227 ,fDyRange(1.3)
f8f46e4d 228 ,fLy(0)
5935a6da 229 ,fT(0.)
f8f46e4d 230 ,fX(0.)
231 ,fY(0.)
232 ,fZ(0.)
233{
234// Constructor
705f8b0a 235 SetNameTitle("ClErrCalib", "Cluster Error Parameterization");
563d1b38 236 memset(fR, 0, 4*sizeof(Float_t));
237 memset(fP, 0, 4*sizeof(Float_t));
f8f46e4d 238}
239
705f8b0a 240//_______________________________________________________
241AliTRDclusterResolution::AliTRDclusterResolution(const char *name)
242 : AliTRDrecoTask(name, "Cluster Error Parameterization")
4226db3e 243 ,fCanvas(NULL)
244 ,fInfo(NULL)
245 ,fResults(NULL)
56f313bd 246 ,fSubTaskMap(0)
247 ,fUseCalib(7)
1ee39b3a 248 ,fDet(-1)
801d4d50 249 ,fCol(-1)
250 ,fRow(-1)
1ee39b3a 251 ,fExB(0.)
bce4b27e 252 ,fDt(0.)
253 ,fDl(0.)
e3147647 254 ,fVdrift(1.5)
5935a6da 255 ,fT0(0.)
e3147647 256 ,fGain(1.)
5468a262 257 ,fXch(0.)
258 ,fZch(0.)
259 ,fH(0.)
563d1b38 260 ,fDyRange(1.3)
1ee39b3a 261 ,fLy(0)
5935a6da 262 ,fT(0.)
1ee39b3a 263 ,fX(0.)
264 ,fY(0.)
265 ,fZ(0.)
266{
267// Constructor
268
269 memset(fR, 0, 4*sizeof(Float_t));
270 memset(fP, 0, 4*sizeof(Float_t));
1ee39b3a 271
272 // By default register all analysis
273 // The user can switch them off in his steering macro
ebc01dc0 274 SetProcess(kYRes);
275 SetProcess(kYSys);
1ee39b3a 276 SetProcess(kMean);
277 SetProcess(kSigm);
278}
279
280//_______________________________________________________
281AliTRDclusterResolution::~AliTRDclusterResolution()
282{
283// Destructor
284
285 if(fCanvas) delete fCanvas;
1ee39b3a 286 if(fResults){
287 fResults->Delete();
288 delete fResults;
289 }
290}
291
1ee39b3a 292//_______________________________________________________
f8f46e4d 293void AliTRDclusterResolution::UserCreateOutputObjects()
1ee39b3a 294{
5468a262 295/* fContainer = Histos();
296 PostData(1, fContainer);*/
1ee39b3a 297}
298
299//_______________________________________________________
300Bool_t AliTRDclusterResolution::GetRefFigure(Int_t ifig)
301{
302// Steering function to retrieve performance plots
303
304 if(!fResults) return kFALSE;
4226db3e 305 TLegend *leg = NULL;
306 TList *l = NULL;
307 TObjArray *arr = NULL;
308 TTree *t = NULL;
309 TH2 *h2 = NULL;TH1 *h1 = NULL;
310 TGraphErrors *gm(NULL), *gs(NULL), *gp(NULL);
1ee39b3a 311 switch(ifig){
ebc01dc0 312 case kYRes:
313 if(!(arr = (TObjArray*)fResults->At(kYRes))) break;
1ee39b3a 314 if(!(gm = (TGraphErrors*)arr->At(0))) break;
315 if(!(gs = (TGraphErrors*)arr->At(1))) break;
316 if(!(gp = (TGraphErrors*)arr->At(2))) break;
5935a6da 317 leg= new TLegend(.7, .7, .9, .95);
318 leg->SetBorderSize(0); leg->SetFillColor(0); leg->SetFillStyle(0);
319 gs->Draw("apl"); leg->AddEntry(gs, "Sigma / Resolution", "pl");
1ee39b3a 320 gs->GetHistogram()->GetYaxis()->SetRangeUser(-50., 700.);
321 gs->GetHistogram()->SetXTitle("Q [a.u.]");
5935a6da 322 gs->GetHistogram()->SetYTitle("y - x tg(#alpha_{L}) [#mum]");
323 gm->Draw("pl");leg->AddEntry(gm, "Mean / Systematics", "pl");
324 gp->Draw("pl");leg->AddEntry(gp, "Abundance / Probability", "pl");
325 leg->Draw();
1ee39b3a 326 return kTRUE;
ebc01dc0 327 case kYSys:
328 if(!(arr = (TObjArray*)fResults->At(kYSys))) break;
1ee39b3a 329 gPad->Divide(2, 1); l = gPad->GetListOfPrimitives();
330 ((TVirtualPad*)l->At(0))->cd();
5935a6da 331 ((TTree*)arr->At(0))->Draw(Form("y:t>>h(%d, -0.5, %f, 51, -.51, .51)",AliTRDseedV1::kNtb, AliTRDseedV1::kNtb-0.5),
1ee39b3a 332 "m[0]*(ly==0&&abs(m[0])<1.e-1)", "colz");
333 ((TVirtualPad*)l->At(1))->cd();
334 leg= new TLegend(.7, .7, .9, .95);
335 leg->SetBorderSize(0); leg->SetFillColor(0); leg->SetFillStyle(0);
336 leg->SetHeader("TRD Plane");
337 for(Int_t il = 1; il<=AliTRDgeometry::kNlayer; il++){
338 if(!(gm = (TGraphErrors*)arr->At(il))) return kFALSE;
339 gm->Draw(il>1?"pc":"apc"); leg->AddEntry(gm, Form("%d", il-1), "pl");
340 if(il>1) continue;
5935a6da 341 gm->GetHistogram()->SetXTitle("t_{drift} [tb]");
1ee39b3a 342 gm->GetHistogram()->SetYTitle("#sigma_{y}(x|cen=0) [#mum]");
343 gm->GetHistogram()->GetYaxis()->SetRangeUser(150., 500.);
344 }
345 leg->Draw();
346 return kTRUE;
347 case kSigm:
348 if(!(t = (TTree*)fResults->At(kSigm))) break;
349 t->Draw("z:t>>h2x(23, 0.1, 2.4, 25, 0., 2.5)","sx*(1)", "lego2fb");
350 h2 = (TH2F*)gROOT->FindObject("h2x");
351 printf(" const Double_t sx[24][25]={\n");
352 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
353 printf(" {");
354 for(Int_t iy=1; iy<h2->GetNbinsY(); iy++){
355 printf("%6.4f ", h2->GetBinContent(ix, iy));
356 }
357 printf("%6.4f},\n", h2->GetBinContent(ix, h2->GetNbinsY()));
358 }
359 printf(" };\n");
360 gPad->Divide(2, 1, 1.e-5, 1.e-5); l = gPad->GetListOfPrimitives();
361 ((TVirtualPad*)l->At(0))->cd();
362 h1 = h2->ProjectionX("hsx_pxx"); h1->Scale(1.e4/kND); h1->SetMarkerStyle(24);
363 h1->SetYTitle("<#sigma_{x}> [#mum]");
364 h1->SetXTitle("t_{drift} [#mus]");
5935a6da 365 h1->GetXaxis()->SetRange(2, AliTRDseedV1::kNtb-1); h1->Draw("pc");
1ee39b3a 366
367 t->Draw("z:t>>h2y(23, 0.1, 2.4, 25, 0., 2.5)","sy*(1)", "lego2fb");
368 h2 = (TH2F*)gROOT->FindObject("h2y");
369 printf(" const Double_t sy[24][25]={\n");
370 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
371 printf(" {");
372 for(Int_t iy=1; iy<h2->GetNbinsY(); iy++){
373 printf("%6.4f ", h2->GetBinContent(ix, iy));
374 }
375 printf("%6.4f},\n", h2->GetBinContent(ix, h2->GetNbinsY()));
376 }
377 printf(" };\n");
378 ((TVirtualPad*)l->At(1))->cd();
379 h1 = h2->ProjectionX("hsy_pxx"); h1->Scale(1.e4/kND); h1->SetMarkerStyle(24);
380 h1->SetYTitle("<#sigma_{y}> [#mum]");
381 h1->SetXTitle("t_{drift} [#mus]");
5935a6da 382 h1->GetXaxis()->SetRange(2, AliTRDseedV1::kNtb-1); h1->Draw("pc");
1ee39b3a 383 return kTRUE;
384 case kMean:
385 if(!(t = (TTree*)fResults->At(kMean))) break;
2ba7720d 386 if(!t->Draw(Form("z:t>>h2x(%d, -0.5, %3.1f, %d, 0., 2.5)",
5935a6da 387 AliTRDseedV1::kNtb, AliTRDseedV1::kNtb-0.5, kND),
2ba7720d 388 "dx*(1)", "goff")) break;
1ee39b3a 389 h2 = (TH2F*)gROOT->FindObject("h2x");
5935a6da 390 printf(" const Double_t dx[%d][%d]={\n", AliTRDseedV1::kNtb, kND);
1ee39b3a 391 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
392 printf(" {");
393 for(Int_t iy=1; iy<h2->GetNbinsY(); iy++){
5935a6da 394 printf("%+6.4e, ", h2->GetBinContent(ix, iy));
1ee39b3a 395 }
5935a6da 396 printf("%+6.4e},\n", h2->GetBinContent(ix, h2->GetNbinsY()));
1ee39b3a 397 }
398 printf(" };\n");
5935a6da 399 gPad->Divide(2, 2, 1.e-5, 1.e-5); l = gPad->GetListOfPrimitives();
1ee39b3a 400 ((TVirtualPad*)l->At(0))->cd();
5935a6da 401 h2->Draw("lego2fb");
402 ((TVirtualPad*)l->At(2))->cd();
1ee39b3a 403 h1 = h2->ProjectionX("hdx_pxx"); h1->Scale(1.e4/kND); h1->SetMarkerStyle(24);
5935a6da 404 h1->SetYTitle("<#deltax> [#mum]");
b9ddd472 405 h1->SetXTitle("t_{drift} [tb]");
5935a6da 406 //h1->GetXaxis()->SetRange(2, AliTRDseedV1::kNtb-1);
407 h1->Draw("pc");
1ee39b3a 408
2ba7720d 409 if(!t->Draw(Form("z:t>>h2y(%d, -0.5, %3.1f, %d, 0., 2.5)",
5935a6da 410 AliTRDseedV1::kNtb, AliTRDseedV1::kNtb-0.5, kND),
2ba7720d 411 "dy*(1)", "goff")) break;
1ee39b3a 412 h2 = (TH2F*)gROOT->FindObject("h2y");
5935a6da 413 printf(" const Double_t dy[%d][%d]={\n", AliTRDseedV1::kNtb, kND);
1ee39b3a 414 for(Int_t ix=1; ix<=h2->GetNbinsX(); ix++){
415 printf(" {");
416 for(Int_t iy=1; iy<h2->GetNbinsY(); iy++){
5935a6da 417 printf("%+6.4e ", h2->GetBinContent(ix, iy));
1ee39b3a 418 }
5935a6da 419 printf("%+6.4e},\n", h2->GetBinContent(ix, h2->GetNbinsY()));
1ee39b3a 420 }
421 printf(" };\n");
422 ((TVirtualPad*)l->At(1))->cd();
5935a6da 423 h2->Draw("lego2fb");
424 ((TVirtualPad*)l->At(3))->cd();
1ee39b3a 425 h1 = h2->ProjectionX("hdy_pxx"); h1->Scale(1.e4/kND); h1->SetMarkerStyle(24);
5935a6da 426 h1->SetYTitle("<#deltay> [#mum]");
b9ddd472 427 h1->SetXTitle("t_{drift} [tb]");
5935a6da 428 //h1->GetXaxis()->SetRange(2, AliTRDseedV1::kNtb-1);
429 h1->Draw("pc");
1ee39b3a 430
431 return kTRUE;
432 default:
433 break;
434 }
435 AliWarning("No container/data found.");
436 return kFALSE;
437}
438
439//_______________________________________________________
440TObjArray* AliTRDclusterResolution::Histos()
441{
442// Retrieve histograms array if already build or build it
443
444 if(fContainer) return fContainer;
445 fContainer = new TObjArray(kNtasks);
446 //fContainer->SetOwner(kTRUE);
447
5468a262 448 TH3S *h3(NULL);TH2I *h2(NULL);
449 TObjArray *arr(NULL);
450 if(!HasGlobalPosition() && !LoadGlobalChamberPosition()) return NULL;
451 Float_t tgt(fZch/fXch), htgt(fH*tgt);
452
453 // SYSTEMATIC PLOTS
ebc01dc0 454 fContainer->AddAt(arr = new TObjArray(3), kYSys);
455 arr->SetName("SysY");
5468a262 456 // systematic plot on pw and q (dydx=ExB+h*dzdx)
ebc01dc0 457 if(!(h3=(TH3S*)gROOT->FindObject(Form("Sys%s%03d", (HasMCdata()?"MC":"") ,fDet)))) {
82b61d3c 458 h3 = new TH3S(
ebc01dc0 459 Form("Sys%s%03d", (HasMCdata()?"MC":""),fDet),
5468a262 460 Form(" Det[%d] Col[%d] Row[%d];log q [a.u.];#deltay [pw];#Delta y[cm]", fDet, fCol, fRow),
461 45, 2., 6.5, // log(q) [a.u.]
462 25, -.51, .51, // y [pw]
463 60, -fDyRange, fDyRange); // dy [cm]
82b61d3c 464 } h3->Reset();
465 arr->AddAt(h3, 0);
5468a262 466 // systematic plot on tb (only for dydx = h*tgt + exb and MPV q)
467 if(!(h2 = (TH2I*)gROOT->FindObject(Form("SysTb%s%03d", (HasMCdata()?"MC":""), fDet)))){
468 h2 = new TH2I(Form("SysTb%s%03d", (HasMCdata()?"MC":""), fDet),
469 Form(" Det[%d] Col[%d] Row[%d];t [time bin];#Delta y[cm]", fDet, fCol, fRow),
470 AliTRDseedV1::kNtb, -.5, AliTRDseedV1::kNtb-0.5, // t [tb]
471 60, -fDyRange, fDyRange); // dy [cm]
472 } h2->Reset();
473 arr->AddAt(h2, 1);
474 // systematic plot on tgp and tb (for MPV q)
475 if(!(h3=(TH3S*)gROOT->FindObject(Form("SysTbTgp%s%03d", (HasMCdata()?"MC":""), fDet)))){
82b61d3c 476 h3 = new TH3S(
5468a262 477 Form("SysTbTgp%s%03d", (HasMCdata()?"MC":""), fDet),
478 Form(" Det[%d];t [time bin];tg(#phi) - h*tg(#theta) %s;#Delta y[cm]", fDet, fExB>1.e-5?"- tg(#alpha_{L})":""),
479 AliTRDseedV1::kNtb, -.5, AliTRDseedV1::kNtb-0.5, // t [tb]
480 36, fExB-.18, fExB+.18, // tgp-h tgt-tg(aL)
481 60, -fDyRange, fDyRange); // dy
ebc01dc0 482 } h3->Reset();
483 arr->AddAt(h3, 2);
484
5468a262 485 // RESOLUTION/PULLS PLOTS
2489d4c8 486 fContainer->AddAt(arr = new TObjArray(6), kYRes);
ebc01dc0 487 arr->SetName("ResY");
5468a262 488 // resolution plot on pw and q (for dydx=0 && B=0)
ebc01dc0 489 if(!(h3=(TH3S*)gROOT->FindObject(Form("Res%s%03d", (HasMCdata()?"MC":"") ,fDet)))) {
490 h3 = new TH3S(
491 Form("Res%s%03d", (HasMCdata()?"MC":""),fDet),
5468a262 492 Form(" Det[%d] Col[%d] Row[%d];log q [a.u];#deltay [pw];#Delta y[cm]", fDet, fCol, fRow),
493 45, 2., 6.5, // log(q) [a.u]
494 25, -.51, .51, // y [pw]
ebc01dc0 495 60, -fDyRange, fDyRange); // dy
496 } h3->Reset();
497 arr->AddAt(h3, 0);
5468a262 498 // Pull plot on pw and q (for dydx=0 && B=0)
499 if(!(h3=(TH3S*)gROOT->FindObject(Form("Pull%s%03d", (HasMCdata()?"MC":""), fDet)))){
ebc01dc0 500 h3 = new TH3S(
5468a262 501 Form("Pull%s%03d", (HasMCdata()?"MC":""), fDet),
502 Form(" Det[%d] Col[%d] Row[%d];log q [a.u.];#deltay [pw];#Delta y[cm]/#sigma_{y}", fDet, fCol, fRow),
503 45, 2., 6.5, // log(q) [a.u]
504 25, -.51, .51, // y [pw]
505 60, -4., 4.); // dy/sy
ebc01dc0 506 } h3->Reset();
507 arr->AddAt(h3, 1);
5468a262 508 // resolution/pull plot on tb (for dydx=0 && B=0 && MPV q)
509 if(!(h3 = (TH3S*)gROOT->FindObject(Form("ResPullTb%s%03d", (HasMCdata()?"MC":""), fDet)))){
510 h3 = new TH3S(Form("ResPullTb%s%03d", (HasMCdata()?"MC":""), fDet),
511 Form(" Det[%d] Col[%d] Row[%d];t [time bin];#Delta y[cm];#Delta y/#sigma_{y}", fDet, fCol, fRow),
512 AliTRDseedV1::kNtb, -.5, AliTRDseedV1::kNtb-0.5, // t [tb]
513 60, -fDyRange, fDyRange, // dy [cm]
514 60, -4., 4.); // dy/sy
ebc01dc0 515 } h3->Reset();
516 arr->AddAt(h3, 2);
5468a262 517 // resolution plot on pw and q (for dydx=0 && B=0) np = 2
518 if(!(h3=(TH3S*)gROOT->FindObject(Form("Res2%s%03d", (HasMCdata()?"MC":"") ,fDet)))) {
519 h3 = new TH3S(
520 Form("Res2%s%03d", (HasMCdata()?"MC":""),fDet),
521 Form(" Det[%d] Col[%d] Row[%d];log q [a.u];#deltay [pw];#Delta y[cm]", fDet, fCol, fRow),
522 45, 2., 6.5, // log(q) [a.u]
523 25, -.51, .51, // y [pw]
524 60, -fDyRange, fDyRange); // dy
525 } h3->Reset();
526 arr->AddAt(h3, 3);
527 // resolution plot on pw and q (for dydx=0 && B=0) np = 4
528 if(!(h3=(TH3S*)gROOT->FindObject(Form("Res4%s%03d", (HasMCdata()?"MC":"") ,fDet)))) {
529 h3 = new TH3S(
530 Form("Res4%s%03d", (HasMCdata()?"MC":""),fDet),
531 Form(" Det[%d] Col[%d] Row[%d];log q [a.u];#deltay [pw];#Delta y[cm]", fDet, fCol, fRow),
532 45, 2., 6.5, // log(q) [a.u]
533 25, -.51, .51, // y [pw]
534 60, -fDyRange, fDyRange); // dy
535 } h3->Reset();
536 arr->AddAt(h3, 4);
2489d4c8 537 // systemtic plot of tb on pw and q (for dydx=0 && B=0)
538 if(!(h3=(TH3S*)gROOT->FindObject(Form("SysTbPwQ%s%03d", (HasMCdata()?"MC":"") ,fDet)))) {
539 h3 = new TH3S(
540 Form("SysTbPwQ%s%03d", (HasMCdata()?"MC":""),fDet),
541 Form(" Det[%d] Col[%d] Row[%d];log q [a.u];#deltay [pw];t [time bin]", fDet, fCol, fRow),
542 45, 2., 6.5, // log(q) [a.u]
543 25, -.51, .51, // y [pw]
544 AliTRDseedV1::kNtb, -.5, AliTRDseedV1::kNtb-0.5); // t [tb]
545 } h3->Reset();
546 arr->AddAt(h3, 5);
5468a262 547
548
1ee39b3a 549
5935a6da 550 fContainer->AddAt(arr = new TObjArray(AliTRDseedV1::kNtb), kSigm);
1ee39b3a 551 arr->SetName("Resolution");
82b61d3c 552 for(Int_t it=0; it<AliTRDseedV1::kNtb; it++){
09cf4aad 553 if(!(h3=(TH3S*)gROOT->FindObject(Form("hr%s%03d_t%02d", (HasMCdata()?"MC":""), fDet, it)))){
1ee39b3a 554 h3 = new TH3S(
09cf4aad 555 Form("hr%s%03d_t%02d", (HasMCdata()?"MC":""), fDet, it),
06a0778f 556 Form(" Det[%d] t_{drift}(%2d)[bin];h*tg(#theta);tg(#phi);#Delta y[cm]", fDet, it),
5468a262 557 35, htgt-0.0035, htgt+0.0035, // h*tgt
558 36, fExB-.18, fExB+.18, // tgp
559 60, -fDyRange, fDyRange); // dy
560 } h3->Reset();
82b61d3c 561 arr->AddAt(h3, it);
1ee39b3a 562 }
1ee39b3a 563 return fContainer;
564}
565
566//_______________________________________________________
f8f46e4d 567void AliTRDclusterResolution::UserExec(Option_t *)
1ee39b3a 568{
569// Fill container histograms
570
e3147647 571 if(!IsCalibrated()){
572 LoadCalibration();
573 if(!IsCalibrated()){
5468a262 574 AliFatal("Loading the calibration settings failed. Check OCDB access.");
801d4d50 575 return;
576 }
577 }
5468a262 578 if(!fContainer){
579 fContainer = Histos();
580 PostData(1, fContainer);
581 }
582 fInfo = dynamic_cast<TObjArray *>(GetInputData(1));
583 AliDebug(2, Form("Clusters[%d]", fInfo->GetEntriesFast()));
1ee39b3a 584
5468a262 585 Int_t det, t, np;
1ee39b3a 586 Float_t x, y, z, q, dy, dydx, dzdx, cov[3], covcl[3];
5468a262 587 TH3S *h3(NULL); TH2I *h2(NULL);
1ee39b3a 588
589 // define limits around ExB for which x contribution is negligible
ea2e835e 590 const Float_t kAroundZero = 3.5e-2; //(+- 2 deg)
1ee39b3a 591
ebc01dc0 592 TObjArray *arr0 = (TObjArray*)fContainer->At(kYSys);
593 TObjArray *arr1 = (TObjArray*)fContainer->At(kYRes);
594 TObjArray *arr2 = (TObjArray*)fContainer->At(kSigm);
1ee39b3a 595
4226db3e 596 const AliTRDclusterInfo *cli = NULL;
1ee39b3a 597 TIterator *iter=fInfo->MakeIterator();
598 while((cli=dynamic_cast<AliTRDclusterInfo*>((*iter)()))){
5468a262 599 if((np = cli->GetNpads())>4) continue;
1ee39b3a 600 cli->GetCluster(det, x, y, z, q, t, covcl);
5935a6da 601
801d4d50 602 // select cluster according to detector region if specified
1ee39b3a 603 if(fDet>=0 && fDet!=det) continue;
801d4d50 604 if(fCol>=0 && fRow>=0){
605 Int_t c,r;
606 cli->GetCenterPad(c, r);
607 if(TMath::Abs(fCol-c) > 5) continue;
608 if(TMath::Abs(fRow-r) > 2) continue;
609 }
801d4d50 610 dy = cli->GetResolution();
a4982ebc 611 AliDebug(4, Form("det[%d] tb[%2d] q[%4.0f Log[%6.4f]] np[%d] dy[%7.2f][um] ypull[%5.2f]", det, t, q, TMath::Log(q), np, 1.e4*dy, dy/TMath::Sqrt(covcl[0])));
1ee39b3a 612
1ee39b3a 613 cli->GetGlobalPosition(y, z, dydx, dzdx, &cov[0]);
5468a262 614 Float_t pw(cli->GetYDisplacement());
1ee39b3a 615
5468a262 616 // systematics as a function of pw and log(q)
ebc01dc0 617 // only for dydx = exB + h*dzdx
5468a262 618 if(TMath::Abs(dydx-fExB-fH*dzdx) < kAroundZero){
619 h3 = (TH3S*)arr0->At(0);
620 h3->Fill(TMath::Log(q), pw, dy);
ebc01dc0 621 }
5468a262 622 // resolution/pull as a function of pw and log(q)
5583a68e 623 // only for dydx = 0, ExB=0
5468a262 624 if(TMath::Abs(fExB) < kAroundZero &&
bc93cc34 625 TMath::Abs(dydx) < kAroundZero &&
626 t>5 && t<24 ){
5468a262 627 switch(np){
628 case 3: // MPV np
629 h3 = (TH3S*)arr1->At(0);
630 h3->Fill(TMath::Log(q), pw, dy);
2489d4c8 631 h3 = (TH3S*)arr1->At(5);
632 h3->Fill(TMath::Log(q), pw, t);
5468a262 633 break;
634 case 2: // Min np
635 h3 = (TH3S*)arr1->At(3);
636 h3->Fill(TMath::Log(q), pw, dy);
637 break;
638 case 4: // Max np
639 h3 = (TH3S*)arr1->At(4);
640 h3->Fill(TMath::Log(q), pw, dy);
641 break;
642 }
643 h3 = (TH3S*)arr1->At(1);
644 h3->Fill(TMath::Log(q), pw, dy/TMath::Sqrt(covcl[0]));
1ee39b3a 645 }
646
647 // do not use problematic clusters in resolution analysis
648 // TODO define limits as calibration aware (gain) !!
5468a262 649 //if(!AcceptableGain(fGain)) continue;
650 if(q<20. || q>250.) continue;
651
652 // systematic as a function of time bin
653 // only for dydx = exB + h*dzdx and MPV q
654 if(TMath::Abs(dydx-fExB-fH*dzdx) < kAroundZero){
655 h2 = (TH2I*)arr0->At(1);
656 h2->Fill(t, dy);
1ee39b3a 657 }
5468a262 658 // systematic as function of tb and tgp
659 // only for MPV q
660 h3 = (TH3S*)arr0->At(2);
661 h3->Fill(t, dydx, dy);
662
663 // resolution/pull as a function of time bin
664 // only for dydx = 0, ExB=0 and MPV q
665 if(TMath::Abs(fExB) < kAroundZero &&
666 TMath::Abs(dydx) < kAroundZero){
667 h3 = (TH3S*)arr1->At(2);
668 h3->Fill(t, dy, dy/TMath::Sqrt(covcl[0]));
ebc01dc0 669 }
1ee39b3a 670
5468a262 671 // resolution as function of tb, tgp and h*tgt
672 // only for MPV q
673 ((TH3S*)arr2->At(t))->Fill(fH*dzdx, dydx, dy);
1ee39b3a 674 }
1ee39b3a 675}
676
677
678//_______________________________________________________
679Bool_t AliTRDclusterResolution::PostProcess()
680{
64d57299 681// Steer processing of various cluster resolution dependences :
682//
683// - process resolution dependency cluster charge
ebc01dc0 684// if(HasProcess(kYRes)) ProcessCharge();
64d57299 685// - process resolution dependency on y displacement
ebc01dc0 686// if(HasProcess(kYSys)) ProcessCenterPad();
64d57299 687// - process resolution dependency on drift legth and drift cell width
688// if(HasProcess(kSigm)) ProcessSigma();
689// - process systematic shift on drift legth and drift cell width
690// if(HasProcess(kMean)) ProcessMean();
691
1ee39b3a 692 if(!fContainer) return kFALSE;
e3147647 693 if(!IsCalibrated()){
5468a262 694 AliError("Not calibrated instance.");
e3147647 695 return kFALSE;
696 }
4226db3e 697 TObjArray *arr = NULL;
698 TTree *t=NULL;
1ee39b3a 699 if(!fResults){
4226db3e 700 TGraphErrors *g = NULL;
1ee39b3a 701 fResults = new TObjArray(kNtasks);
702 fResults->SetOwner();
ebc01dc0 703 fResults->AddAt(arr = new TObjArray(3), kYRes);
1ee39b3a 704 arr->SetOwner();
705 arr->AddAt(g = new TGraphErrors(), 0);
706 g->SetLineColor(kBlue); g->SetMarkerColor(kBlue);
707 g->SetMarkerStyle(7);
708 arr->AddAt(g = new TGraphErrors(), 1);
709 g->SetLineColor(kRed); g->SetMarkerColor(kRed);
710 g->SetMarkerStyle(23);
711 arr->AddAt(g = new TGraphErrors(), 2);
712 g->SetLineColor(kGreen); g->SetMarkerColor(kGreen);
713 g->SetMarkerStyle(7);
714
715 // pad center dependence
ebc01dc0 716 fResults->AddAt(arr = new TObjArray(AliTRDgeometry::kNlayer+1), kYSys);
1ee39b3a 717 arr->SetOwner();
718 arr->AddAt(
719 t = new TTree("cent", "dy=f(y,x,ly)"), 0);
720 t->Branch("ly", &fLy, "ly/B");
5935a6da 721 t->Branch("t", &fT, "t/F");
1ee39b3a 722 t->Branch("y", &fY, "y/F");
723 t->Branch("m", &fR[0], "m[2]/F");
724 t->Branch("s", &fR[2], "s[2]/F");
725 t->Branch("pm", &fP[0], "pm[2]/F");
726 t->Branch("ps", &fP[2], "ps[2]/F");
727 for(Int_t il=1; il<=AliTRDgeometry::kNlayer; il++){
728 arr->AddAt(g = new TGraphErrors(), il);
729 g->SetLineColor(il); g->SetLineStyle(il);
730 g->SetMarkerColor(il);g->SetMarkerStyle(4);
731 }
732
733
734 fResults->AddAt(t = new TTree("sigm", "dy=f(dw,x,dydx)"), kSigm);
5935a6da 735 t->Branch("t", &fT, "t/F");
736 t->Branch("x", &fX, "x/F");
1ee39b3a 737 t->Branch("z", &fZ, "z/F");
738 t->Branch("sx", &fR[0], "sx[2]/F");
739 t->Branch("sy", &fR[2], "sy[2]/F");
740
741
742 fResults->AddAt(t = new TTree("mean", "dy=f(dw,x,dydx - h dzdx)"), kMean);
5935a6da 743 t->Branch("t", &fT, "t/F");
744 t->Branch("x", &fX, "x/F");
1ee39b3a 745 t->Branch("z", &fZ, "z/F");
746 t->Branch("dx", &fR[0], "dx[2]/F");
747 t->Branch("dy", &fR[2], "dy[2]/F");
748 } else {
4226db3e 749 TObject *o = NULL;
1ee39b3a 750 TIterator *iter=fResults->MakeIterator();
751 while((o=((*iter)()))) o->Clear(); // maybe it is wrong but we should never reach this point
752 }
753
1ee39b3a 754 // process resolution dependency on charge
ebc01dc0 755 if(HasProcess(kYRes)) ProcessCharge();
1ee39b3a 756
757 // process resolution dependency on y displacement
5468a262 758 if(HasProcess(kYSys)) ProcessNormalTracks();
1ee39b3a 759
760 // process resolution dependency on drift legth and drift cell width
761 if(HasProcess(kSigm)) ProcessSigma();
762
763 // process systematic shift on drift legth and drift cell width
764 if(HasProcess(kMean)) ProcessMean();
765
766 return kTRUE;
767}
768
769//_______________________________________________________
e3147647 770Bool_t AliTRDclusterResolution::LoadCalibration()
1ee39b3a 771{
801d4d50 772// Retrieve calibration parameters from OCDB, drift velocity and t0 for the detector region specified by
773// a previous call to AliTRDclusterResolution::SetCalibrationRegion().
774
56f313bd 775 AliCDBManager *cdb = AliCDBManager::Instance(); // check access OCDB
1ee39b3a 776 if(cdb->GetRun() < 0){
777 AliError("OCDB manager not properly initialized");
778 return kFALSE;
779 }
1ee39b3a 780 // check magnetic field
56f313bd 781 if(!TGeoGlobalMagField::Instance() || !TGeoGlobalMagField::Instance()->IsLocked()){
782 AliError("Magnetic field not available.");
801d4d50 783 return kFALSE;
1ee39b3a 784 }
785
1ee39b3a 786 AliTRDcalibDB *fCalibration = AliTRDcalibDB::Instance();
801d4d50 787 AliTRDCalROC *fCalVdriftROC(fCalibration->GetVdriftROC(fDet>=0?fDet:0))
788 ,*fCalT0ROC(fCalibration->GetT0ROC(fDet>=0?fDet:0));
1ee39b3a 789 const AliTRDCalDet *fCalVdriftDet = fCalibration->GetVdriftDet();
5935a6da 790 const AliTRDCalDet *fCalT0Det = fCalibration->GetT0Det();
1ee39b3a 791
56f313bd 792 if(IsUsingCalibParam(kVdrift)){
793 fVdrift = fCalVdriftDet->GetValue(fDet>=0?fDet:0);
794 if(fCol>=0 && fRow>=0) fVdrift*= fCalVdriftROC->GetValue(fCol, fRow);
795 }
5935a6da 796 fExB = AliTRDCommonParam::Instance()->GetOmegaTau(fVdrift);
bce4b27e 797 AliTRDCommonParam::Instance()->GetDiffCoeff(fDt, fDl, fVdrift);
56f313bd 798 if(IsUsingCalibParam(kT0)){
799 fT0 = fCalT0Det->GetValue(fDet>=0?fDet:0);
800 if(fCol>=0 && fRow>=0) fT0 *= fCalT0ROC->GetValue(fCol, fRow);
801 }
802 if(IsUsingCalibParam(kGain)) fGain = (fCol>=0 && fRow>=0)?fCalibration-> GetGainFactor(fDet, fCol, fRow):fCalibration-> GetGainFactorAverage(fDet);
803
e3147647 804 SetBit(kCalibrated);
5935a6da 805
5468a262 806 AliInfo(Form("Calibration D[%3d] Col[%3d] Row[%2d] : \n t0[%5.3f] vd[%5.3f] gain[%5.3f] ExB[%f] DiffT[%f] DiffL[%f]", fDet, fCol, fRow, fT0, fVdrift, fGain, fExB, fDt, fDl));
5935a6da 807
1ee39b3a 808 return kTRUE;
809}
810
5468a262 811//_______________________________________________________
812Bool_t AliTRDclusterResolution::LoadGlobalChamberPosition()
813{
814// Retrieve global chamber position from alignment
815// a previous call to AliTRDclusterResolution::SetCalibrationRegion() is mandatory.
816
817 TGeoHMatrix *matrix(NULL);
818 Double_t loc[] = {0., 0., 0.}, glb[] = {0., 0., 0.};
819 AliTRDgeometry *geo(AliTRDinfoGen::Geometry());
820 if(!(matrix= geo->GetClusterMatrix(fDet))) {
821 AliFatal(Form("Could not get transformation matrix for detector %d.", fDet));
822 return kFALSE;
823 }
824 matrix->LocalToMaster(loc, glb);
825 fXch = glb[0]+ AliTRDgeometry::AnodePos()-.5*AliTRDgeometry::AmThick() - AliTRDgeometry::DrThick();
826 AliTRDpadPlane *pp(geo->GetPadPlane(fDet));
827 fH = TMath::Tan(pp->GetTiltingAngle()*TMath::DegToRad());
828 fZch = 0.;
829 if(fRow>=0){
830 fZch = pp->GetRowPos(fRow)+0.5*pp->GetLengthIPad();
831 }else{
832 Int_t nrows(pp->GetNrows());
833 Float_t zmax(pp->GetRow0()),
834 zmin(zmax - 2 * pp->GetLengthOPad()
835 - (nrows-2) * pp->GetLengthIPad()
836 - (nrows-1) * pp->GetRowSpacing());
837 fZch = 0.5*(zmin+zmax);
838 }
839
840 AliInfo(Form("Global pos. D[%3d] Col[%3d] Row[%2d] : \n x[%6.2f] z[%6.2f] h[%+6.2f].", fDet, fCol, fRow, fXch, fZch, fH));
841 SetBit(kGlobal);
842 return kTRUE;
843}
844
801d4d50 845//_______________________________________________________
846void AliTRDclusterResolution::SetCalibrationRegion(Int_t det, Int_t col, Int_t row)
847{
848// Set calibration region in terms of detector and pad.
849// By default detector 0 mean values are considered.
850
851 if(det>=0 && det<AliTRDgeometry::kNdet){
852 fDet = det;
853 if(col>=0 && row>=0){
5468a262 854 // check pad col/row for detector
855 AliTRDgeometry *geo = AliTRDinfoGen::Geometry();
856 AliTRDpadPlane *pp(geo->GetPadPlane(fDet));
857 if(fCol>=pp->GetNcols() ||
858 fRow>=pp->GetNrows()){
859 AliWarning(Form("Pad coordinates col[%d] or row[%d] incorrect for det[%d].\nLimits are max col[%d] max row[%d]. Reset to default", fCol, fRow, fDet, pp->GetNcols(), pp->GetNrows()));
860 fCol = -1; fRow=-1;
861 } else {
862 fCol = col;
863 fRow = row;
864 }
801d4d50 865 }
5468a262 866 } else {
867 AliFatal(Form("Detector index outside range [0 %d].", AliTRDgeometry::kNdet));
801d4d50 868 }
5468a262 869 return;
801d4d50 870}
871
1ee39b3a 872//_______________________________________________________
873void AliTRDclusterResolution::SetVisual()
874{
875 if(fCanvas) return;
876 fCanvas = new TCanvas("clResCanvas", "Cluster Resolution Visualization", 10, 10, 600, 600);
877}
878
879//_______________________________________________________
880void AliTRDclusterResolution::ProcessCharge()
881{
882// Resolution as a function of cluster charge.
883//
884// As described in the function ProcessCenterPad() the error parameterization for clusters for phi = a_L can be
885// written as:
886// BEGIN_LATEX
887// #sigma_{y}^{2} = #sigma_{y}^{2}|_{B=0} + tg^{2}(#alpha_{L})*#sigma_{x}^{2}
888// END_LATEX
889// with the contribution in case of B=0 given by:
890// BEGIN_LATEX
891// #sigma_{y}|_{B=0} = #sigma_{diff}*Gauss(0, s_{ly}) + #delta_{#sigma}(q)
892// END_LATEX
893// which further can be simplified to:
894// BEGIN_LATEX
895// <#sigma_{y}|_{B=0}>(q) = <#sigma_{y}> + #delta_{#sigma}(q)
896// <#sigma_{y}> = #int{f(q)#sigma_{y}dq}
897// END_LATEX
898// The results for s_y and f(q) are displayed below:
899//Begin_Html
900//<img src="TRD/clusterQerror.gif">
901//End_Html
902// The function has to extended to accomodate gain calibration scalling and errors.
903//
904// Author
905// Alexandru Bercuci <A.Bercuci@gsi.de>
906
2489d4c8 907
908
909 TObjArray *arr(NULL);
910 if(!(arr = (TObjArray*)fContainer->At(kYSys))) {
911 AliError("Missing systematic container");
912 return;
913 }
914 TH3S *h3s(NULL);
915 if(!(h3s = (TH3S*)arr->At(0))){
916 AliError("Missing systematic histo");
917 return;
918 }
919 // PROCESS SYSTEMATIC
920 Float_t tmin(6.5), tmax(20.5), tmed(0.5*(tmin+tmax));
921 TGraphErrors *g[2]; TH1 *h(NULL);
922 g[0] = new TGraphErrors();
923 g[0]->SetMarkerStyle(24);g[0]->SetMarkerColor(kBlue);g[0]->SetLineColor(kBlue);
924 g[1] = new TGraphErrors();
925 g[1]->SetMarkerStyle(24);g[1]->SetMarkerColor(kRed);g[1]->SetLineColor(kRed);
926 // define model for systematic shift vs pw
927 TF1 fm("fm", "[0]+[1]*sin(x*[2])", -.45,.45);
928 fm.SetParameter(0, 0.); fm.SetParameter(1, 1.e-2); fm.FixParameter(2, TMath::TwoPi());
929 fm.SetParNames("#deltay", "#pm#delta", "2*#pi");
930 h3s->GetXaxis()->SetRange(tmin, tmax);
931 if(!AliTRDresolution::Process((TH2*)h3s->Project3D("zy"), g))return;
932 g[0]->Fit(&fm, "QR");
933 if(fCanvas){
934 g[0]->Draw("apl");
935 fCanvas->Modified(); fCanvas->Update();
936 h = g[0]->GetHistogram();
937 h->SetTitle(fm.GetTitle());
938 h->GetXaxis()->SetTitle("pw");h->GetXaxis()->CenterTitle();
939 h->GetYaxis()->SetTitle("#Delta y[cm]");h->GetYaxis()->CenterTitle();
940 if(IsSaveAs()) fCanvas->SaveAs(Form("D%03d_SysNormTrack_pw.gif", fDet));
941 else gSystem->Sleep(100);
942 }
943
944 // define model for systematic shift vs tb
945 TF1 fx("fx", "[0]+0.1*[1]*(x-[2])", tmin, tmax);
946 fx.SetParNames("#deltay", "#deltay/t", "<t>");
947 fx.FixParameter(2, tmed);
948 h3s->GetXaxis()->UnZoom();
949 if(!AliTRDresolution::Process((TH2*)h3s->Project3D("zx"), g)) return;
950 g[0]->Fit(&fx, "Q", "", tmin, tmax);
951 if(fCanvas){
952 g[0]->Draw("apl");
953 fCanvas->Modified(); fCanvas->Update();
954 h = g[0]->GetHistogram();
955 h->SetTitle(fx.GetTitle());
956 h->GetXaxis()->SetTitle("t [tb]");h->GetXaxis()->CenterTitle();
957 h->GetYaxis()->SetTitle("#Delta y[cm]");h->GetYaxis()->CenterTitle();
958 if(IsSaveAs()) fCanvas->SaveAs(Form("D%03d_SysNormTrack_tb.gif", fDet));
959 else gSystem->Sleep(100);
960 }
961
5935a6da 962 TH3S *h3(NULL);
ebc01dc0 963 if(!(h3 = (TH3S*)fContainer->At(kYRes))) {
1ee39b3a 964 AliWarning("Missing dy=f(Q) histo");
965 return;
966 }
967 TF1 f("f", "gaus", -.5, .5);
5935a6da 968 TAxis *ax(NULL);
969 TH1 *h1(NULL);
1ee39b3a 970
971 // compute mean error on x
972 Double_t s2x = 0.;
5935a6da 973 for(Int_t ix=5; ix<AliTRDseedV1::kNtb; ix++){
1ee39b3a 974 // retrieve error on the drift length
975 s2x += AliTRDcluster::GetSX(ix);
976 }
5935a6da 977 s2x /= (AliTRDseedV1::kNtb-5); s2x *= s2x;
76d976d2 978 //Double_t exb2 = fExB*fExB;
1ee39b3a 979
2489d4c8 980 arr = (TObjArray*)fResults->At(kYRes);
1ee39b3a 981 TGraphErrors *gqm = (TGraphErrors*)arr->At(0);
982 TGraphErrors *gqs = (TGraphErrors*)arr->At(1);
983 TGraphErrors *gqp = (TGraphErrors*)arr->At(2);
984 Double_t q, n = 0., entries;
5935a6da 985 ax = h3->GetXaxis();
1ee39b3a 986 for(Int_t ix=1; ix<=ax->GetNbins(); ix++){
987 q = TMath::Exp(ax->GetBinCenter(ix));
5935a6da 988 ax->SetRange(ix, ix);
989 h1 = h3->Project3D("y");
1ee39b3a 990 entries = h1->GetEntries();
5935a6da 991 if(entries < 150) continue;
1ee39b3a 992 h1->Fit(&f, "Q");
993
994 // Fill sy^2 = f(q)
995 Int_t ip = gqm->GetN();
996 gqm->SetPoint(ip, q, 1.e4*f.GetParameter(1));
997 gqm->SetPointError(ip, 0., 1.e4*f.GetParError(1));
998
999 // correct sigma for ExB effect
5935a6da 1000 gqs->SetPoint(ip, q, 1.e4*f.GetParameter(2)/**f.GetParameter(2)-exb2*s2x)*/);
1001 gqs->SetPointError(ip, 0., 1.e4*f.GetParError(2)/**f.GetParameter(2)*/);
1ee39b3a 1002
1003 // save probability
1004 n += entries;
1005 gqp->SetPoint(ip, q, entries);
1006 gqp->SetPointError(ip, 0., 0./*TMath::Sqrt(entries)*/);
1007 }
1008
1009 // normalize probability and get mean sy
1010 Double_t sm = 0., sy;
1011 for(Int_t ip=gqp->GetN(); ip--;){
1012 gqp->GetPoint(ip, q, entries);
1013 entries/=n;
5935a6da 1014 gqp->SetPoint(ip, q, 1.e4*entries);
1ee39b3a 1015 gqs->GetPoint(ip, q, sy);
1016 sm += entries*sy;
1017 }
1018
1019 // error parametrization s(q) = <sy> + b(1/q-1/q0)
1020 TF1 fq("fq", "[0] + [1]/x", 20., 250.);
1021 gqs->Fit(&fq/*, "W"*/);
1022 printf("sm=%f [0]=%f [1]=%f\n", 1.e-4*sm, fq.GetParameter(0), fq.GetParameter(1));
1023 printf(" const Float_t sq0inv = %f; // [1/q0]\n", (sm-fq.GetParameter(0))/fq.GetParameter(1));
1024 printf(" const Float_t sqb = %f; // [cm]\n", 1.e-4*fq.GetParameter(1));
1025}
1026
1027//_______________________________________________________
2489d4c8 1028Bool_t AliTRDclusterResolution::ProcessNormalTracks()
1ee39b3a 1029{
1030// Resolution as a function of y displacement from pad center and drift length.
1031//
1032// Since the error parameterization of cluster r-phi position can be written as (see AliTRDcluster::SetSigmaY2()):
1033// BEGIN_LATEX
1034// #sigma_{y}^{2} = (#sigma_{diff}*Gauss(0, s_{ly}) + #delta_{#sigma}(q))^{2} + tg^{2}(#alpha_{L})*#sigma_{x}^{2} + tg^{2}(#phi-#alpha_{L})*#sigma_{x}^{2}+[tg(#phi-#alpha_{L})*tg(#alpha_{L})*x]^{2}/12
1035// END_LATEX
1036// one can see that for phi = a_L one gets the following expression:
1037// BEGIN_LATEX
1038// #sigma_{y}^{2} = #sigma_{y}^{2}|_{B=0} + tg^{2}(#alpha_{L})*#sigma_{x}^{2}
1039// END_LATEX
1040// where we have explicitely marked the remaining term in case of absence of magnetic field. Thus one can use the
1041// previous equation to estimate s_y for B=0 and than by comparing in magnetic field conditions one can get the s_x.
1042// This is a simplified method to determine the error parameterization for s_x and s_y as compared to the one
1043// implemented in ProcessSigma(). For more details on cluster error parameterization please see also
1044// AliTRDcluster::SetSigmaY2()
1045//
1046// The representation of dy=f(y_cen, x_drift| layer) can be also used to estimate the systematic shift in the r-phi
1047// coordinate resulting from imperfection in the cluster shape parameterization. From the expresion of the shift derived
1048// in ProcessMean() with phi=exb one gets:
1049// BEGIN_LATEX
1050// <#Delta y>= <#delta x> * (tg(#alpha_{L})-h*dz/dx) + <#delta y - #delta x * tg(#alpha_{L})>
1051// <#Delta y>(y_{cen})= -h*<#delta x>(x_{drift}, q_{cl}) * dz/dx + #delta y(y_{cen}, ...)
1052// END_LATEX
1053// where all dependences are made explicit. This last expression can be used in two ways:
1054// - by average on the dz/dx we can determine directly dy (the method implemented here)
1055// - by plotting as a function of dzdx one can determine both dx and dy components in an independent method.
1056//Begin_Html
1057//<img src="TRD/clusterYcorr.gif">
1058//End_Html
1059// Author
1060// Alexandru Bercuci <A.Bercuci@gsi.de>
1061
5468a262 1062 TObjArray *arr(NULL);
2489d4c8 1063 TH3S *h3r(NULL), *h3t(NULL);
5468a262 1064 if(!(arr= (TObjArray*)fContainer->At(kYRes))) {
1065 AliError("Missing resolution container");
2489d4c8 1066 return kFALSE;
1067 }
1068 if(!(h3r = (TH3S*)arr->At(0))){
1069 AliError("Missing resolution pw/q histo");
1070 return kFALSE;
1071 } else if(!(Int_t)h3r->GetEntries()){
1072 AliError("Empty resolution pw/q histo");
1073 return kFALSE;
1074 }
1075 if(!(h3t = (TH3S*)arr->At(2))){
1076 AliError("Missing resolution t histo");
1077 return kFALSE;
1078 } else if(!(Int_t)h3t->GetEntries()){
1079 AliError("Empty resolution t histo");
1080 return kFALSE;
5468a262 1081 }
5468a262 1082
2489d4c8 1083 // local variables
1084 Double_t x(0.), y(0.), ex(0.), ey(0.);
5468a262 1085 Float_t tmin(6.5), tmax(20.5), tmed(0.5*(tmin+tmax));
1086 TGraphErrors *g[2]; TH1 *h(NULL);
1087 g[0] = new TGraphErrors();
1088 g[0]->SetMarkerStyle(24);g[0]->SetMarkerColor(kBlue);g[0]->SetLineColor(kBlue);
1089 g[1] = new TGraphErrors();
1090 g[1]->SetMarkerStyle(24);g[1]->SetMarkerColor(kRed);g[1]->SetLineColor(kRed);
5468a262 1091
2489d4c8 1092 // PROCESS RESOLUTION VS TB
5468a262 1093 TF1 fsx("fsx", "[0]*[0]+[1]*[1]*[2]*0.1*(x-[3])", tmin, tmax);
2489d4c8 1094 fsx.SetParNames("#sqrt{<#sigma^{2}(prf, q)>}(t_{med})", "D_{T}", "v_{drift}", "t_{med}");
5468a262 1095 fsx.FixParameter(1, fDt);
1096 fsx.SetParameter(2, fVdrift);
1097 fsx.FixParameter(3, tmed);
2489d4c8 1098 if(!AliTRDresolution::Process((TH2*)h3r->Project3D("yx"), g)) return kFALSE;
5468a262 1099 for(Int_t ip(0); ip<g[1]->GetN(); ip++){
1100 g[1]->GetPoint(ip, x, y);ex = g[1]->GetErrorX(ip); ey = g[1]->GetErrorY(ip);
1101 g[1]->SetPoint(ip, x, y*y);g[1]->SetPointError(ip, ex, 2*y*ey);
1102 }
1103 g[1]->Fit(&fsx, "Q", "", tmin, tmax);
1104 if(fCanvas){
1105 g[1]->Draw("apl");
1106 fCanvas->Modified(); fCanvas->Update();
1107 h = g[1]->GetHistogram();
1108 h->SetTitle(fsx.GetTitle());
1109 h->GetXaxis()->SetTitle("t [tb]");h->GetXaxis()->CenterTitle();
1110 h->GetYaxis()->SetTitle("#sigma^{2} (y) [cm^{2}]");h->GetYaxis()->CenterTitle();
1111 if(IsSaveAs()) fCanvas->SaveAs(Form("D%03d_ResNormTrack_tb.gif", fDet));
1112 else gSystem->Sleep(100);
1113 }
1ee39b3a 1114
5468a262 1115 // define model for resolution vs pw
1116 TF1 fg("fg", "gaus", -.5, .5); fg.FixParameter(1, 0.);
1117 TF1 fs("fs", "[0]*[0]*exp(-1*(x/[1])**2)+[2]", -.5, .5);
1118 fs.SetParNames("<#sigma^{max}(q,prf)>_{q}", "#sigma(pw)", "D_{T}^{2}*<x>");
1119 h3r->GetXaxis()->SetRange(tmin, tmax);
2489d4c8 1120 if(!AliTRDresolution::Process((TH2*)h3r->Project3D("zy"), g, 200)) return kFALSE;
5468a262 1121 for(Int_t ip(0); ip<g[1]->GetN(); ip++){
1122 g[1]->GetPoint(ip, x, y); ex = g[1]->GetErrorX(ip); ey = g[1]->GetErrorY(ip);
1123 g[1]->SetPoint(ip, x, y*y);g[1]->SetPointError(ip, ex, 2.*y*ey);
1124 }
1125 g[1]->Fit(&fg, "QR");
1126 fs.SetParameter(0, TMath::Sqrt(fg.GetParameter(0)));
1127 fs.SetParameter(1, fg.GetParameter(2));
1128 Float_t sdiff(fDt*fDt*fsx.GetParameter(2)*tmed*0.1);
1129 fs.SetParameter(2, sdiff);
1130 fs.SetParLimits(2, 0.1*sdiff, 1.9*sdiff);
1131 g[1]->Fit(&fs, "QR");
1132 if(fCanvas){
1133 g[1]->Draw("apl");
1134 fCanvas->Modified(); fCanvas->Update();
1135 h = g[1]->GetHistogram();
1136 h->SetTitle(fs.GetTitle());
1137 h->GetXaxis()->SetTitle("pw");h->GetXaxis()->CenterTitle();
1138 h->GetYaxis()->SetTitle("#sigma^{2} (y) [cm^{2}]");h->GetYaxis()->CenterTitle();
1139 if(IsSaveAs()) fCanvas->SaveAs(Form("D%03d_ResNormTrack_pw.gif", fDet));
1140 else gSystem->Sleep(100);
1141 }
1ee39b3a 1142
5468a262 1143 AliDebug(2, Form("<s(q,prf)>[mum] = %7.3f", 1.e4*TMath::Sqrt(fsx.Eval(0.))));
1144 AliDebug(2, Form("<s(q)>[mum] = %7.3f", 1.e4*TMath::Sqrt(fs.Eval(-0.5)-fs.GetParameter(2))));
1145 AliDebug(2, Form("<s(x)>[mum] = %7.3f(prf) %7.3f(diff)", 1.e4*TMath::Sqrt(fs.GetParameter(2)), 1.e4*TMath::Sqrt(sdiff)));
1146
1147 // define model for resolution vs q
1148 TF1 fq("fq", "[0]*[0]*exp(-1*[1]*(x-[2])**2)+[2]", 2.5, 5.5);
1149 fq.SetParNames("<#sigma^{max}(q,prf)>_{prf}", "slope","mean", "D_{T}^{2}*<x>");
2489d4c8 1150 if(!AliTRDresolution::Process((TH2*)h3t->Project3D("yx"), g)) return kFALSE;
5468a262 1151 for(Int_t ip(0); ip<g[1]->GetN(); ip++){
1152 g[1]->GetPoint(ip, x, y); ex = g[1]->GetErrorX(ip); ey = g[1]->GetErrorY(ip);
1153 g[1]->SetPoint(ip, x, y*y);g[1]->SetPointError(ip, ex, 2.*y*ey);
1154 }
1155 fq.SetParameter(0, 8.e-2); fq.SetParLimits(0, 0., 1.);
1156 fq.SetParameter(1, 1.); //fq.SetParLimits(1, -1., 0.);
1157 fq.SetParameter(3, sdiff); fq.SetParLimits(3, 0.1*sdiff, 1.9*sdiff);
1158 g[1]->Fit(&fq, "QR");
1159// AliDebug(2, Form("<sq>[mum] = %7.3f", 1.e4*TMath::Sqrt(fs.Eval(-0.5)-fs.GetParameter(2)));
1160// AliDebug(2, Form("<sx>[mum] = %7.3f(prf) %7.3f(diff)", 1.e4*TMath::Sqrt(fs.Eval(-0.5)-fs.GetParameter(2)), 1.e4*TMath::Sqrt(sdiff)));
1161 if(fCanvas){
1162 g[1]->Draw("apl");
1ee39b3a 1163 fCanvas->Modified(); fCanvas->Update();
5468a262 1164 h = g[1]->GetHistogram();
1165 h->SetTitle(fs.GetTitle());
1166 h->GetXaxis()->SetTitle("log(q) [a.u.]");h->GetXaxis()->CenterTitle();
1167 h->GetYaxis()->SetTitle("#sigma^{2} (y) [cm^{2}]");h->GetYaxis()->CenterTitle();
1168 if(IsSaveAs()) fCanvas->SaveAs(Form("D%03d_ResNormTrack_q.gif", fDet));
1ee39b3a 1169 else gSystem->Sleep(100);
1170 }
2489d4c8 1171 return kTRUE;
1ee39b3a 1172}
1173
1174//_______________________________________________________
1175void AliTRDclusterResolution::ProcessSigma()
1176{
1177// As the r-phi coordinate is the only one which is measured by the TRD detector we have to rely on it to
1178// estimate both the radial (x) and r-phi (y) errors. This method is based on the following assumptions.
1179// The measured error in the y direction is the sum of the intrinsic contribution of the r-phi measurement
1180// with the contribution of the radial measurement - because x is not a parameter of Alice track model (Kalman).
1181// BEGIN_LATEX
1182// #sigma^{2}|_{y} = #sigma^{2}_{y*} + #sigma^{2}_{x*}
1183// END_LATEX
1184// In the general case
1185// BEGIN_LATEX
1186// #sigma^{2}_{y*} = #sigma^{2}_{y} + tg^{2}(#alpha_{L})#sigma^{2}_{x_{drift}}
1187// #sigma^{2}_{x*} = tg^{2}(#phi - #alpha_{L})*(#sigma^{2}_{x_{drift}} + #sigma^{2}_{x_{0}} + tg^{2}(#alpha_{L})*x^{2}/12)
1188// END_LATEX
1189// where we have explicitely show the lorentz angle correction on y and the projection of radial component on the y
1190// direction through the track angle in the bending plane (phi). Also we have shown that the radial component in the
1191// last equation has twp terms, the drift and the misalignment (x_0). For ideal geometry or known misalignment one
1192// can solve the equation
1193// BEGIN_LATEX
1194// #sigma^{2}|_{y} = tg^{2}(#phi - #alpha_{L})*(#sigma^{2}_{x} + tg^{2}(#alpha_{L})*x^{2}/12)+ [#sigma^{2}_{y} + tg^{2}(#alpha_{L})#sigma^{2}_{x}]
1195// END_LATEX
1196// by fitting a straight line:
1197// BEGIN_LATEX
1198// #sigma^{2}|_{y} = a(x_{cl}, z_{cl}) * tg^{2}(#phi - #alpha_{L}) + b(x_{cl}, z_{cl})
1199// END_LATEX
1200// the error parameterization will be given by:
1201// BEGIN_LATEX
1202// #sigma_{x} (x_{cl}, z_{cl}) = #sqrt{a(x_{cl}, z_{cl}) - tg^{2}(#alpha_{L})*x^{2}/12}
1203// #sigma_{y} (x_{cl}, z_{cl}) = #sqrt{b(x_{cl}, z_{cl}) - #sigma^{2}_{x} (x_{cl}, z_{cl}) * tg^{2}(#alpha_{L})}
1204// END_LATEX
1205// Below there is an example of such dependency.
1206//Begin_Html
1207//<img src="TRD/clusterSigmaMethod.gif">
1208//End_Html
1209//
1210// The error parameterization obtained by this method are implemented in the functions AliTRDcluster::GetSX() and
1211// AliTRDcluster::GetSYdrift(). For an independent method to determine s_y as a function of drift length check the
1212// function ProcessCenterPad(). One has to keep in mind that while this method return the mean s_y over the distance
1213// to pad center distribution the other method returns the *STANDARD* value at center=0 (maximum). To recover the
1214// standard value one has to solve the obvious equation:
1215// BEGIN_LATEX
1216// #sigma_{y}^{STANDARD} = #frac{<#sigma_{y}>}{#int{s exp(s^{2}/#sigma) ds}}
1217// END_LATEX
1218// with "<s_y>" being the value calculated here and "sigma" the width of the s_y distribution calculated in
1219// ProcessCenterPad().
1220//
1221// Author
1222// Alexandru Bercuci <A.Bercuci@gsi.de>
1223
1224 TObjArray *arr = (TObjArray*)fContainer->At(kSigm);
1225 if(!arr){
1226 AliWarning("Missing dy=f(x_d, d_w) container");
1227 return;
1228 }
1229
1230 // init visualization
4226db3e 1231 TGraphErrors *ggs = NULL;
1232 TGraph *line = NULL;
1ee39b3a 1233 if(fCanvas){
1234 ggs = new TGraphErrors();
1235 line = new TGraph();
1236 line->SetLineColor(kRed);line->SetLineWidth(2);
1237 }
1238
1239 // init logistic support
1240 TF1 f("f", "gaus", -.5, .5);
1241 TLinearFitter gs(1,"pol1");
4226db3e 1242 TH1 *hFrame=NULL;
1243 TH1D *h1 = NULL; TH3S *h3=NULL;
1244 TAxis *ax = NULL;
5935a6da 1245 Double_t exb2 = fExB*fExB;
1ee39b3a 1246 AliTRDcluster c;
1247 TTree *t = (TTree*)fResults->At(kSigm);
5935a6da 1248 for(Int_t ix=0; ix<AliTRDseedV1::kNtb; ix++){
1ee39b3a 1249 if(!(h3=(TH3S*)arr->At(ix))) continue;
1250 c.SetPadTime(ix);
5935a6da 1251 fX = c.GetXloc(fT0, fVdrift);
1252 fT = c.GetLocalTimeBin(); // ideal
1253 printf(" pad time[%d] local[%f]\n", ix, fT);
1ee39b3a 1254 for(Int_t iz=1; iz<=h3->GetXaxis()->GetNbins(); iz++){
1255 ax = h3->GetXaxis();
1256 ax->SetRange(iz, iz);
1257 fZ = ax->GetBinCenter(iz);
1258
1259 // reset visualization
1260 if(fCanvas){
1261 new(ggs) TGraphErrors();
1262 ggs->SetMarkerStyle(7);
1263 }
1264 gs.ClearPoints();
1265
1266 for(Int_t ip=1; ip<=h3->GetYaxis()->GetNbins(); ip++){
1267 ax = h3->GetYaxis();
1268 ax->SetRange(ip, ip);
1269 Double_t tgl = ax->GetBinCenter(ip);
1270 // finish navigation in the HnSparse
1271
1272 //if(TMath::Abs(dydx)>0.18) continue;
1273 Double_t tgg = (tgl-fExB)/(1.+tgl*fExB);
1274 Double_t tgg2 = tgg*tgg;
1275
1276 h1 = (TH1D*)h3->Project3D("z");
1277 Int_t entries = (Int_t)h1->Integral();
1278 if(entries < 50) continue;
1279 //Adjust(&f, h1);
1280 h1->Fit(&f, "QN");
1281
1282 Double_t s2 = f.GetParameter(2)*f.GetParameter(2);
1283 Double_t s2e = 2.*f.GetParameter(2)*f.GetParError(2);
1284 // Fill sy^2 = f(tg^2(phi-a_L))
1285 gs.AddPoint(&tgg2, s2, s2e);
1286
1287 if(!ggs) continue;
1288 Int_t jp = ggs->GetN();
1289 ggs->SetPoint(jp, tgg2, s2);
1290 ggs->SetPointError(jp, 0., s2e);
1291 }
1292 // TODO here a more robust fit method has to be provided
1293 // for which lower boundaries on the parameters have to
1294 // be imposed. Unfortunately the Minuit fit does not work
1295 // for the TGraph in the case of B not 0.
1296 if(gs.Eval()) continue;
1297
5935a6da 1298 fR[0] = gs.GetParameter(1) - fX*fX*exb2/12.;
1299 AliDebug(3, Form(" s2x+x2=%f ang=%f s2x=%f", gs.GetParameter(1), fX*fX*exb2/12., fR[0]));
1ee39b3a 1300 fR[0] = TMath::Max(fR[0], Float_t(4.e-4));
1301
1302 // s^2_y = s0^2_y + tg^2(a_L) * s^2_x
1303 // s0^2_y = f(D_L)*x + s_PRF^2
1304 fR[2]= gs.GetParameter(0)-exb2*fR[0];
5935a6da 1305 AliDebug(3, Form(" s2y+s2x=%f s2y=%f", fR[0], fR[2]));
1ee39b3a 1306 fR[2] = TMath::Max(fR[2], Float_t(2.5e-5));
1307 fR[0] = TMath::Sqrt(fR[0]);
1308 fR[1] = .5*gs.GetParError(1)/fR[0];
1309 fR[2] = TMath::Sqrt(fR[2]);
1310 fR[3] = gs.GetParError(0)+exb2*exb2*gs.GetParError(1);
1311 t->Fill();
5935a6da 1312 AliDebug(2, Form("xd=%4.2f[cm] sx=%6.1f[um] sy=%5.1f[um]", fX, 1.e4*fR[0], 1.e4*fR[2]));
1ee39b3a 1313
1314 if(!fCanvas) continue;
1315 fCanvas->cd(); fCanvas->SetLogx(); //fCanvas->SetLogy();
1316 if(!hFrame){
1317 fCanvas->SetMargin(0.15, 0.01, 0.1, 0.01);
1318 hFrame=new TH1I("hFrame", "", 100, 0., .3);
1319 hFrame->SetMinimum(0.);hFrame->SetMaximum(.005);
1320 hFrame->SetXTitle("tg^{2}(#phi-#alpha_{L})");
1321 hFrame->SetYTitle("#sigma^{2}y[cm^{2}]");
1322 hFrame->GetYaxis()->SetTitleOffset(2.);
1323 hFrame->SetLineColor(1);hFrame->SetLineWidth(1);
1324 hFrame->Draw();
1325 } else hFrame->Reset();
1326 Double_t xx = 0., dxx=.2/50;
1327 for(Int_t ip=0;ip<50;ip++){
1328 line->SetPoint(ip, xx, gs.GetParameter(0)+xx*gs.GetParameter(1));
1329 xx+=dxx;
1330 }
1331 ggs->Draw("pl"); line->Draw("l");
1332 fCanvas->Modified(); fCanvas->Update();
1333 if(IsSaveAs()) fCanvas->SaveAs(Form("Figures/ProcessSigma_z[%5.3f]_x[%5.3f].gif", fZ, fX));
1334 else gSystem->Sleep(100);
1335 }
1336 }
1337 return;
1338}
1339
1340//_______________________________________________________
1341void AliTRDclusterResolution::ProcessMean()
1342{
1343// By this method the cluster shift in r-phi and radial directions can be estimated by comparing with the MC.
1344// The resolution of the cluster corrected for pad tilt with respect to MC in the r-phi (measuring) plane can be
1345// expressed by:
1346// BEGIN_LATEX
1347// #Delta y=w - y_{MC}(x_{cl})
1348// w = y_{cl}^{'} + h*(z_{MC}(x_{cl})-z_{cl})
1349// y_{MC}(x_{cl}) = y_{0} - dy/dx*x_{cl}
1350// z_{MC}(x_{cl}) = z_{0} - dz/dx*x_{cl}
1351// y_{cl}^{'} = y_{cl}-x_{cl}*tg(#alpha_{L})
1352// END_LATEX
1353// where x_cl is the drift length attached to a cluster, y_cl is the r-phi coordinate of the cluster measured by
1354// charge sharing on adjacent pads and y_0 and z_0 are MC reference points (as example the track references at
1355// entrance/exit of a chamber). If we suppose that both r-phi (y) and radial (x) coordinate of the clusters are
1356// affected by errors we can write
1357// BEGIN_LATEX
1358// x_{cl} = x_{cl}^{*} + #delta x
1359// y_{cl} = y_{cl}^{*} + #delta y
1360// END_LATEX
1361// where the starred components are the corrected values. Thus by definition the following quantity
1362// BEGIN_LATEX
1363// #Delta y^{*}= w^{*} - y_{MC}(x_{cl}^{*})
1364// END_LATEX
1365// has 0 average over all dependency. Using this decomposition we can write:
1366// BEGIN_LATEX
1367// <#Delta y>=<#Delta y^{*}> + <#delta x * (dy/dx-h*dz/dx) + #delta y - #delta x * tg(#alpha_{L})>
1368// END_LATEX
1369// which can be transformed to the following linear dependence:
1370// BEGIN_LATEX
1371// <#Delta y>= <#delta x> * (dy/dx-h*dz/dx) + <#delta y - #delta x * tg(#alpha_{L})>
1372// END_LATEX
1373// if expressed as function of dy/dx-h*dz/dx. Furtheremore this expression can be plotted for various clusters
1374// i.e. we can explicitely introduce the diffusion (x_cl) and drift cell - anisochronity (z_cl) dependences. From
1375// plotting this dependence and linear fitting it with:
1376// BEGIN_LATEX
1377// <#Delta y>= a(x_{cl}, z_{cl}) * (dy/dx-h*dz/dx) + b(x_{cl}, z_{cl})
1378// END_LATEX
1379// the systematic shifts will be given by:
1380// BEGIN_LATEX
1381// #delta x (x_{cl}, z_{cl}) = a(x_{cl}, z_{cl})
1382// #delta y (x_{cl}, z_{cl}) = b(x_{cl}, z_{cl}) + a(x_{cl}, z_{cl}) * tg(#alpha_{L})
1383// END_LATEX
1384// Below there is an example of such dependency.
1385//Begin_Html
1386//<img src="TRD/clusterShiftMethod.gif">
1387//End_Html
1388//
1389// The occurance of the radial shift is due to the following conditions
1390// - the approximation of a constant drift velocity over the drift length (larger drift velocities close to
1391// cathode wire plane)
1392// - the superposition of charge tails in the amplification region (first clusters appear to be located at the
1393// anode wire)
1394// - the superposition of charge tails in the drift region (shift towards anode wire)
1395// - diffusion effects which convolute with the TRF thus enlarging it
1396// - approximate knowledge of the TRF (approximate measuring in test beam conditions)
1397//
1398// The occurance of the r-phi shift is due to the following conditions
1399// - approximate model for cluster shape (LUT)
1400// - rounding-up problems
1401//
1402// The numerical results for ideal simulations for the radial and r-phi shifts are displayed below and used
1403// for the cluster reconstruction (see the functions AliTRDcluster::GetXcorr() and AliTRDcluster::GetYcorr()).
1404//Begin_Html
1405//<img src="TRD/clusterShiftX.gif">
1406//<img src="TRD/clusterShiftY.gif">
1407//End_Html
1408// More details can be found in the presentation given during the TRD
1409// software meeting at the end of 2008 and beginning of year 2009, published on indico.cern.ch.
1410//
1411// Author
1412// Alexandru Bercuci <A.Bercuci@gsi.de>
1413
1414
1415
1416 TObjArray *arr = (TObjArray*)fContainer->At(kMean);
1417 if(!arr){
1418 AliWarning("Missing dy=f(x_d, d_w) container");
1419 return;
1420 }
1421
1422 // init logistic support
1423 TF1 f("f", "gaus", -.5, .5);
1424 TF1 line("l", "[0]+[1]*x", -.15, .15);
1425 TGraphErrors *gm = new TGraphErrors();
4226db3e 1426 TH1 *hFrame=NULL;
1427 TH1D *h1 = NULL; TH3S *h3 =NULL;
1428 TAxis *ax = NULL;
5935a6da 1429
1430 AliDebug(1, Form("Calibrate for Det[%3d] t0[%5.3f] vd[%5.3f]", fDet, fT0, fVdrift));
1ee39b3a 1431
1432 AliTRDcluster c;
1433 TTree *t = (TTree*)fResults->At(kMean);
5935a6da 1434 for(Int_t ix=0; ix<AliTRDseedV1::kNtb; ix++){
1ee39b3a 1435 if(!(h3=(TH3S*)arr->At(ix))) continue;
1436 c.SetPadTime(ix);
5935a6da 1437 fX = c.GetXloc(fT0, fVdrift);
1438 fT = c.GetLocalTimeBin();
1ee39b3a 1439 for(Int_t iz=1; iz<=h3->GetXaxis()->GetNbins(); iz++){
1440 ax = h3->GetXaxis();
1441 ax->SetRange(iz, iz);
1442 fZ = ax->GetBinCenter(iz);
1443
1444 // reset fitter
1445 new(gm) TGraphErrors();
1446 gm->SetMarkerStyle(7);
1447
1448 for(Int_t ip=1; ip<=h3->GetYaxis()->GetNbins(); ip++){
1449 ax = h3->GetYaxis();
1450 ax->SetRange(ip, ip);
1451 Double_t tgl = ax->GetBinCenter(ip);
1452 // finish navigation in the HnSparse
1453
1454 h1 = (TH1D*)h3->Project3D("z");
1455 Int_t entries = (Int_t)h1->Integral();
b9ddd472 1456 if(entries < 50) continue;
1ee39b3a 1457 //Adjust(&f, h1);
1458 h1->Fit(&f, "QN");
1459
1460 // Fill <Dy> = f(dydx - h*dzdx)
1461 Int_t jp = gm->GetN();
1462 gm->SetPoint(jp, tgl, f.GetParameter(1));
1463 gm->SetPointError(jp, 0., f.GetParError(1));
1464 }
5935a6da 1465 if(gm->GetN()<10) continue;
1ee39b3a 1466
1467 gm->Fit(&line, "QN");
1468 fR[0] = line.GetParameter(1); // dx
1469 fR[1] = line.GetParError(1);
1470 fR[2] = line.GetParameter(0) + fExB*fR[0]; // xs = dy - tg(a_L)*dx
1471 t->Fill();
5935a6da 1472 AliDebug(2, Form("tb[%02d] xd=%4.2f[cm] dx=%6.2f[um] dy=%6.2f[um]", ix, fX, 1.e4*fR[0], 1.e4*fR[2]));
1ee39b3a 1473 if(!fCanvas) continue;
5935a6da 1474
1ee39b3a 1475 fCanvas->cd();
1476 if(!hFrame){
1477 fCanvas->SetMargin(0.1, 0.02, 0.1, 0.01);
1478 hFrame=new TH1I("hFrame", "", 100, -.3, .3);
1479 hFrame->SetMinimum(-.1);hFrame->SetMaximum(.1);
1480 hFrame->SetXTitle("tg#phi-htg#theta");
1481 hFrame->SetYTitle("#Delta y[cm]");
1482 hFrame->GetYaxis()->SetTitleOffset(1.5);
1483 hFrame->SetLineColor(1);hFrame->SetLineWidth(1);
1484 hFrame->Draw();
1485 } else hFrame->Reset();
1486 gm->Draw("pl"); line.Draw("same");
1487 fCanvas->Modified(); fCanvas->Update();
5935a6da 1488 if(IsSaveAs()) fCanvas->SaveAs(Form("Figures/ProcessMean_Z[%5.3f]_TB[%02d].gif", fZ, ix));
1ee39b3a 1489 else gSystem->Sleep(100);
1490 }
1491 }
1492}