]>
Commit | Line | Data |
---|---|---|
9462866a | 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 | // | |
fa7831fb | 61 | // Clusters can be radially shifted due to three causes: |
9462866a | 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 | // | |
fa7831fb | 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 | ||
9462866a | 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} + exp(-a*(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"); | |
146 | // cdb->SetRun(0); | |
147 | // // initialize magnetic field. | |
148 | // AliMagFMaps *field = new AliMagFMaps("Maps","Maps", 2, 1., 10., AliMagFMaps::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 | // if(!res->PostProcess()) return; | |
156 | // new TCanvas; | |
157 | // res->GetRefFigure(fig); | |
158 | // } | |
159 | // | |
160 | // Authors: // | |
161 | // Alexandru Bercuci <A.Bercuci@gsi.de> // | |
162 | //////////////////////////////////////////////////////////////////////////// | |
163 | ||
b2dc316d | 164 | #include "AliTRDclusterResolution.h" |
165 | #include "AliTRDtrackInfo/AliTRDclusterInfo.h" | |
5198d8c6 | 166 | #include "AliTRDgeometry.h" |
6bc4a8f4 | 167 | #include "AliTRDcalibDB.h" |
168 | #include "Cal/AliTRDCalROC.h" | |
169 | #include "Cal/AliTRDCalDet.h" | |
b2dc316d | 170 | |
171 | #include "AliLog.h" | |
6bc4a8f4 | 172 | #include "AliTracker.h" |
173 | #include "AliCDBManager.h" | |
b2dc316d | 174 | |
175 | #include "TObjArray.h" | |
176 | #include "TAxis.h" | |
fc0946a7 | 177 | #include "TF1.h" |
178 | #include "TGraphErrors.h" | |
b2dc316d | 179 | #include "TH2I.h" |
180 | #include "TMath.h" | |
9462866a | 181 | #include "TLinearFitter.h" |
182 | ||
183 | #include "TCanvas.h" | |
184 | #include "TSystem.h" | |
185 | ||
b2dc316d | 186 | |
187 | ClassImp(AliTRDclusterResolution) | |
188 | ||
189 | ||
190 | //_______________________________________________________ | |
191 | AliTRDclusterResolution::AliTRDclusterResolution() | |
5198d8c6 | 192 | : AliTRDrecoTask("ClErrParam", "Cluster Error Parametrization") |
b2dc316d | 193 | ,fInfo(0x0) |
fc0946a7 | 194 | ,fResults(0x0) |
195 | ,fAt(0x0) | |
196 | ,fAd(0x0) | |
197 | ,fExB(0.) | |
9462866a | 198 | ,fVdrift(0.) |
6bc4a8f4 | 199 | ,fDet(-1) |
b2dc316d | 200 | { |
9462866a | 201 | // ideal equidistant binning |
202 | //fAt = new TAxis(kNTB, -0.075, (kNTB-.5)*.15); | |
203 | ||
204 | // equidistant binning for scaled for X0-MC (track ref) | |
205 | fAt = new TAxis(kNTB, -0.075+.088, (kNTB-.5)*.15+.088); | |
206 | ||
207 | // non-equidistant binning after vdrift correction | |
208 | // const Double_t x[kNTB+1] = { | |
209 | // 0.000000, 0.185084, 0.400490, 0.519701, 0.554653, 0.653150, 0.805063, 0.990261, | |
210 | // 1.179610, 1.356406, 1.524094, 1.685499, 1.843083, 1.997338, 2.148077, 2.298274, | |
211 | // 2.448656, 2.598639, 2.747809, 2.896596, 3.045380, 3.195000, 3.340303, 3.461688, | |
212 | // 3.540094, 3.702677}; | |
213 | // fAt = new TAxis(kNTB, x); | |
214 | ||
fc0946a7 | 215 | fAd = new TAxis(kND, 0., .25); |
b2dc316d | 216 | } |
217 | ||
218 | //_______________________________________________________ | |
219 | AliTRDclusterResolution::~AliTRDclusterResolution() | |
220 | { | |
fc0946a7 | 221 | if(fAd) delete fAd; |
222 | if(fAt) delete fAt; | |
223 | if(fResults){ | |
224 | fResults->Delete(); | |
225 | delete fResults; | |
226 | } | |
b2dc316d | 227 | } |
228 | ||
229 | //_______________________________________________________ | |
230 | void AliTRDclusterResolution::ConnectInputData(Option_t *) | |
231 | { | |
232 | fInfo = dynamic_cast<TObjArray *>(GetInputData(0)); | |
233 | } | |
234 | ||
235 | //_______________________________________________________ | |
236 | void AliTRDclusterResolution::CreateOutputObjects() | |
237 | { | |
238 | OpenFile(0, "RECREATE"); | |
239 | fContainer = Histos(); | |
240 | } | |
241 | ||
242 | //_______________________________________________________ | |
e15179be | 243 | Bool_t AliTRDclusterResolution::GetRefFigure(Int_t ifig) |
b2dc316d | 244 | { |
e15179be | 245 | if(!fResults) return kFALSE; |
fc0946a7 | 246 | |
247 | TObjArray *arr = 0x0; | |
248 | TH2 *h2 = 0x0; | |
9462866a | 249 | TGraphErrors *gm(0x0), *gs(0x0), *gp(0x0); |
fc0946a7 | 250 | switch(ifig){ |
251 | case kQRes: | |
252 | if(!(arr = (TObjArray*)fResults->At(kQRes))) break; | |
253 | if(!(gm = (TGraphErrors*)arr->At(0))) break; | |
254 | if(!(gs = (TGraphErrors*)arr->At(1))) break; | |
9462866a | 255 | if(!(gp = (TGraphErrors*)arr->At(2))) break; |
fc0946a7 | 256 | gs->Draw("apl"); |
9462866a | 257 | gs->GetHistogram()->GetYaxis()->SetRangeUser(-.01, .6); |
258 | gs->GetHistogram()->SetXTitle("Q [a.u.]"); | |
259 | gs->GetHistogram()->SetYTitle("#sigma_{y} / #mu_{y} [mm] / freq"); | |
260 | gm->Draw("pl"); | |
261 | gp->Draw("pl"); | |
e15179be | 262 | return kTRUE; |
9462866a | 263 | case kCenter: |
264 | if(!(arr = (TObjArray*)fResults->At(kCenter))) break; | |
265 | if(!(h2 = (TH2F*)arr->At(0))) break; | |
fc0946a7 | 266 | h2->Draw("lego2"); |
e15179be | 267 | return kTRUE; |
9462866a | 268 | case kSigm: |
269 | if(!(arr = (TObjArray*)fResults->At(kSigm))) break; | |
270 | gPad->Divide(2, 1); | |
271 | gPad->cd(1); | |
272 | if(!(h2 = (TH2F*)arr->At(0))) break; | |
273 | h2->Draw("lego2fb"); | |
274 | gPad->cd(2); | |
275 | if(!(h2 = (TH2F*)arr->At(1))) break; | |
276 | h2->Draw("lego2fb"); | |
277 | return kTRUE; | |
278 | case kMean: | |
279 | if(!(arr = (TObjArray*)fResults->At(kMean))) break; | |
280 | arr->ls(); | |
281 | /* gPad->Divide(2, 1); | |
282 | gPad->cd(1);*/ | |
283 | if(!(h2 = (TH2F*)arr->At(0))) break; | |
284 | h2->Draw("lego2 fb"); | |
285 | /* gPad->cd(2); | |
286 | if(!(h2 = (TH2F*)arr->At(1))) break; | |
287 | h2->Draw("lego2fb");*/ | |
e15179be | 288 | return kTRUE; |
fc0946a7 | 289 | default: |
290 | break; | |
291 | } | |
9462866a | 292 | AliWarning("No container/data found."); |
e15179be | 293 | return kFALSE; |
b2dc316d | 294 | } |
295 | ||
296 | //_______________________________________________________ | |
297 | TObjArray* AliTRDclusterResolution::Histos() | |
298 | { | |
299 | if(fContainer) return fContainer; | |
9462866a | 300 | fContainer = new TObjArray(sizeof(AliTRDclusterResolution::EResultContainers)); |
b2dc316d | 301 | //fContainer->SetOwner(kTRUE); |
302 | ||
5198d8c6 | 303 | TH2I *h2 = 0x0; |
304 | TObjArray *arr = 0x0; | |
305 | ||
306 | fContainer->AddAt(h2 = new TH2I("h_q", "", 50, 2.2, 7.5, 100, -.5, .5), kQRes); | |
307 | h2->SetXTitle("log(q) [a.u.]"); | |
308 | h2->SetYTitle("#Delta y[cm]"); | |
309 | h2->SetZTitle("entries"); | |
310 | ||
9462866a | 311 | fContainer->AddAt(arr = new TObjArray(AliTRDgeometry::kNlayer), kCenter); |
5198d8c6 | 312 | for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){ |
6bc4a8f4 | 313 | arr->AddAt(h2 = new TH2I(Form("h_y%d", ily), Form("Ly[%d]", ily), 51, -.51, .51, 100, -.5, .5), ily); |
5198d8c6 | 314 | h2->SetXTitle("y_{w} [w]"); |
315 | h2->SetYTitle("#Delta y[cm]"); | |
316 | h2->SetZTitle("entries"); | |
317 | } | |
318 | ||
9462866a | 319 | fContainer->AddAt(arr = new TObjArray(kN), kSigm); |
b2dc316d | 320 | Int_t ih = 0; |
fc0946a7 | 321 | for(Int_t id=1; id<=fAd->GetNbins(); id++){ |
322 | for(Int_t it=1; it<=fAt->GetNbins(); it++){ | |
9462866a | 323 | arr->AddAt(h2 = new TH2I(Form("h_d%02dt%02d", id, it), Form("d_{wire}(%3.1f-%3.1f)[mm] x_{drift}(%5.2f-%5.2f)[mm]", 10.*fAd->GetBinCenter(id)- 5.*fAd->GetBinWidth(id), 10.*fAd->GetBinCenter(id)+ 5.*fAd->GetBinWidth(id), 10.*fAt->GetBinCenter(it)- 5.*fAt->GetBinWidth(it), 10.*fAt->GetBinCenter(it)+ 5.*fAt->GetBinWidth(it)), 35, -.35, .35, 100, -.5, .5), ih++); |
5198d8c6 | 324 | h2->SetXTitle("tg#phi"); |
325 | h2->SetYTitle("#Delta y[cm]"); | |
326 | h2->SetZTitle("entries"); | |
b2dc316d | 327 | } |
328 | } | |
9462866a | 329 | |
330 | fContainer->AddAt(arr = new TObjArray(kN), kMean); | |
331 | ih = 0; | |
332 | for(Int_t id=1; id<=fAd->GetNbins(); id++){ | |
333 | for(Int_t it=1; it<=fAt->GetNbins(); it++){ | |
334 | arr->AddAt(h2 = new TH2I(Form("h_d%02dt%02d", id, it), Form("d_{wire}(%3.1f-%3.1f)[mm] x_{drift}(%5.2f-%5.2f)[mm]", 10.*fAd->GetBinCenter(id)- 5.*fAd->GetBinWidth(id), 10.*fAd->GetBinCenter(id)+ 5.*fAd->GetBinWidth(id), 10.*fAt->GetBinCenter(it)- 5.*fAt->GetBinWidth(it), 10.*fAt->GetBinCenter(it)+ 5.*fAt->GetBinWidth(it)), 35, -.35, .35, 100, -.5, .5), ih++); | |
335 | h2->SetXTitle("tg#phi-h*tg(#theta)"); | |
336 | h2->SetYTitle("#Delta y[cm]"); | |
337 | h2->SetZTitle("entries"); | |
338 | } | |
339 | } | |
340 | ||
b2dc316d | 341 | return fContainer; |
342 | } | |
343 | ||
344 | //_______________________________________________________ | |
345 | void AliTRDclusterResolution::Exec(Option_t *) | |
346 | { | |
6bc4a8f4 | 347 | if(!HasExB()) AliWarning("ExB was not set. Call SetExB() before running the task."); |
348 | ||
87b166d3 | 349 | Int_t det, t; |
fc0946a7 | 350 | Float_t x, y, z, q, dy, dydx, dzdx, cov[3], covcl[3]; |
b2dc316d | 351 | TH2I *h2 = 0x0; |
5198d8c6 | 352 | |
9462866a | 353 | // define limits around ExB for which x contribution is negligible |
354 | const Float_t kDtgPhi = 3.5e-2; //(+- 2 deg) | |
355 | ||
356 | TObjArray *arr0 = (TObjArray*)fContainer->At(kCenter); | |
357 | TObjArray *arr1 = (TObjArray*)fContainer->At(kSigm); | |
358 | TObjArray *arr2 = (TObjArray*)fContainer->At(kMean); | |
5198d8c6 | 359 | |
b2dc316d | 360 | const AliTRDclusterInfo *cli = 0x0; |
361 | TIterator *iter=fInfo->MakeIterator(); | |
362 | while((cli=dynamic_cast<AliTRDclusterInfo*>((*iter)()))){ | |
6bc4a8f4 | 363 | cli->GetCluster(det, x, y, z, q, t, covcl); |
364 | if(fDet>=0 && fDet!=det) continue; | |
9462866a | 365 | |
366 | dy = cli->GetResolution(); | |
367 | cli->GetGlobalPosition(y, z, dydx, dzdx, &cov[0]); | |
368 | ||
369 | // resolution as a function of cluster charge | |
370 | // only for phi equal exB | |
371 | if(TMath::Abs(dydx-fExB) < kDtgPhi){ | |
372 | h2 = (TH2I*)fContainer->At(kQRes); | |
373 | h2->Fill(TMath::Log(q), dy); | |
374 | } | |
375 | ||
376 | // do not use problematic clusters in resolution analysis | |
377 | // TODO define limits as calibration aware (gain) !! | |
378 | if(q<20. || q>250.) continue; | |
379 | ||
380 | // resolution as a function of y displacement from pad center | |
381 | // only for phi equal exB | |
382 | if(TMath::Abs(dydx-fExB) < kDtgPhi){ | |
383 | h2 = (TH2I*)arr0->At(AliTRDgeometry::GetLayer(det)); | |
384 | h2->Fill(cli->GetYDisplacement(), dy); | |
385 | } | |
6bc4a8f4 | 386 | |
fc0946a7 | 387 | Int_t it = fAt->FindBin(cli->GetDriftLength()); |
388 | if(it==0 || it == fAt->GetNbins()+1){ | |
b2dc316d | 389 | AliWarning(Form("Drift length %f outside allowed range", cli->GetDriftLength())); |
390 | continue; | |
391 | } | |
fc0946a7 | 392 | Int_t id = fAd->FindBin(cli->GetAnisochronity()); |
393 | if(id==0 || id == fAd->GetNbins()+1){ | |
b2dc316d | 394 | AliWarning(Form("Distance to anode %f outside allowed range", cli->GetAnisochronity())); |
395 | continue; | |
396 | } | |
9462866a | 397 | // calculate index of cluster position in array |
398 | Int_t hid = (id-1)*kNTB+it-1; | |
b2dc316d | 399 | |
9462866a | 400 | // fill histo for resolution (sigma) |
401 | h2 = (TH2I*)arr1->At(hid); | |
6bc4a8f4 | 402 | h2->Fill(dydx, dy); |
b2dc316d | 403 | |
9462866a | 404 | // fill histo for systematic (mean) |
405 | h2 = (TH2I*)arr2->At(hid); | |
406 | h2->Fill(dydx-cli->GetTilt()*dzdx, dy); | |
b2dc316d | 407 | } |
408 | PostData(0, fContainer); | |
409 | } | |
410 | ||
411 | ||
412 | //_______________________________________________________ | |
413 | Bool_t AliTRDclusterResolution::PostProcess() | |
414 | { | |
fc0946a7 | 415 | if(!fContainer) return kFALSE; |
6bc4a8f4 | 416 | if(!HasExB()) AliWarning("ExB was not set. Call SetExB() before running the post processing."); |
fc0946a7 | 417 | |
5198d8c6 | 418 | TObjArray *arr = 0x0; |
fc0946a7 | 419 | TH2 *h2 = 0x0; |
420 | if(!fResults){ | |
421 | TGraphErrors *g = 0x0; | |
9462866a | 422 | fResults = new TObjArray(sizeof(AliTRDclusterResolution::EResultContainers)); |
fc0946a7 | 423 | fResults->SetOwner(); |
9462866a | 424 | fResults->AddAt(arr = new TObjArray(3), kQRes); |
fc0946a7 | 425 | arr->SetOwner(); |
426 | arr->AddAt(g = new TGraphErrors(), 0); | |
427 | g->SetLineColor(kBlue); g->SetMarkerColor(kBlue); | |
428 | g->SetMarkerStyle(7); | |
429 | arr->AddAt(g = new TGraphErrors(), 1); | |
430 | g->SetLineColor(kRed); g->SetMarkerColor(kRed); | |
431 | g->SetMarkerStyle(23); | |
9462866a | 432 | arr->AddAt(g = new TGraphErrors(), 2); |
433 | g->SetLineColor(kGreen); g->SetMarkerColor(kGreen); | |
fc0946a7 | 434 | g->SetMarkerStyle(7); |
fc0946a7 | 435 | |
fa7831fb | 436 | fResults->AddAt(arr = new TObjArray(3), kCenter); |
9462866a | 437 | arr->SetOwner(); |
438 | arr->AddAt(h2 = new TH2F("hYM", "", | |
439 | AliTRDgeometry::kNlayer, -.5, AliTRDgeometry::kNlayer-.5, 51, -.51, .51), 0); | |
440 | h2->SetXTitle("ly"); | |
441 | h2->SetYTitle("y [w]"); | |
442 | h2->SetZTitle("#mu_{x} [mm]"); | |
443 | arr->AddAt(h2 = (TH2F*)h2->Clone("hYS"), 1); | |
444 | h2->SetZTitle("#sigma_{x} [mm]"); | |
fa7831fb | 445 | arr->AddAt(h2 = (TH2F*)h2->Clone("hYP"), 2); |
446 | h2->SetZTitle("entries"); | |
9462866a | 447 | |
448 | fResults->AddAt(arr = new TObjArray(2), kSigm); | |
449 | arr->SetOwner(); | |
450 | arr->AddAt(h2 = new TH2F("hSX", "", | |
fc0946a7 | 451 | fAd->GetNbins(), fAd->GetXmin(), fAd->GetXmax(), |
9462866a | 452 | fAt->GetNbins(), fAt->GetXmin(), fAt->GetXmax()), 0); |
fc0946a7 | 453 | h2->SetXTitle("d [mm]"); |
454 | h2->SetYTitle("x [mm]"); | |
9462866a | 455 | h2->SetZTitle("#sigma_{x} [mm]"); |
456 | arr->AddAt(h2 = (TH2F*)h2->Clone("hSY"), 1); | |
457 | h2->SetZTitle("#sigma_{y} [mm]"); | |
458 | ||
459 | fResults->AddAt(arr = new TObjArray(2), kMean); | |
460 | arr->SetOwner(); | |
461 | arr->AddAt(h2 = (TH2F*)h2->Clone("hDX"), 0); | |
462 | h2->SetZTitle("dx [mm]"); | |
463 | arr->AddAt(h2 = (TH2F*)h2->Clone("hX0"), 1); | |
464 | h2->SetZTitle("x0 [mm]"); | |
fc0946a7 | 465 | } else { |
466 | TObject *o = 0x0; | |
467 | TIterator *iter=fResults->MakeIterator(); | |
5198d8c6 | 468 | while((o=((*iter)()))) o->Clear(); // maybe it is wrong but we should never reach this point |
fc0946a7 | 469 | } |
9462866a | 470 | |
471 | // precalculated value of tg^2(alpha_L) | |
472 | Double_t exb2 = fExB*fExB; | |
473 | // square of the mean value of sigma drift length. | |
474 | // has to come from previous calibration | |
475 | //Double_t sxd2 = 1.;// [mm^2] | |
fc0946a7 | 476 | |
9462866a | 477 | printf("ExB[%e] ExB2[%e]\n", fExB, exb2); |
fc0946a7 | 478 | |
479 | // process resolution dependency on charge | |
fa7831fb | 480 | ProcessCharge(); |
fc0946a7 | 481 | |
fc0946a7 | 482 | // process resolution dependency on y displacement |
fa7831fb | 483 | ProcessCenterPad(); |
fc0946a7 | 484 | |
5198d8c6 | 485 | // process resolution dependency on drift legth and drift cell width |
9462866a | 486 | ProcessSigma(); |
487 | ||
488 | // process systematic shift on drift legth and drift cell width | |
fa7831fb | 489 | ProcessMean(); |
fc0946a7 | 490 | |
491 | return kTRUE; | |
b2dc316d | 492 | } |
493 | ||
6bc4a8f4 | 494 | //_______________________________________________________ |
9462866a | 495 | Bool_t AliTRDclusterResolution::SetExB(Int_t det, Int_t col, Int_t row) |
6bc4a8f4 | 496 | { |
497 | // check OCDB | |
498 | AliCDBManager *cdb = AliCDBManager::Instance(); | |
499 | if(cdb->GetRun() < 0){ | |
500 | AliError("OCDB manager not properly initialized"); | |
501 | return kFALSE; | |
502 | } | |
503 | ||
504 | // check magnetic field | |
505 | if(TMath::Abs(AliTracker::GetBz()) < 1.e-10){ | |
506 | AliWarning("B=0. Magnetic field may not be initialized. Continue if you know what you are doing !"); | |
507 | } | |
508 | ||
509 | // set reference detector if any | |
510 | if(det>=0 && det<AliTRDgeometry::kNdet) fDet = det; | |
511 | else det = 0; | |
512 | ||
513 | AliTRDcalibDB *fCalibration = AliTRDcalibDB::Instance(); | |
514 | AliTRDCalROC *fCalVdriftROC = fCalibration->GetVdriftROC(det); | |
515 | const AliTRDCalDet *fCalVdriftDet = fCalibration->GetVdriftDet(); | |
516 | ||
9462866a | 517 | fVdrift = fCalVdriftDet->GetValue(det) * fCalVdriftROC->GetValue(col, row); |
518 | fExB = fCalibration->GetOmegaTau(fVdrift, -0.1*AliTracker::GetBz()); | |
6bc4a8f4 | 519 | SetBit(kExB); |
520 | return kTRUE; | |
521 | } | |
b2dc316d | 522 | |
9462866a | 523 | //_______________________________________________________ |
524 | void AliTRDclusterResolution::ProcessCharge() | |
525 | { | |
526 | TH2I *h2 = 0x0; | |
527 | if((h2 = (TH2I*)fContainer->At(kQRes))) { | |
528 | AliWarning("Missing dy=f(Q) histo"); | |
529 | return; | |
530 | } | |
531 | TF1 f("f", "gaus", -.5, .5); | |
532 | TAxis *ax = 0x0; | |
533 | TH1D *h1 = 0x0; | |
534 | ||
535 | TObjArray *arr = (TObjArray*)fResults->At(kQRes); | |
536 | TGraphErrors *gqm = (TGraphErrors*)arr->At(0); | |
537 | TGraphErrors *gqs = (TGraphErrors*)arr->At(1); | |
538 | TGraphErrors *gqp = (TGraphErrors*)arr->At(2); | |
539 | Double_t q, n = 0., entries; | |
540 | ax = h2->GetXaxis(); | |
541 | for(Int_t ix=1; ix<=ax->GetNbins(); ix++){ | |
542 | Double_t q = TMath::Exp(ax->GetBinCenter(ix)); | |
543 | if(q<20. || q>250.) continue; // ?! | |
544 | ||
545 | h1 = h2->ProjectionY("py", ix, ix); | |
546 | entries = h1->GetEntries(); | |
547 | if(entries < 50) continue; | |
548 | Adjust(&f, h1); | |
549 | h1->Fit(&f, "Q"); | |
550 | ||
551 | // Fill sy^2 = f(q) | |
552 | Int_t ip = gqm->GetN(); | |
553 | gqm->SetPoint(ip, q, 10.*f.GetParameter(1)); | |
554 | gqm->SetPointError(ip, 0., 10.*f.GetParError(1)); | |
555 | ||
556 | // correct sigma for ExB effect | |
557 | gqs->SetPoint(ip, q, 1.e1*f.GetParameter(2)/**f.GetParameter(2)-exb2*sxd2*/); | |
558 | gqs->SetPointError(ip, 0., 1.e1*f.GetParError(2)/**f.GetParameter(2)*/); | |
559 | ||
560 | // save probability | |
561 | n += entries; | |
562 | gqp->SetPoint(ip, q, entries); | |
563 | gqp->SetPointError(ip, 0., 0./*TMath::Sqrt(entries)*/); | |
564 | } | |
565 | ||
566 | // normalize probability and get mean sy | |
567 | Double_t sm = 0., sy; | |
568 | for(Int_t ip=gqp->GetN(); ip--;){ | |
569 | gqp->GetPoint(ip, q, entries); | |
570 | entries/=n; | |
571 | gqp->SetPoint(ip, q, entries); | |
572 | gqs->GetPoint(ip, q, sy); | |
573 | sm += entries*sy; | |
574 | } | |
575 | ||
576 | // error parametrization s(q) = <sy> + b(1/q-1/q0) | |
577 | TF1 fq("fq", "[0] + [1]/x", 20., 250.); | |
578 | gqs->Fit(&fq); | |
579 | printf("sy(Q) :: sm[%f] b[%f] 1/q0[%f]\n", sm, fq.GetParameter(1), (sm-fq.GetParameter(0))/fq.GetParameter(1)); | |
580 | } | |
581 | ||
582 | //_______________________________________________________ | |
583 | void AliTRDclusterResolution::ProcessCenterPad() | |
584 | { | |
585 | TObjArray *arr = (TObjArray*)fContainer->At(kCenter); | |
586 | if(!arr) { | |
587 | AliWarning("Missing dy=f(y_d) container"); | |
588 | return; | |
589 | } | |
590 | TF1 f("f", "gaus", -.5, .5); | |
591 | TAxis *ax = 0x0; | |
592 | TH1D *h1 = 0x0; | |
593 | TH2I *h2 = 0x0; | |
594 | ||
595 | TObjArray *arrg = (TObjArray*)fResults->At(kCenter); | |
596 | TH2F *hym = (TH2F*)arrg->At(0); | |
597 | TH2F *hys = (TH2F*)arrg->At(1); | |
fa7831fb | 598 | TH2F *hyp = (TH2F*)arrg->At(2); |
9462866a | 599 | for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){ |
600 | if(!(h2 = (TH2I*)arr->At(ily))) continue; | |
601 | ax = h2->GetXaxis(); | |
602 | for(Int_t ix=1; ix<=ax->GetNbins(); ix++){ | |
603 | Float_t yd = ax->GetBinCenter(ix); | |
604 | h1 = h2->ProjectionY("py", ix, ix); | |
fa7831fb | 605 | Int_t entries = (Int_t)h1->GetEntries(); |
606 | if(entries < 50) continue; | |
607 | //Adjust(&f, h1); | |
9462866a | 608 | h1->Fit(&f, "Q"); |
609 | ||
610 | // Fill sy = f(y_w) | |
fa7831fb | 611 | hyp->Fill(ily, yd, entries); |
9462866a | 612 | hym->Fill(ily, yd, f.GetParameter(1)); |
fa7831fb | 613 | //hym->SetPointError(ip, 0., f.GetParError(1)); |
9462866a | 614 | hys->Fill(ily, yd, f.GetParameter(2)); |
fa7831fb | 615 | //hys->SetPointError(ip, 0., f.GetParError(2)); |
9462866a | 616 | } |
617 | } | |
fa7831fb | 618 | |
619 | // postprocess spectra | |
620 | TCanvas *c = new TCanvas; | |
621 | TF1 fgaus("fgaus", "gaus", -.5, .5); | |
622 | for(Int_t ily=0; ily<AliTRDgeometry::kNlayer; ily++){ | |
623 | h1 = hys->ProjectionY("pyy", ily+1, ily+1); | |
624 | ||
625 | c->cd(); | |
626 | h1->Fit(&fgaus, "Q"); | |
627 | c->Modified(); c->Update(); gSystem->Sleep(500); | |
628 | printf(" {%5.3e, %5.3e, %5.3e, ", fgaus.GetParameter(0), fgaus.GetParameter(1), fgaus.GetParameter(2)); | |
629 | ||
630 | Float_t sy = 0.; | |
631 | h1 = hyp->ProjectionY("pyy", ily+1, ily+1); | |
632 | for(Int_t ix=1; ix<=h1->GetNbinsX(); ix++){ | |
633 | sy += fgaus.Eval(h1->GetBinCenter(ix))*h1->GetBinContent(ix); | |
634 | // printf("ix[%d] gaus[%e] p[%d]\n", ix, fgaus.Eval(h1->GetBinCenter(ix)), (Int_t)h1->GetBinContent(ix)); | |
635 | } | |
636 | sy /= h1->GetEntries(); | |
637 | printf("%5.3e},\n", sy); | |
638 | } | |
639 | ||
9462866a | 640 | } |
641 | ||
642 | //_______________________________________________________ | |
643 | void AliTRDclusterResolution::ProcessSigma() | |
644 | { | |
645 | TObjArray *arr = (TObjArray*)fContainer->At(kSigm); | |
646 | if(!arr){ | |
647 | AliWarning("Missing dy=f(x_d, d_wire) container"); | |
648 | return; | |
649 | } | |
650 | TLinearFitter gs(1,"pol1"); | |
651 | TF1 f("f", "gaus", -.5, .5); | |
652 | TAxis *ax = 0x0; | |
653 | TH1D *h1 = 0x0; | |
654 | TH2I *h2 = 0x0; | |
655 | ||
656 | Double_t d(0.), x(0.), sx, sy; | |
657 | TObjArray *arrr = (TObjArray*)fResults->At(kSigm); | |
658 | TH2F *hsx = (TH2F*)arrr->At(0); | |
659 | TH2F *hsy = (TH2F*)arrr->At(1); | |
660 | for(Int_t id=1; id<=fAd->GetNbins(); id++){ | |
661 | d = fAd->GetBinCenter(id); //[mm] | |
662 | printf(" Doing d = %f[mm]\n", d); | |
663 | for(Int_t it=1; it<=fAt->GetNbins(); it++){ | |
664 | x = fAt->GetBinCenter(it); //[mm] | |
665 | printf(" Doing xd = %f[mm]\n", x); | |
666 | Int_t idx = (id-1)*kNTB+it-1; | |
667 | ||
668 | // retrieve data histogram | |
669 | if(!(h2 = (TH2I*)arr->At(idx))) { | |
670 | AliWarning(Form("Missing histo at index idx[%3d] [id[%2d] it[%2d]] xd[%f] d[%f]\n", idx, id, it, x, d)); | |
671 | continue; | |
672 | } | |
673 | gs.ClearPoints(); | |
674 | ax = h2->GetXaxis(); | |
675 | for(Int_t ix=1; ix<=ax->GetNbins(); ix++){ | |
676 | Float_t dydx = ax->GetBinCenter(ix); | |
677 | Double_t tgg = (dydx-fExB)/(1.+dydx*fExB); | |
678 | Double_t tgg2 = tgg*tgg; | |
679 | h1 = h2->ProjectionY("py", ix, ix); | |
680 | if(h1->GetEntries() < 100) continue; | |
681 | //Adjust(&f, h1); | |
682 | printf("\tFit ix[%d] on %s entries [%d]\n", ix, h2->GetName(), (Int_t)h1->GetEntries()); | |
683 | h1->Fit(&f, "QN"); | |
684 | ||
685 | // Fill sy^2 = f(tg^2(phi-a_L)) | |
686 | gs.AddPoint(&tgg2, 1.e2*f.GetParameter(2)*f.GetParameter(2), 2.e2*f.GetParameter(2)*f.GetParError(2)); | |
687 | } | |
688 | if(gs.Eval()) continue; | |
689 | sx = TMath::Sqrt(gs.GetParameter(1)); | |
690 | sy = TMath::Sqrt(gs.GetParameter(0)); | |
691 | printf("sx[%f] sy[%f] [mm]\n", sx, sy); | |
692 | ||
693 | hsx->SetBinContent(id, it, sx); | |
694 | //hsx->SetBinError(id, it, sig.GetParError(1)); | |
695 | ||
696 | // s^2_y = s0^2_y + tg^2(a_L) * s^2_x | |
697 | hsy->SetBinContent(id, it, sy/* - exb2*sig.GetParameter(1)*/); | |
698 | //hsy->SetBinError(id, it, sig.GetParError(0)+exb2*exb2*sig.GetParError(1)); | |
699 | } | |
700 | } | |
701 | ||
702 | // fit sy parallel to the drift | |
703 | h1 = hsy->ProjectionY("pyy"); h1->Scale(1./hsy->GetNbinsX()); | |
704 | TF1 fsyD("fsy", "[0]+exp([1]*(x+[2]))", 0.5, 3.5); | |
705 | h1->Fit(&fsyD); | |
706 | ||
707 | ||
708 | // fit sx parallel to the drift | |
709 | h1 = hsx->ProjectionY("pyy"); h1->Scale(1./hsx->GetNbinsX()); | |
710 | TF1 fsxD("fsx", "gaus(0)+expo(3)", 0., 3.5); | |
711 | h1->Fit(&fsxD); | |
712 | ||
713 | // fit sx perpendicular to the drift | |
714 | Int_t nb = 0; | |
715 | TAxis *ay = hsx->GetYaxis(); | |
716 | TH1D *hx = hsx->ProjectionX("px", 1,1); | |
717 | TH1D *hAn = (TH1D*)hx->Clone("hAn"); hAn->Reset(); | |
718 | for(Int_t ib = 11; ib<24; ib++, nb++){ | |
719 | hx = hsx->ProjectionX("px", ib, ib); | |
720 | for(Int_t id=1; id<=hx->GetNbinsX(); id++) | |
721 | hx->SetBinContent(id, hx->GetBinContent(id)-fsxD.Eval(ay->GetBinCenter(ib))); | |
722 | hAn->Add(hx); | |
723 | } | |
724 | hAn->Scale(1./nb); | |
725 | hAn->Fit("pol2"); | |
726 | } | |
727 | ||
728 | //_______________________________________________________ | |
729 | void AliTRDclusterResolution::ProcessMean() | |
730 | { | |
731 | TObjArray *arr = (TObjArray*)fContainer->At(kMean); | |
732 | if(!arr){ | |
733 | AliWarning("Missing dy=f(x_d, d_wire) container"); | |
734 | return; | |
735 | } | |
736 | TGraphErrors *gm = new TGraphErrors(); | |
737 | TF1 f("f", "gaus", -.5, .5); | |
738 | TF1 line("l", Form("%6.4f*[0]+[1]", fExB), -.12, .12); | |
739 | Double_t d(0.), x(0.), dx, x0; | |
740 | TAxis *ax = 0x0; | |
741 | TH1D *h1 = 0x0; | |
742 | TH2I *h2 = 0x0; | |
743 | ||
744 | TCanvas *c=new TCanvas; | |
745 | ||
746 | TObjArray *arrr = (TObjArray*)fResults->At(kMean); | |
747 | TH2F *hdx = (TH2F*)arrr->At(0); | |
748 | TH2F *hx0 = (TH2F*)arrr->At(1); | |
749 | for(Int_t id=1; id<=fAd->GetNbins(); id++){ | |
750 | d = fAd->GetBinCenter(id); //[mm] | |
751 | printf(" Doing d = %f[mm]\n", d); | |
752 | for(Int_t it=1; it<=fAt->GetNbins(); it++){ | |
753 | x = fAt->GetBinCenter(it); //[mm] | |
754 | printf(" Doing xd = %f[mm]\n", x); | |
755 | Int_t idx = (id-1)*kNTB+it-1; | |
756 | if(!(h2 = (TH2I*)arr->At(idx))) { | |
757 | AliWarning(Form("Missing histo at index idx[%3d] [id[%2d] it[%2d]] xd[%f] d[%f]\n", idx, id, it, x, d)); | |
758 | continue; | |
759 | } | |
760 | Int_t ip = 0; | |
761 | ax = h2->GetXaxis(); | |
762 | for(Int_t ix=1; ix<=ax->GetNbins(); ix++){ | |
763 | Double_t dydx = ax->GetBinCenter(ix); | |
764 | h1 = h2->ProjectionY("py", ix, ix); | |
765 | if(h1->GetEntries() < 50) continue; | |
766 | //Adjust(&f, h1); | |
767 | //printf("\tFit ix[%d] on %s entries [%d]\n", ix, h2->GetName(), (Int_t)h1->GetEntries()); | |
768 | h1->Fit(&f, "QN"); | |
769 | ||
770 | // Fill <Dy> = f(dydx - h*dzdx) | |
771 | gm->SetPoint(ip, dydx, 10.*f.GetParameter(1)); | |
772 | gm->SetPointError(ip, 0., 10.*f.GetParError(1)); | |
773 | ip++; | |
774 | } | |
775 | if(gm->GetN()<4) continue; | |
776 | ||
777 | gm->Fit(&line, "QN"); | |
778 | c->cd(); | |
779 | gm->Draw("apl"); | |
780 | c->Modified(); c->Update(); gSystem->Sleep(500); | |
781 | dx = line.GetParameter(1); // = (fVdrift + dVd)*(fT + tCorr); | |
782 | x0 = line.GetParameter(0); // = tg(a_L)*dx | |
783 | printf(" dx[%f] x0[%f] [mm]\n", dx, x0); | |
784 | ||
785 | hdx->SetBinContent(id, it, dx); | |
786 | hx0->SetBinContent(id, it, x0); | |
787 | } | |
788 | } | |
789 | ||
790 | TH1D *h=hdx->ProjectionY("py"); h->Scale(1./hdx->GetNbinsX()); | |
791 | } |