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