]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/AliTRDcluster.cxx
a1fec9cfdafba719114949e1de8ec32cab0e557d
[u/mrichter/AliRoot.git] / TRD / AliTRDcluster.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial 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$ */
17
18  
19 ///////////////////////////////////////////////////////////////////////////////
20 //                                                                           //
21 //  TRD cluster                                                              //
22 //                                                                           //
23 /////////////////////////////////////////////////////////////////////////////// 
24
25 #include "TMath.h"
26
27 #include "AliLog.h"
28 #include "AliTRDcluster.h"
29 #include "AliTRDgeometry.h"
30 #include "AliTRDCommonParam.h"
31
32 ClassImp(AliTRDcluster)
33
34 const Int_t AliTRDcluster::fgkNlut = 128;
35 Double_t *AliTRDcluster::fgLUT = 0x0;
36
37 //___________________________________________________________________________
38 AliTRDcluster::AliTRDcluster() 
39   :AliCluster() 
40   ,fPadCol(0)
41   ,fPadRow(0)
42   ,fPadTime(0)
43   ,fLocalTimeBin(0)
44   ,fNPads(0)
45   ,fClusterMasking(0)
46   ,fDetector(0)
47   ,fQ(0)
48   ,fCenter(0)
49
50   //
51   // Default constructor
52   //
53
54   for (Int_t i = 0; i < 7; i++) {
55     fSignals[i] = 0;
56   }
57   SetBit(kLUT);
58 }
59
60 //___________________________________________________________________________
61 AliTRDcluster::AliTRDcluster(Int_t det, UChar_t col, UChar_t row, UChar_t time, const Short_t *sig, UShort_t vid) 
62   :AliCluster() 
63   ,fPadCol(col)
64   ,fPadRow(row)
65   ,fPadTime(time)
66   ,fLocalTimeBin(0)
67   ,fNPads(0)
68   ,fClusterMasking(0)
69   ,fDetector(det)
70   ,fQ(0.)
71   ,fCenter(0.)
72
73   //
74   // Constructor for self constructing cluster. In this approach the information is inserted gradualy into the 
75   // cluster and all dependencies are (re)calculated inside the cluster itself.
76   //
77   // A.Bercuci <A.Bercuci@gsi.de>
78
79   memcpy(&fSignals, sig, 7*sizeof(Short_t));
80   fQ = fSignals[2]+fSignals[3]+fSignals[4];
81   SetVolumeId(vid);
82   SetBit(kLUT);
83 }
84
85 //___________________________________________________________________________
86 AliTRDcluster::AliTRDcluster(Int_t det, Float_t q
87                            , Float_t *pos, Float_t *sig
88                            , Int_t *tracks, Char_t npads, Short_t *signals
89                            , UChar_t col, UChar_t row, UChar_t time
90                            , Char_t timebin, Float_t center, UShort_t volid)
91   :AliCluster(volid,pos[0],pos[1],pos[2],sig[0],sig[1],0.0,0x0) 
92   ,fPadCol(col)
93   ,fPadRow(row)
94   ,fPadTime(time)
95   ,fLocalTimeBin(timebin)
96   ,fNPads(npads)
97   ,fClusterMasking(0)
98   ,fDetector(det)
99   ,fQ(q)
100   ,fCenter(center)
101
102   //
103   // Constructor
104   //
105
106   for (Int_t i = 0; i < 7; i++) {
107     fSignals[i] = signals[i];
108   }
109
110   if (tracks) {
111     AddTrackIndex(tracks);
112   }
113   SetBit(kLUT);
114 }
115
116 //_____________________________________________________________________________
117 AliTRDcluster::AliTRDcluster(const AliTRDcluster &c)
118   :AliCluster(c)
119   ,fPadCol(c.fPadCol)
120   ,fPadRow(c.fPadRow)
121   ,fPadTime(c.fPadTime)
122   ,fLocalTimeBin(c.fLocalTimeBin)
123   ,fNPads(c.fNPads)
124   ,fClusterMasking(c.fClusterMasking)
125   ,fDetector(c.fDetector)
126   ,fQ(c.fQ)
127   ,fCenter(c.fCenter)
128 {
129   //
130   // Copy constructor 
131   //
132
133   SetLabel(c.GetLabel(0),0);
134   SetLabel(c.GetLabel(1),1);
135   SetLabel(c.GetLabel(2),2);
136
137   SetY(c.GetY());
138   SetZ(c.GetZ());
139   AliCluster::SetSigmaY2(c.GetSigmaY2());
140   SetSigmaZ2(c.GetSigmaZ2());  
141
142   for (Int_t i = 0; i < 7; i++) {
143     fSignals[i] = c.fSignals[i];
144   }
145
146 }
147
148 //_____________________________________________________________________________
149 void AliTRDcluster::AddTrackIndex(Int_t *track)
150 {
151   //
152   // Adds track index. Currently assumed that track is an array of
153   // size 9, and up to 3 track indexes are stored in fTracks[3].
154   // Indexes are sorted according to:
155   //  1) index of max number of appearances is stored first
156   //  2) if two or more indexes appear equal number of times, the lowest
157   //     ones are stored first;
158   //
159
160   const Int_t kSize = 9;
161   Int_t  entries[kSize][2];
162
163   Int_t  i = 0;
164   Int_t  j = 0;
165   Int_t  k = 0;
166   Int_t  index;
167   Bool_t indexAdded;
168
169   for (i = 0; i < kSize; i++) {
170     entries[i][0] = -1;
171     entries[i][1] =  0;
172   }                                 
173
174   for (k = 0; k < kSize; k++) {
175
176     index      = track[k];
177     indexAdded = kFALSE; 
178
179     j = 0;
180     if (index >= 0) {
181       while ((!indexAdded) && (j < kSize)) {
182         if ((entries[j][0] == index) || 
183             (entries[j][1] ==     0)) {
184           entries[j][0] = index;
185           entries[j][1] = entries[j][1] + 1;
186           indexAdded    = kTRUE;
187         }
188         j++;
189       }
190     }
191
192   }
193
194   // Sort by number of appearances and index value
195   Int_t swap = 1;
196   Int_t tmp0;
197   Int_t tmp1;
198   while (swap > 0) {
199     swap = 0;
200     for (i = 0; i < (kSize - 1); i++) {
201       if ((entries[i][0]   >= 0) && 
202           (entries[i+1][0] >= 0)) {
203         if ((entries[i][1] < entries[i+1][1]) ||
204             ((entries[i][1] == entries[i+1][1]) &&
205              (entries[i][0] >  entries[i+1][0]))) {
206           tmp0            = entries[i][0];
207           tmp1            = entries[i][1];
208           entries[i][0]   = entries[i+1][0];
209           entries[i][1]   = entries[i+1][1];
210           entries[i+1][0] = tmp0;
211           entries[i+1][1] = tmp1;
212           swap++;
213         }
214       }
215     }
216   }               
217
218   // Set track indexes
219   for (i = 0; i < 3; i++) {
220     SetLabel(entries[i][0],i);
221   }
222
223   return;
224
225 }          
226
227 //_____________________________________________________________________________
228 void AliTRDcluster::Clear(Option_t *)
229 {
230   //
231   // Reset all member to the default value
232   //
233   fPadCol=0;
234   fPadRow=0;
235   fPadTime=0;
236   fLocalTimeBin=0;
237   fNPads=0;
238   fClusterMasking=0;
239   fDetector=0;
240   for (Int_t i=0; i < 7; i++) fSignals[i]=0;
241   fQ = 0;
242   fCenter = 0;
243   for (Int_t i = 0; i < 3; i++) SetLabel(0,i);
244   SetX(0.);
245   SetY(0.);
246   SetZ(0.);
247   AliCluster::SetSigmaY2(0.);
248   SetSigmaZ2(0.);
249   SetVolumeId(0);
250 }
251
252 //_____________________________________________________________________________
253 Float_t AliTRDcluster::GetSumS() const
254 {
255   //
256   // Returns the total charge from a not unfolded cluster
257   //
258
259   Float_t sum = 0.0;
260   for (Int_t i = 0; i < 7; i++) {
261     sum += fSignals[i];
262   }
263
264   return sum;
265
266 }
267
268 //___________________________________________________________________________
269 Double_t AliTRDcluster::GetSX(Int_t tb, Double_t z)
270 {
271 // Returns the error parameterization in the radial direction for TRD clusters as function of 
272 // the calibrated time bin (tb) and optionally distance to anode wire (z). By default (no z information) 
273 // the mean value over all cluster to wire distance is chosen.
274 // 
275 // There are several contributions which are entering in the definition of the radial errors of the clusters. 
276 // Although an analytic defition should be possible for the moment this is not yet available but instead a 
277 // numerical parameterization is provided (see AliTRDclusterResolution::ProcessSigma() for the calibration 
278 // method). The result is displayed in the figure below as a 2D plot and also as the projection on the drift axis. 
279 //
280 //Begin_Html
281 //<img src="TRD/clusterXerrorDiff2D.gif">
282 //End_Html
283 //
284 // Here is a list of uncertainty components:
285 // - Time Response Function (TRF) - the major contribution. since TRF is also not symmetric (even if tail is 
286 //   cancelled) it also creates a systematic shift dependent on the charge distribution before and after the cluster.
287 // - longitudinal diffusion - increase the width of TRF and scales with square root of drift length
288 // - variation in the drift velocity within the drift cell 
289 //
290 // Author
291 // A.Bercuci <A.Bercuci@gsi.de>
292
293   if(tb<1 || tb>=24) return 10.; // return huge [10cm]
294   const Double_t sx[24][10]={
295     {0.000e+00, 9.352e-01, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 2.309e+00},
296     {8.387e-02, 8.718e-02, 8.816e-02, 9.444e-02, 9.993e-02, 1.083e-01, 1.161e-01, 1.280e-01, 1.417e-01, 1.406e-01},
297     {1.097e-01, 1.105e-01, 1.127e-01, 1.151e-01, 1.186e-01, 1.223e-01, 1.272e-01, 1.323e-01, 1.389e-01, 1.490e-01},
298     {1.407e-01, 1.404e-01, 1.414e-01, 1.430e-01, 1.429e-01, 1.449e-01, 1.476e-01, 1.494e-01, 1.515e-01, 1.589e-01},
299     {1.681e-01, 1.679e-01, 1.666e-01, 1.657e-01, 1.656e-01, 1.649e-01, 1.652e-01, 1.662e-01, 1.671e-01, 1.694e-01},
300     {1.745e-01, 1.737e-01, 1.707e-01, 1.690e-01, 1.643e-01, 1.610e-01, 1.612e-01, 1.628e-01, 1.638e-01, 1.659e-01},
301     {1.583e-01, 1.558e-01, 1.535e-01, 1.488e-01, 1.445e-01, 1.419e-01, 1.428e-01, 1.451e-01, 1.462e-01, 1.494e-01},
302     {1.414e-01, 1.391e-01, 1.368e-01, 1.300e-01, 1.256e-01, 1.259e-01, 1.285e-01, 1.326e-01, 1.358e-01, 1.406e-01},
303     {1.307e-01, 1.289e-01, 1.261e-01, 1.216e-01, 1.193e-01, 1.165e-01, 1.201e-01, 1.241e-01, 1.274e-01, 1.344e-01},
304     {1.251e-01, 1.227e-01, 1.208e-01, 1.155e-01, 1.110e-01, 1.116e-01, 1.133e-01, 1.187e-01, 1.229e-01, 1.308e-01},
305     {1.234e-01, 1.209e-01, 1.175e-01, 1.127e-01, 1.094e-01, 1.093e-01, 1.109e-01, 1.155e-01, 1.210e-01, 1.275e-01},
306     {1.215e-01, 1.187e-01, 1.156e-01, 1.108e-01, 1.070e-01, 1.065e-01, 1.090e-01, 1.134e-01, 1.196e-01, 1.251e-01},
307     {1.202e-01, 1.180e-01, 1.151e-01, 1.108e-01, 1.070e-01, 1.058e-01, 1.089e-01, 1.127e-01, 1.183e-01, 1.256e-01},
308     {1.207e-01, 1.176e-01, 1.142e-01, 1.109e-01, 1.072e-01, 1.069e-01, 1.088e-01, 1.122e-01, 1.182e-01, 1.252e-01},
309     {1.213e-01, 1.182e-01, 1.156e-01, 1.102e-01, 1.076e-01, 1.063e-01, 1.091e-01, 1.132e-01, 1.181e-01, 1.243e-01},
310     {1.205e-01, 1.180e-01, 1.150e-01, 1.104e-01, 1.072e-01, 1.063e-01, 1.083e-01, 1.132e-01, 1.183e-01, 1.243e-01},
311     {1.212e-01, 1.195e-01, 1.135e-01, 1.107e-01, 1.070e-01, 1.065e-01, 1.097e-01, 1.126e-01, 1.185e-01, 1.238e-01},
312     {1.201e-01, 1.184e-01, 1.155e-01, 1.111e-01, 1.088e-01, 1.075e-01, 1.089e-01, 1.131e-01, 1.189e-01, 1.237e-01},
313     {1.197e-01, 1.186e-01, 1.147e-01, 1.113e-01, 1.085e-01, 1.077e-01, 1.105e-01, 1.137e-01, 1.188e-01, 1.245e-01},
314     {1.213e-01, 1.194e-01, 1.154e-01, 1.114e-01, 1.091e-01, 1.082e-01, 1.098e-01, 1.140e-01, 1.194e-01, 1.247e-01},
315     {1.210e-01, 1.189e-01, 1.155e-01, 1.119e-01, 1.088e-01, 1.080e-01, 1.105e-01, 1.141e-01, 1.195e-01, 1.244e-01},
316     {1.196e-01, 1.189e-01, 1.145e-01, 1.105e-01, 1.095e-01, 1.083e-01, 1.087e-01, 1.121e-01, 1.173e-01, 1.208e-01},
317     {1.123e-01, 1.129e-01, 1.108e-01, 1.110e-01, 1.080e-01, 1.065e-01, 1.056e-01, 1.066e-01, 1.071e-01, 1.095e-01},
318     {1.136e-01, 1.135e-01, 1.130e-01, 1.122e-01, 1.113e-01, 1.071e-01, 1.041e-01, 1.025e-01, 1.014e-01, 9.973e-02}
319   };
320   if(z>=0. && z<.25) return sx[tb][Int_t(z/.025)];
321   
322   Double_t m = 0.; for(Int_t id=10; id--;) m+=sx[tb][id];
323   return m*.1;
324 }
325
326 //___________________________________________________________________________
327 Double_t AliTRDcluster::GetSYdrift(Int_t tb, Int_t ly, Double_t/* z*/)
328 {
329 // Returns the error parameterization for TRD clusters as function of the drift length (here calibrated time bin tb)
330 // and optionally distance to anode wire (z) for the LUT r-phi cluster shape. By default (no z information) the largest 
331 // value over all cluster to wire values is chosen.
332 // 
333 // For the LUT method the dependence of s_y with x and d is obtained via a fit to the cluster to MC 
334 // resolution. (see class AliTRDclusterResolution for more details). A normalization to the reference radial position
335 // x0 = 0.675 (tb=5 for ideal vd) is also applied (see GetSYprf()). The function is *NOT* calibration aware ! 
336 // The result is displayed in the figure below as a 2D plot and also as the projection on the drift axis. A comparison 
337 // with the GAUS parameterization is also given
338 //
339 // For the GAUS method the dependence of s_y with x is *analytic* and it is expressed by the relation.
340 // BEGIN_LATEX
341 // #sigma^{2}_{y} = #sigma^{2}_{PRF} + #frac{x#delta_{t}^{2}}{(1+tg(#alpha_{L}))^{2}}
342 // END_LATEX
343 // The result is displayed in the figure below as function of the drift time and compared with the LUT parameterization.
344 //Begin_Html
345 //<img src="TRD/clusterYerrorDiff2D.gif">
346 //<img src="TRD/clusterYerrorDiff1D.gif">
347 //End_Html
348 //
349 // Author
350 // A.Bercuci <A.Bercuci@gsi.de>
351
352
353   if(tb<1 || tb>=24) return 10.; // return huge [10cm]
354   const Float_t lSy[6][24] = {
355     {75.7561, 0.0325, 0.0175, 0.0174, 0.0206, 0.0232,
356      0.0253, 0.0262, 0.0265, 0.0264, 0.0266, 0.0257,
357      0.0258, 0.0261, 0.0259, 0.0253, 0.0257, 0.0261,
358      0.0255, 0.0250, 0.0259, 0.0266, 0.0278, 0.0319
359     },
360     {49.2252, 0.0371, 0.0204, 0.0189, 0.0230, 0.0261,
361      0.0281, 0.0290, 0.0292, 0.0286, 0.0277, 0.0279,
362      0.0285, 0.0281, 0.0291, 0.0281, 0.0281, 0.0282,
363      0.0272, 0.0282, 0.0282, 0.0284, 0.0310, 0.0334
364     },
365     {55.1674, 0.0388, 0.0212, 0.0200, 0.0239, 0.0271,
366      0.0288, 0.0299, 0.0306, 0.0300, 0.0296, 0.0303,
367      0.0293, 0.0290, 0.0291, 0.0294, 0.0295, 0.0290,
368      0.0293, 0.0292, 0.0292, 0.0293, 0.0316, 0.0358
369     },
370     {45.1004, 0.0411, 0.0225, 0.0215, 0.0249, 0.0281,
371      0.0301, 0.0315, 0.0320, 0.0308, 0.0318, 0.0321,
372      0.0312, 0.0311, 0.0316, 0.0315, 0.0310, 0.0308,
373      0.0313, 0.0303, 0.0314, 0.0314, 0.0324, 0.0369
374     },
375     {43.8614, 0.0420, 0.0239, 0.0224, 0.0268, 0.0296,
376      0.0322, 0.0336, 0.0333, 0.0326, 0.0321, 0.0325,
377      0.0329, 0.0326, 0.0323, 0.0322, 0.0326, 0.0320,
378      0.0329, 0.0319, 0.0314, 0.0329, 0.0341, 0.0373
379     },
380     {40.5440, 0.0434, 0.0246, 0.0236, 0.0275, 0.0311,
381      0.0332, 0.0345, 0.0347, 0.0347, 0.0340, 0.0336,
382      0.0339, 0.0344, 0.0339, 0.0341, 0.0341, 0.0342,
383      0.0345, 0.0328, 0.0341, 0.0332, 0.0356, 0.0398
384     },
385   };
386   // adjusted ...
387   return TMath::Max(lSy[ly][tb]-0.0150, 0.0010);
388
389 /*  const Double_t sy[24][10]={
390     {0.000e+00, 2.610e-01, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 0.000e+00, 4.680e-01},
391     {3.019e-02, 3.036e-02, 3.131e-02, 3.203e-02, 3.294e-02, 3.407e-02, 3.555e-02, 3.682e-02, 3.766e-02, 3.824e-02},
392     {1.773e-02, 1.778e-02, 1.772e-02, 1.790e-02, 1.807e-02, 1.833e-02, 1.873e-02, 1.905e-02, 1.958e-02, 2.029e-02},
393     {1.774e-02, 1.772e-02, 1.746e-02, 1.738e-02, 1.756e-02, 1.756e-02, 1.739e-02, 1.720e-02, 1.743e-02, 1.769e-02},
394     {2.064e-02, 2.078e-02, 2.069e-02, 2.060e-02, 2.033e-02, 2.024e-02, 2.022e-02, 1.961e-02, 1.922e-02, 1.901e-02},
395     {2.382e-02, 2.379e-02, 2.371e-02, 2.333e-02, 2.318e-02, 2.285e-02, 2.255e-02, 2.244e-02, 2.174e-02, 2.132e-02},
396     {2.615e-02, 2.589e-02, 2.539e-02, 2.493e-02, 2.420e-02, 2.396e-02, 2.362e-02, 2.342e-02, 2.321e-02, 2.330e-02},
397     {2.640e-02, 2.638e-02, 2.577e-02, 2.548e-02, 2.477e-02, 2.436e-02, 2.416e-02, 2.401e-02, 2.399e-02, 2.402e-02},
398     {2.647e-02, 2.632e-02, 2.587e-02, 2.546e-02, 2.465e-02, 2.447e-02, 2.429e-02, 2.415e-02, 2.429e-02, 2.475e-02},
399     {2.657e-02, 2.637e-02, 2.580e-02, 2.525e-02, 2.492e-02, 2.441e-02, 2.446e-02, 2.441e-02, 2.478e-02, 2.491e-02},
400     {2.640e-02, 2.608e-02, 2.583e-02, 2.539e-02, 2.478e-02, 2.440e-02, 2.456e-02, 2.464e-02, 2.486e-02, 2.533e-02},
401     {2.636e-02, 2.630e-02, 2.584e-02, 2.542e-02, 2.483e-02, 2.451e-02, 2.449e-02, 2.467e-02, 2.496e-02, 2.554e-02},
402     {2.634e-02, 2.629e-02, 2.583e-02, 2.526e-02, 2.480e-02, 2.460e-02, 2.458e-02, 2.472e-02, 2.518e-02, 2.549e-02},
403     {2.629e-02, 2.621e-02, 2.581e-02, 2.527e-02, 2.480e-02, 2.458e-02, 2.451e-02, 2.485e-02, 2.516e-02, 2.547e-02},
404     {2.629e-02, 2.607e-02, 2.573e-02, 2.543e-02, 2.485e-02, 2.464e-02, 2.452e-02, 2.476e-02, 2.505e-02, 2.550e-02},
405     {2.635e-02, 2.613e-02, 2.578e-02, 2.523e-02, 2.491e-02, 2.465e-02, 2.470e-02, 2.467e-02, 2.515e-02, 2.564e-02},
406     {2.613e-02, 2.602e-02, 2.587e-02, 2.526e-02, 2.507e-02, 2.482e-02, 2.456e-02, 2.486e-02, 2.509e-02, 2.572e-02},
407     {2.620e-02, 2.599e-02, 2.563e-02, 2.528e-02, 2.484e-02, 2.462e-02, 2.464e-02, 2.476e-02, 2.513e-02, 2.571e-02},
408     {2.634e-02, 2.596e-02, 2.565e-02, 2.519e-02, 2.497e-02, 2.457e-02, 2.450e-02, 2.481e-02, 2.511e-02, 2.540e-02},
409     {2.593e-02, 2.589e-02, 2.563e-02, 2.511e-02, 2.472e-02, 2.453e-02, 2.452e-02, 2.474e-02, 2.501e-02, 2.543e-02},
410     {2.576e-02, 2.582e-02, 2.526e-02, 2.505e-02, 2.462e-02, 2.446e-02, 2.445e-02, 2.466e-02, 2.486e-02, 2.510e-02},
411     {2.571e-02, 2.549e-02, 2.533e-02, 2.501e-02, 2.453e-02, 2.443e-02, 2.445e-02, 2.450e-02, 2.448e-02, 2.469e-02},
412     {2.812e-02, 2.786e-02, 2.776e-02, 2.723e-02, 2.695e-02, 2.650e-02, 2.642e-02, 2.617e-02, 2.612e-02, 2.610e-02},
413     {3.251e-02, 3.267e-02, 3.223e-02, 3.183e-02, 3.125e-02, 3.106e-02, 3.067e-02, 3.010e-02, 2.936e-02, 2.927e-02}
414   };
415   if(z>=0. && z<.25) return sy[tb][Int_t(z/.025)] -  sy[5][Int_t(z/.025)];
416
417   Double_t m = -1.e8; for(Int_t id=10; id--;) if((sy[tb][id] - sy[5][id])>m) m=sy[tb][id]-sy[5][id];
418
419   return m;*/
420 }
421
422 //___________________________________________________________________________
423 Double_t AliTRDcluster::GetSYcharge(Float_t q)
424 {
425 // Parameterization of the r-phi resolution component due to cluster charge.
426 // The value is the offset from the nominal cluster resolution defined as the
427 // cluster resolution at average cluster charge (q0).
428 // 
429 // BEGIN_LATEX
430 // #Delta #sigma_{y}(q) = a*(#frac{1}{q} - #frac{1}{q_{0}})
431 // q_{0} #approx 50
432 // END_LATEX
433 // The definition is *NOT* robust against gain fluctuations and thus two approaches are possible
434 // when residual miscalibration are available:
435 //   - determine parameterization with a resolution matching those of the gain
436 //   - define an analytic model which scales with the gain.
437 // 
438 // For more details please see AliTRDclusterResolution::ProcessCharge()
439 //
440 //Begin_Html
441 //<img src="TRD/clusterQerror.gif">
442 //End_Html
443 //
444 // Author
445 // A.Bercuci <A.Bercuci@gsi.de>
446
447   const Float_t sq0inv = 0.019962; // [1/q0]
448   const Float_t sqb    = 0.037328; // [cm]
449
450   return sqb*(1./q - sq0inv);
451 }
452
453 //___________________________________________________________________________
454 Double_t AliTRDcluster::GetSYprf(Int_t ly, Double_t center, Double_t s2)
455 {
456 // Parameterization of the cluster error in the r-phi direction due to charge sharing between 
457 // adiacent pads. Should be identical to what is provided in the OCDB as PRF [TODO]
458 //
459 // The parameterization is obtained from fitting cluster resolution at phi=exb and |x-0.675|<0.225. 
460 // For more details see AliTRDclusterResolution::ProcessCenter().
461 //
462 //Begin_Html
463 //<img src="TRD/clusterPRFerror.gif">
464 //End_Html
465 //
466 // Author
467 // A.Bercuci <A.Bercuci@gsi.de>
468
469 /*  const Float_t scy[AliTRDgeometry::kNlayer][4] = {
470     {2.827e-02, 9.600e-04, 4.296e-01, 2.271e-02},
471     {2.952e-02,-2.198e-04, 4.146e-01, 2.339e-02},
472     {3.090e-02, 1.514e-03, 4.020e-01, 2.402e-02},
473     {3.260e-02,-2.037e-03, 3.946e-01, 2.509e-02},
474     {3.439e-02,-3.601e-04, 3.883e-01, 2.623e-02},
475     {3.510e-02, 2.066e-03, 3.651e-01, 2.588e-02},
476   };*/
477   const Float_t lPRF[] = {0.438, 0.403, 0.393, 0.382, 0.376, 0.345};
478
479   return s2*TMath::Gaus(center, 0., lPRF[ly]);
480 }
481
482
483 //___________________________________________________________________________
484 Double_t AliTRDcluster::GetXcorr(Int_t tb, Double_t z)
485 {
486 // Drift length correction [cm]. Due to variation of mean drift velocity along the drift region
487 // from nominal vd at xd->infinity. For drift velocity determination based on tracking information 
488 // the correction should be negligible.
489 //Begin_Html
490 //<img src="TRD/clusterXcorr.gif">
491 //End_Html
492 // TODO to be parametrized in term of drift velocity at infinite drift length
493 // A.Bercuci (Mar 28 2009)
494
495   if(tb<0 || tb>=24) return 0.;
496   const Int_t nd = 5;
497   const Double_t dx[24][nd]={
498     {+1.747e-01,+3.195e-01,+1.641e-01,+1.607e-01,+6.002e-01},
499     {+5.468e-02,+5.760e-02,+6.365e-02,+8.003e-02,+1.067e-01},
500     {-6.327e-02,-6.339e-02,-6.423e-02,-6.900e-02,-7.949e-02},
501     {-1.417e-01,-1.424e-01,-1.450e-01,-1.465e-01,-1.514e-01},
502     {-1.637e-01,-1.619e-01,-1.622e-01,-1.613e-01,-1.648e-01},
503     {-1.386e-01,-1.334e-01,-1.261e-01,-1.276e-01,-1.314e-01},
504     {-8.799e-02,-8.299e-02,-7.861e-02,-8.038e-02,-8.436e-02},
505     {-5.139e-02,-4.849e-02,-4.641e-02,-4.965e-02,-5.286e-02},
506     {-2.927e-02,-2.773e-02,-2.807e-02,-3.021e-02,-3.378e-02},
507     {-1.380e-02,-1.229e-02,-1.335e-02,-1.547e-02,-1.984e-02},
508     {-4.168e-03,-4.601e-03,-5.462e-03,-8.164e-03,-1.035e-02},
509     {+2.044e-03,+1.889e-03,+9.603e-04,-1.342e-03,-3.736e-03},
510     {+3.568e-03,+3.581e-03,+2.391e-03,+2.942e-05,-1.585e-03},
511     {+4.403e-03,+4.571e-03,+3.509e-03,+8.703e-04,-1.425e-03},
512     {+4.941e-03,+4.808e-03,+3.284e-03,+1.105e-03,-1.208e-03},
513     {+5.124e-03,+5.022e-03,+4.305e-03,+2.023e-03,-1.145e-03},
514     {+4.882e-03,+4.008e-03,+3.408e-03,+7.886e-04,-1.356e-03},
515     {+3.852e-03,+3.539e-03,+2.057e-03,+1.670e-04,-1.993e-03},
516     {+2.154e-03,+2.111e-03,+5.723e-04,-1.254e-03,-3.256e-03},
517     {+1.755e-03,+2.101e-03,+9.516e-04,-1.649e-03,-3.394e-03},
518     {+1.617e-03,+1.662e-03,+4.169e-04,-9.843e-04,-4.309e-03},
519     {-9.204e-03,-9.069e-03,-1.182e-02,-1.458e-02,-1.880e-02},
520     {-6.727e-02,-6.820e-02,-6.804e-02,-7.134e-02,-7.615e-02},
521     {-1.802e-01,-1.733e-01,-1.633e-01,-1.601e-01,-1.632e-01}
522   };
523 //   const Double_t dx[24][nd]={
524 //     {+0.000e+00,+0.000e+00,+0.000e+00,+0.000e+00,+0.000e+00,+0.000e+00,+0.000e+00,+0.000e+00,+0.000e+00,+0.000e+00},
525 //     {-2.763e-04,-2.380e-04,-6.286e-04,-9.424e-04,+1.046e-03,+1.932e-03,+1.620e-03,+1.951e-03,-1.321e-03,-1.115e-03},
526 //     {-1.825e-03,-9.245e-04,-1.012e-03,-8.215e-04,+2.703e-05,+1.403e-03,+2.340e-03,+2.577e-03,+2.017e-03,+8.006e-04},
527 //     {-3.070e-03,-8.563e-04,-1.257e-03,+8.491e-05,+4.503e-04,-2.467e-05,-1.793e-04,+5.085e-04,+1.321e-03,+4.056e-04},
528 //     {-3.637e-03,-2.857e-03,-3.098e-03,-2.304e-03,-1.467e-03,-1.755e-03,+4.585e-04,+2.757e-03,+3.184e-03,+3.525e-03},
529 //     {-9.884e-03,-7.695e-03,-7.290e-03,-3.990e-03,-9.982e-04,+2.226e-03,+3.375e-03,+6.419e-03,+7.209e-03,+6.891e-03},
530 //     {-6.844e-03,-5.807e-03,-4.012e-03,-1.566e-03,+5.035e-04,+2.024e-03,+3.225e-03,+3.918e-03,+5.942e-03,+6.024e-03},
531 //     {-2.628e-03,-2.201e-03,-4.562e-04,+9.832e-04,+3.411e-03,+2.062e-03,+1.526e-03,+9.350e-04,+8.842e-04,+1.007e-03},
532 //     {+6.603e-04,+1.545e-03,+1.681e-03,+1.918e-03,+2.165e-03,+1.825e-03,+1.691e-03,-1.923e-04,+1.835e-04,-1.284e-03},
533 //     {+1.895e-03,+1.586e-03,+2.000e-03,+3.537e-03,+2.526e-03,+1.316e-03,+8.229e-04,-7.671e-05,-2.175e-03,-3.528e-03},
534 //     {+2.927e-03,+3.369e-03,+3.603e-03,+2.675e-03,+2.737e-03,+1.133e-03,+4.318e-04,-1.215e-03,-2.443e-03,-3.116e-03},
535 //     {+3.072e-03,+3.564e-03,+3.612e-03,+3.149e-03,+2.768e-03,+1.186e-03,+3.083e-04,-1.447e-03,-2.480e-03,-3.263e-03},
536 //     {+2.697e-03,+3.565e-03,+3.759e-03,+2.855e-03,+2.909e-03,+6.564e-04,-5.224e-04,-3.309e-04,-1.636e-03,-3.739e-03},
537 //     {+3.633e-03,+3.232e-03,+3.727e-03,+3.024e-03,+3.365e-03,+1.598e-03,-6.903e-04,-1.039e-03,-3.176e-03,-4.472e-03},
538 //     {+2.999e-03,+3.942e-03,+3.322e-03,+3.162e-03,+1.978e-03,+1.657e-03,-4.760e-04,-8.343e-04,-2.346e-03,-3.281e-03},
539 //     {+3.734e-03,+3.098e-03,+3.435e-03,+2.512e-03,+2.651e-03,+1.745e-03,+9.424e-04,-1.404e-03,-3.177e-03,-4.444e-03},
540 //     {+3.204e-03,+4.003e-03,+3.068e-03,+2.697e-03,+3.187e-03,+3.878e-04,-1.124e-04,-1.855e-03,-2.584e-03,-3.807e-03},
541 //     {+2.653e-03,+3.631e-03,+2.327e-03,+3.460e-03,+1.810e-03,+1.244e-03,-3.651e-04,-2.664e-04,-2.307e-03,-3.642e-03},
542 //     {+2.538e-03,+3.208e-03,+2.390e-03,+3.519e-03,+1.763e-03,+1.330e-04,+1.669e-04,-1.422e-03,-1.685e-03,-3.519e-03},
543 //     {+2.605e-03,+2.465e-03,+2.771e-03,+2.966e-03,+2.361e-03,+6.029e-04,-4.435e-04,-1.876e-03,-1.694e-03,-3.757e-03},
544 //     {+2.866e-03,+3.315e-03,+3.146e-03,+2.117e-03,+1.933e-03,+9.339e-04,+9.556e-04,-1.314e-03,-3.615e-03,-3.558e-03},
545 //     {+4.002e-03,+3.543e-03,+3.631e-03,+4.127e-03,+1.919e-03,-2.852e-04,-9.484e-04,-2.060e-03,-4.477e-03,-5.491e-03},
546 //     {+6.029e-03,+5.147e-03,+4.286e-03,+2.215e-03,+9.240e-04,-1.554e-03,-2.366e-03,-3.635e-03,-5.372e-03,-6.467e-03},
547 //     {+3.941e-03,+3.995e-03,+5.638e-04,-3.332e-04,-2.539e-03,-3.764e-03,-3.647e-03,-4.900e-03,-5.414e-03,-5.202e-03}
548 //   };
549   if(z>=0. && z<.25) return dx[tb][Int_t(z/.025)];
550
551   Double_t m = 0.; for(Int_t id=nd; id--;) m+=dx[tb][id];
552   return m/nd;
553 }
554
555 //___________________________________________________________________________
556 Double_t AliTRDcluster::GetYcorr(Int_t ly, Float_t y)
557 {
558 // PRF correction for the LUT r-phi cluster shape.
559 //Begin_Html
560 //<img src="TRD/clusterYcorr.gif">
561 //End_Html
562
563   const Float_t cy[AliTRDgeometry::kNlayer][3] = {
564     { 4.014e-04, 8.605e-03, -6.880e+00},
565     {-3.061e-04, 9.663e-03, -6.789e+00},
566     { 1.124e-03, 1.105e-02, -6.825e+00},
567     {-1.527e-03, 1.231e-02, -6.777e+00},
568     { 2.150e-03, 1.387e-02, -6.783e+00},
569     {-1.296e-03, 1.486e-02, -6.825e+00}
570   }; 
571
572   return cy[ly][0] + cy[ly][1] * TMath::Sin(cy[ly][2] * y);
573 }
574
575 //_____________________________________________________________________________
576 Float_t AliTRDcluster::GetXloc(Double_t t0, Double_t vd, Double_t *const /*q*/, Double_t *const /*xq*/, Double_t /*z*/)
577 {
578 //
579 // (Re)Calculate cluster position in the x direction in local chamber coordinates (with respect to the anode wire 
580 // position) using all available information from tracking.
581 // Input parameters:
582 //   t0 - calibration aware trigger delay [us]
583 //   vd - drift velocity in the region of the cluster [cm/us]
584 //   z  - distance to the anode wire [cm]. By default average over the drift cell width.
585 //   q & xq - array of charges and cluster positions from previous clusters in the tracklet [a.u.]
586 // Output values :
587 //   return x position of the cluster with respect to the 
588 //   anode wire using all tracking information
589 //
590 // The estimation of the radial position is based on calculating the drift time and the drift velocity at the point of 
591 // estimation. The drift time can be estimated according to the expression:
592 // BEGIN_LATEX
593 // t_{drift} = t_{bin} - t_{0} - t_{cause}(x) - t_{TC}(q_{i-1}, q_{i-2}, ...)
594 // END_LATEX
595 // where t_0 is the delay of the trigger signal. t_cause is the causality delay between ionisation electrons hitting 
596 // the anode and the registration of maximum signal by the electronics - it is due to the rising time of the TRF 
597 // A second order correction here comes from the fact that the time spreading of charge at anode is the convolution of
598 // TRF with the diffusion and thus cross-talk between clusters before and after local clusters changes with drift length. 
599 // t_TC is the residual charge from previous (in time) clusters due to residual tails after tail cancellation. 
600 // This tends to push cluster forward and depends on the magnitude of their charge.
601 //
602 // The drift velocity varies with the drift length (and distance to anode wire) as described by cell structure simulation. 
603 // Thus one, in principle, can calculate iteratively the drift length from the expression:
604 // BEGIN_LATEX
605 // x = t_{drift}(x)*v_{drift}(x)
606 // END_LATEX
607 // In practice we use a numerical approach (AliTRDcluster::GetXcorr()) to correct for anisochronity obtained from MC 
608 // comparison (see AliTRDclusterResolution::ProcessSigma()). Also the calibration of 0 approximation (no x dependence)
609 // for t_cause is obtained from MC comparisons and impossible to disentangle in real life from trigger delay.
610 //
611 // Author
612 // Alex Bercuci <A.Bercuci@gsi.de>
613 //
614
615   AliTRDCommonParam *cp = AliTRDCommonParam::Instance(); 
616   Double_t fFreq = cp->GetSamplingFrequency();
617
618   //drift time corresponding to the center of the time bin
619   Double_t td = (fPadTime + .5)/fFreq; // [us] 
620   // correction for t0
621   td -= t0;
622   // time bin corrected for t0
623   // Bug in TMath::Nint().root-5.23.02
624   // TMath::Nint(3.5) = 4 and TMath::Nint(4.5) = 4
625   Double_t tmp = td*fFreq;
626   fLocalTimeBin = Char_t(TMath::Floor(tmp));
627   if(tmp-fLocalTimeBin > .5) fLocalTimeBin++;
628   if(td < .2) return 0.;
629   // TRF rising time (fitted)
630   // It should be absorbed by the t0. For the moment t0 is 0 for simulations.
631   // A.Bercuci (Mar 26 2009)
632   td -= 0.189;
633
634   // apply fitted correction 
635   Float_t x = td*vd + GetXcorr(fLocalTimeBin);
636   if(x>0.&&x<.5*AliTRDgeometry::CamHght()+AliTRDgeometry::CdrHght()) SetInChamber();
637
638   return x;
639
640 /*
641   // calculate radial posion of clusters in the drift region
642
643   // invert drift time function
644   Double_t xM= AliTRDgeometry::CamHght()+AliTRDgeometry::CdrHght(),
645            x = vd*td + .5*AliTRDgeometry::CamHght(), 
646            t = cp->TimeStruct(vd, x, z), dx1=0.,dx2;
647   while(TMath::Abs(td-t)>1.e-4){ // convergence on 100ps
648     dx2 = vd*(td-t);
649     if(TMath::Abs(TMath::Abs(dx2)-TMath::Abs(dx1))<1.e-6){
650       x+=.5*dx2;
651       break;
652     } else x+=dx2;
653
654     if(x<0. || x>xM) return 0.;
655     t = cp->TimeStruct(vd, x, z);
656     dx1 = dx2;
657   }
658
659   return x-.5*AliTRDgeometry::CamHght();
660 */
661 }
662
663 //_____________________________________________________________________________
664 Float_t AliTRDcluster::GetYloc(Double_t y0, Double_t s2, Double_t W, Double_t *const y1, Double_t *const y2)
665 {
666 // Calculate, in tracking cooordinate system, the r-phi offset the cluster from the middle of the center pad. Three possible methods are implemented:
667 //   - Center of Gravity (COG) see AliTRDcluster::GetDYcog()
668 //   - Look-up Table (LUT) see AliTRDcluster::GetDYlut()
669 //   - Gauss shape (GAUS) see AliTRDcluster::GetDYgauss()
670 // In addition for the case of LUT method position corrections are also applied (see AliTRDcluster::GetYcorr())
671
672   if(IsRPhiMethod(kCOG)) GetDYcog();
673   else if(IsRPhiMethod(kLUT)) GetDYlut();
674   else if(IsRPhiMethod(kGAUS)) GetDYgauss(s2/W/W, y1, y2);
675   else return 0.;
676
677   if(y1) (*y1)*=W;
678   if(y2) (*y2)*=W;
679
680   return y0+fCenter*W+(IsRPhiMethod(kLUT)?GetYcorr(AliTRDgeometry::GetLayer(fDetector), fCenter):0.);
681 }
682
683 //___________________________________________________________________________
684 void AliTRDcluster::SetSigmaY2(Float_t s2, Float_t dt, Float_t exb, Float_t x, Float_t z, Float_t tgp)
685 {
686 // Set variance of TRD cluster in the r-phi direction for each method.
687 // Parameters :
688 //   - s2  - variance due to PRF width for the case of Gauss model. Replaced by parameterization in case of LUT.
689 //   - dt  - transversal diffusion coeficient 
690 //   - exb - tg of lorentz angle
691 //   - x   - drift length - with respect to the anode wire
692 //   - z   - offset from the anode wire
693 //   - tgp - local tangent of the track momentum azimuthal angle
694 //
695 // The ingredients from which the error is computed are:
696 //   - PRF (charge sharing on adjacent pads)  - see AliTRDcluster::GetSYprf()
697 //   - diffusion (dependence with drift length and [2nd order] distance to anode wire) - see AliTRDcluster::GetSYdrift()
698 //   - charge of the cluster (complex dependence on gain and tail cancellation) - see AliTRDcluster::GetSYcharge()
699 //   - lorentz angle (dependence on the drift length and [2nd order] distance to anode wire) - see AliTRDcluster::GetSX()
700 //   - track angle (superposition of charges on the anode wire) - see AliTRDseedV1::Fit()
701 //   - projection of radial(x) error on r-phi due to fixed value assumed in tracking for x - see AliTRDseedV1::Fit()
702 //
703 // The last 2 contributions to cluster error can be estimated only during tracking when the track angle 
704 // is known (tgp). For this reason the errors (and optional position) of TRD clusters are recalculated during 
705 // tracking and thus clusters attached to tracks might differ from bare clusters.
706 // 
707 // Taking into account all contributions one can write the the TRD cluster error parameterization as:
708 // BEGIN_LATEX
709 // #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
710 // END_LATEX
711 // From this formula one can deduce a that the simplest calibration method for PRF and diffusion contributions is 
712 // by measuring resolution at B=0T and phi=0. To disentangle further the two remaining contributions one has 
713 // to represent s2 as a function of drift length. 
714 // 
715 // In the gaussian model the diffusion contribution can be expressed as:
716 // BEGIN_LATEX
717 // #sigma^{2}_{y} = #sigma^{2}_{PRF} + #frac{x#delta_{t}^{2}}{(1+tg(#alpha_{L}))^{2}}
718 // END_LATEX
719 // thus resulting the PRF contribution. For the case of the LUT model both contributions have to be determined from 
720 // the fit (see AliTRDclusterResolution::ProcessCenter() for details).
721 // 
722 // Author:
723 // A.Bercuci <A.Bercuci@gsi.de>
724
725   Float_t sigmaY2 = 0.;
726   Int_t ly = AliTRDgeometry::GetLayer(fDetector);
727   if(IsRPhiMethod(kCOG)) sigmaY2 = 4.e-4;
728   else if(IsRPhiMethod(kLUT)){ 
729     Float_t sd = GetSYdrift(fLocalTimeBin, ly, z); //printf("drift[%6.2f] ", 1.e4*sd);
730     sigmaY2 = GetSYprf(ly, fCenter, sd); //printf("PRF[%6.2f] ", 1.e4*sigmaY2);
731     // add charge contribution TODO scale with respect to s2
732     sigmaY2+= GetSYcharge(TMath::Abs(fQ)); //printf("Q[%6.2f] ", 1.e4*sigmaY2);
733     sigmaY2 = TMath::Max(sigmaY2, Float_t(0.0010)); //!! protection 
734     sigmaY2*= sigmaY2;
735   } else if(IsRPhiMethod(kGAUS)){
736     // PRF contribution
737     sigmaY2 = s2;
738     // Diffusion contribution
739     Double_t sD2 = dt/(1.+exb); sD2 *= sD2; sD2 *= x;
740     sigmaY2+= sD2; 
741     // add charge contribution TODO scale with respect to s2
742     //sigmaY2+= GetSYcharge(TMath::Abs(fQ));
743   }
744
745   // store tg^2(phi-a_L) and tg^2(a_L)
746   Double_t tgg = (tgp-exb)/(1.+tgp*exb); tgg *= tgg;
747   Double_t exb2= exb*exb;
748
749   // Lorentz angle shift contribution 
750   Float_t sx = GetSX(fLocalTimeBin, z); sx*=sx;
751   sigmaY2+= exb2*sx; //printf("Al[%6.2f] ", 1.e4*TMath::Sqrt(sigmaY2));
752
753   // Radial contribution due to not measuring x in Kalman model 
754   sigmaY2+= tgg*sx; //printf("x[%6.2f] ", 1.e4*TMath::Sqrt(sigmaY2));
755
756   // Track angle contribution
757   sigmaY2+= tgg*x*x*exb2/12.; //printf("angle[%6.2f]\n", 1.e4*TMath::Sqrt(sigmaY2));
758
759   AliCluster::SetSigmaY2(sigmaY2);
760 }
761
762 //_____________________________________________________________________________
763 Bool_t AliTRDcluster::IsEqual(const TObject *o) const
764 {
765   //
766   // Compare relevant information of this cluster with another one
767   //
768   
769   const AliTRDcluster *inCluster = dynamic_cast<const AliTRDcluster*>(o);
770   if (!o || !inCluster) return kFALSE;
771
772   if ( AliCluster::GetX() != inCluster->GetX() ) return kFALSE;
773   if ( AliCluster::GetY() != inCluster->GetY() ) return kFALSE;
774   if ( AliCluster::GetZ() != inCluster->GetZ() ) return kFALSE;
775   if ( fQ != inCluster->fQ ) return kFALSE;
776   if ( fDetector != inCluster->fDetector ) return kFALSE;
777   if ( fPadCol != inCluster->fPadCol ) return kFALSE;
778   if ( fPadRow != inCluster->fPadRow ) return kFALSE;
779   if ( fPadTime != inCluster->fPadTime ) return kFALSE;
780   if ( fClusterMasking != inCluster->fClusterMasking ) return kFALSE;
781   if ( IsInChamber() != inCluster->IsInChamber() ) return kFALSE;
782   if ( IsShared() != inCluster->IsShared() ) return kFALSE;
783   if ( IsUsed() != inCluster->IsUsed() ) return kFALSE;
784   
785   return kTRUE;
786 }
787
788 //_____________________________________________________________________________
789 void AliTRDcluster::Print(Option_t *o) const
790 {
791   AliInfo(Form("Det[%3d] LTrC[%+6.2f %+6.2f %+6.2f] Q[%5.1f] FLAG[in(%c) use(%c) sh(%c)] Y[%s]", 
792     fDetector, GetX(), GetY(), GetZ(), fQ, 
793     IsInChamber() ? 'y' : 'n', 
794     IsUsed() ? 'y' : 'n', 
795     IsShared() ? 'y' : 'n',
796     IsRPhiMethod(kGAUS)?"GAUS":(IsRPhiMethod(kLUT)?"LUT":"COG")
797   ));
798
799   if(strcmp(o, "a")!=0) return;
800   AliInfo(Form("LChC[c(%3d) r(%2d) t(%2d)] t-t0[%2d] Npad[%d] cen[%5.3f] mask[%d]", fPadCol, fPadRow, fPadTime, fLocalTimeBin, fNPads, fCenter, fClusterMasking)); 
801   AliInfo(Form("Signals[%3d %3d %3d %3d %3d %3d %3d]", fSignals[0], fSignals[1], fSignals[2], fSignals[3], fSignals[4], fSignals[5], fSignals[6]));
802 }
803
804
805 //_____________________________________________________________________________
806 void AliTRDcluster::SetPadMaskedPosition(UChar_t position)
807 {
808   //
809   // store the pad corruption position code
810   // 
811   // Code: 1 = left cluster
812   //       2 = middle cluster;
813   //       4 = right cluster
814   //
815   for(Int_t ipos = 0; ipos < 3; ipos++)
816     if(TESTBIT(position, ipos))
817       SETBIT(fClusterMasking, ipos);
818 }
819
820 //_____________________________________________________________________________
821 void AliTRDcluster::SetPadMaskedStatus(UChar_t status)
822 {
823   //
824   // store the status of the corrupted pad
825   //
826   // Code: 2 = noisy
827   //       4 = Bridged Left
828   //       8 = Bridged Right
829   //      32 = Not Connected
830   for(Int_t ipos = 0; ipos < 5; ipos++)
831     if(TESTBIT(status, ipos))
832       SETBIT(fClusterMasking, ipos + 3);
833 }
834
835 //___________________________________________________________________________
836 Float_t AliTRDcluster::GetDYcog(Double_t *const, Double_t *const)
837 {
838 //
839 // Get COG position
840 // Used for clusters with more than 3 pads - where LUT not applicable
841 //
842   Double_t sum = fSignals[1]
843                 +fSignals[2]
844                 +fSignals[3] 
845                 +fSignals[4]
846                 +fSignals[5];
847
848   // ???????????? CBL
849   // Go to 3 pad COG ????
850   // ???????????? CBL
851   fCenter = (0.0 * (-fSignals[1] + fSignals[5])
852                       + (-fSignals[2] + fSignals[4])) / sum;
853
854   return fCenter;
855 }
856
857 //___________________________________________________________________________
858 Float_t AliTRDcluster::GetDYlut(Double_t *const, Double_t *const)
859 {
860   //
861   // Calculates the cluster position using the lookup table.
862   // Method provided by Bogdan Vulpescu.
863   //
864
865   if(!fgLUT) FillLUT();
866
867   Double_t ampL = fSignals[2],
868            ampC = fSignals[3],
869            ampR = fSignals[4];
870   Int_t ilayer = AliTRDgeometry::GetLayer(fDetector);
871
872   Double_t x    = 0.0;
873   Double_t xmin, xmax, xwid;
874
875   Int_t    side = 0;
876   Int_t    ix;
877
878   Double_t xMin[AliTRDgeometry::kNlayer] = { 
879     0.006492, 0.006377, 0.006258, 0.006144, 0.006030, 0.005980 
880   };
881   Double_t xMax[AliTRDgeometry::kNlayer] = { 
882     0.960351, 0.965870, 0.970445, 0.974352, 0.977667, 0.996101 
883   };
884
885   if      (ampL > ampR) {
886     x    = (ampL - ampR) / ampC;
887     side = -1;
888   } 
889   else if (ampL < ampR) {
890     x    = (ampR - ampL) / ampC;
891     side = +1;
892   }
893
894   if (ampL != ampR) {
895
896     xmin = xMin[ilayer] + 0.000005;
897     xmax = xMax[ilayer] - 0.000005;
898     xwid = (xmax - xmin) / 127.0;
899
900     if      (x < xmin) fCenter = 0.0000;
901     else if (x > xmax) fCenter = side * 0.5000;
902     else {
903       ix      = (Int_t) ((x - xmin) / xwid);
904       fCenter = side * fgLUT[ilayer*fgkNlut+ix];
905     }
906   } else fCenter = 0.0;
907
908   return fCenter;
909 }
910
911 //___________________________________________________________________________
912 Float_t AliTRDcluster::GetDYgauss(Double_t s2w, Double_t *const y1, Double_t *const y2)
913 {
914 //
915 // (Re)Calculate cluster position in the y direction in local chamber coordinates using all available information from tracking.
916 //
917 // Input parameters:
918 //   s2 - sigma of gaussian parameterization (see bellow for the exact parameterization)
919 //   W  - pad width
920 //   xd - drift length (with respect to the anode wire) [cm]
921 //   wt - omega*tau = tg(a_L)
922 // Output values :
923 //   y1 and y2 - partial positions based on 2 pads clusters
924 //   return y position of the cluster from all information
925 //
926 // Estimation of y coordinate is based on the gaussian approximation of the PRF. Thus one may
927 // calculate the y position knowing the signals q_i-1, q_i and q_i+1 in the 3 adiacent pads by:
928 // BEGIN_LATEX
929 // y = #frac{1}{w_{1}+w_{2}}#[]{w_{1}#(){y_{0}-#frac{W}{2}+#frac{s^{2}}{W}ln#frac{q_{i}}{q_{i-1}}}+w_{2}#(){y_{0}+ #frac{W}{2}+#frac{s^{2}}{W}ln#frac{q_{i+1}}{q_{i}}}}
930 // END_LATEX
931 // where W is the pad width, y_0 is the position of the center pad and s^2 is given by
932 // BEGIN_LATEX
933 // s^{2} = s^{2}_{0} + s^{2}_{diff} (x,B) + #frac{tg^{2}(#phi-#alpha_{L})*l^{2}}{12}
934 // END_LATEX
935 // with s_0 being the PRF for 0 drift and track incidence phi equal to the lorentz angle a_L and the diffusion term 
936 // being described by:
937 // BEGIN_LATEX
938 // s_{diff} (x,B) = #frac{D_{L}#sqrt{x}}{1+#(){#omega#tau}^{2}}
939 // END_LATEX
940 // with x being the drift length. The weights w_1 and w_2 are taken to be q_i-1^2 and q_i+1^2 respectively
941 // 
942 // Authors
943 // Alex Bercuci <A.Bercuci@gsi.de>
944 // Theodor Rascanu <trascanu@stud.uni-frankfurt.de>
945 //
946   Double_t w1 = fSignals[2]*fSignals[2];
947   Double_t w2 = fSignals[4]*fSignals[4];
948   Double_t w = w1+w2;
949   if(w<1.){
950     AliError("Missing side signals for cluster.");
951     Print("a");
952     return 0.;
953   }  
954
955   //Double_t s2w = s2/W/W;
956   Float_t y1r  = fSignals[2]>0 ? (-0.5 + s2w*TMath::Log(fSignals[3]/(Float_t)fSignals[2])) : 0.;
957   Float_t y2r  = fSignals[4]>0 ? (0.5 + s2w*TMath::Log(fSignals[4]/(Float_t)fSignals[3])) : 0.;
958
959   if(y1) (*y1) = y1r;
960   if(y2) (*y2) = y2r;
961
962   return fCenter      = (w1*y1r+w2*y2r)/w;
963 }
964
965
966
967 //_____________________________________________________________________________
968 void AliTRDcluster::FillLUT()
969 {
970   //
971   // Create the LUT
972   //
973
974   // The lookup table from Bogdan
975   Float_t lut[AliTRDgeometry::kNlayer][fgkNlut] = {  
976     {
977       0.0070, 0.0150, 0.0224, 0.0298, 0.0374, 0.0454, 0.0533, 0.0611, 
978       0.0684, 0.0755, 0.0827, 0.0900, 0.0975, 0.1049, 0.1120, 0.1187, 
979       0.1253, 0.1318, 0.1385, 0.1453, 0.1519, 0.1584, 0.1646, 0.1704, 
980       0.1762, 0.1821, 0.1879, 0.1938, 0.1996, 0.2053, 0.2108, 0.2160, 
981       0.2210, 0.2260, 0.2310, 0.2361, 0.2411, 0.2461, 0.2509, 0.2557, 
982       0.2602, 0.2646, 0.2689, 0.2732, 0.2774, 0.2816, 0.2859, 0.2901, 
983       0.2942, 0.2983, 0.3022, 0.3061, 0.3099, 0.3136, 0.3172, 0.3207, 
984       0.3242, 0.3278, 0.3312, 0.3347, 0.3382, 0.3416, 0.3450, 0.3483, 
985       0.3515, 0.3547, 0.3579, 0.3609, 0.3639, 0.3669, 0.3698, 0.3727, 
986       0.3756, 0.3785, 0.3813, 0.3842, 0.3870, 0.3898, 0.3926, 0.3952, 
987       0.3979, 0.4005, 0.4032, 0.4057, 0.4082, 0.4108, 0.4132, 0.4157, 
988       0.4181, 0.4205, 0.4228, 0.4252, 0.4275, 0.4299, 0.4322, 0.4345, 
989       0.4367, 0.4390, 0.4412, 0.4434, 0.4456, 0.4478, 0.4499, 0.4520, 
990       0.4541, 0.4562, 0.4583, 0.4603, 0.4623, 0.4643, 0.4663, 0.4683, 
991       0.4702, 0.4722, 0.4741, 0.4758, 0.4774, 0.4790, 0.4805, 0.4824, 
992       0.4844, 0.4863, 0.4883, 0.4902, 0.4921, 0.4940, 0.4959, 0.4978 
993     },
994     {
995       0.0072, 0.0156, 0.0235, 0.0313, 0.0394, 0.0478, 0.0561, 0.0642, 
996       0.0718, 0.0792, 0.0868, 0.0947, 0.1025, 0.1101, 0.1172, 0.1241, 
997       0.1309, 0.1378, 0.1449, 0.1518, 0.1586, 0.1650, 0.1710, 0.1770, 
998       0.1830, 0.1891, 0.1952, 0.2011, 0.2070, 0.2125, 0.2177, 0.2229, 
999       0.2280, 0.2332, 0.2383, 0.2435, 0.2484, 0.2533, 0.2581, 0.2627, 
1000       0.2670, 0.2714, 0.2757, 0.2799, 0.2842, 0.2884, 0.2927, 0.2968, 
1001       0.3008, 0.3048, 0.3086, 0.3123, 0.3159, 0.3195, 0.3231, 0.3266, 
1002       0.3301, 0.3335, 0.3370, 0.3404, 0.3438, 0.3471, 0.3504, 0.3536, 
1003       0.3567, 0.3598, 0.3628, 0.3657, 0.3686, 0.3715, 0.3744, 0.3772, 
1004       0.3800, 0.3828, 0.3856, 0.3884, 0.3911, 0.3938, 0.3965, 0.3991, 
1005       0.4016, 0.4042, 0.4067, 0.4092, 0.4116, 0.4140, 0.4164, 0.4187, 
1006       0.4211, 0.4234, 0.4257, 0.4280, 0.4302, 0.4325, 0.4347, 0.4369, 
1007       0.4391, 0.4413, 0.4434, 0.4456, 0.4477, 0.4497, 0.4518, 0.4538, 
1008       0.4558, 0.4578, 0.4598, 0.4618, 0.4637, 0.4656, 0.4675, 0.4694, 
1009       0.4713, 0.4732, 0.4750, 0.4766, 0.4781, 0.4797, 0.4813, 0.4832, 
1010       0.4851, 0.4870, 0.4888, 0.4906, 0.4925, 0.4942, 0.4960, 0.4978
1011     },
1012     {
1013       0.0075, 0.0163, 0.0246, 0.0328, 0.0415, 0.0504, 0.0592, 0.0674, 
1014       0.0753, 0.0832, 0.0914, 0.0996, 0.1077, 0.1154, 0.1225, 0.1296, 
1015       0.1369, 0.1442, 0.1515, 0.1585, 0.1652, 0.1714, 0.1776, 0.1839, 
1016       0.1902, 0.1965, 0.2025, 0.2085, 0.2141, 0.2194, 0.2247, 0.2299, 
1017       0.2352, 0.2405, 0.2457, 0.2507, 0.2557, 0.2604, 0.2649, 0.2693, 
1018       0.2737, 0.2780, 0.2823, 0.2867, 0.2909, 0.2951, 0.2992, 0.3033, 
1019       0.3072, 0.3110, 0.3146, 0.3182, 0.3218, 0.3253, 0.3288, 0.3323, 
1020       0.3357, 0.3392, 0.3426, 0.3459, 0.3492, 0.3524, 0.3555, 0.3586, 
1021       0.3616, 0.3645, 0.3674, 0.3703, 0.3731, 0.3759, 0.3787, 0.3815, 
1022       0.3843, 0.3870, 0.3897, 0.3925, 0.3950, 0.3976, 0.4002, 0.4027, 
1023       0.4052, 0.4076, 0.4101, 0.4124, 0.4148, 0.4171, 0.4194, 0.4217, 
1024       0.4239, 0.4262, 0.4284, 0.4306, 0.4328, 0.4350, 0.4371, 0.4393, 
1025       0.4414, 0.4435, 0.4455, 0.4476, 0.4496, 0.4516, 0.4536, 0.4555, 
1026       0.4575, 0.4594, 0.4613, 0.4632, 0.4650, 0.4669, 0.4687, 0.4705, 
1027       0.4723, 0.4741, 0.4758, 0.4773, 0.4789, 0.4804, 0.4821, 0.4839, 
1028       0.4857, 0.4875, 0.4893, 0.4910, 0.4928, 0.4945, 0.4961, 0.4978
1029     },
1030     {
1031       0.0078, 0.0171, 0.0258, 0.0345, 0.0438, 0.0532, 0.0624, 0.0708, 
1032       0.0791, 0.0875, 0.0962, 0.1048, 0.1130, 0.1206, 0.1281, 0.1356, 
1033       0.1432, 0.1508, 0.1582, 0.1651, 0.1716, 0.1780, 0.1845, 0.1910, 
1034       0.1975, 0.2038, 0.2099, 0.2155, 0.2210, 0.2263, 0.2317, 0.2371, 
1035       0.2425, 0.2477, 0.2528, 0.2578, 0.2626, 0.2671, 0.2715, 0.2759, 
1036       0.2803, 0.2846, 0.2890, 0.2933, 0.2975, 0.3016, 0.3056, 0.3095, 
1037       0.3132, 0.3168, 0.3204, 0.3239, 0.3274, 0.3309, 0.3344, 0.3378, 
1038       0.3412, 0.3446, 0.3479, 0.3511, 0.3543, 0.3574, 0.3603, 0.3633, 
1039       0.3662, 0.3690, 0.3718, 0.3747, 0.3774, 0.3802, 0.3829, 0.3857, 
1040       0.3883, 0.3910, 0.3936, 0.3962, 0.3987, 0.4012, 0.4037, 0.4061, 
1041       0.4085, 0.4109, 0.4132, 0.4155, 0.4177, 0.4200, 0.4222, 0.4244, 
1042       0.4266, 0.4288, 0.4309, 0.4331, 0.4352, 0.4373, 0.4394, 0.4414, 
1043       0.4435, 0.4455, 0.4475, 0.4494, 0.4514, 0.4533, 0.4552, 0.4571, 
1044       0.4590, 0.4608, 0.4626, 0.4645, 0.4662, 0.4680, 0.4698, 0.4715, 
1045       0.4733, 0.4750, 0.4766, 0.4781, 0.4796, 0.4812, 0.4829, 0.4846, 
1046       0.4863, 0.4880, 0.4897, 0.4914, 0.4930, 0.4946, 0.4963, 0.4979
1047     },
1048     {
1049       0.0081, 0.0178, 0.0270, 0.0364, 0.0463, 0.0562, 0.0656, 0.0744, 
1050       0.0831, 0.0921, 0.1013, 0.1102, 0.1183, 0.1261, 0.1339, 0.1419, 
1051       0.1499, 0.1576, 0.1648, 0.1715, 0.1782, 0.1849, 0.1917, 0.1984, 
1052       0.2048, 0.2110, 0.2167, 0.2223, 0.2278, 0.2333, 0.2389, 0.2444, 
1053       0.2497, 0.2548, 0.2598, 0.2645, 0.2691, 0.2735, 0.2780, 0.2824, 
1054       0.2868, 0.2912, 0.2955, 0.2997, 0.3038, 0.3078, 0.3116, 0.3152, 
1055       0.3188, 0.3224, 0.3259, 0.3294, 0.3329, 0.3364, 0.3398, 0.3432, 
1056       0.3465, 0.3497, 0.3529, 0.3561, 0.3591, 0.3620, 0.3649, 0.3677, 
1057       0.3705, 0.3733, 0.3761, 0.3788, 0.3816, 0.3843, 0.3869, 0.3896, 
1058       0.3922, 0.3948, 0.3973, 0.3998, 0.4022, 0.4047, 0.4070, 0.4094, 
1059       0.4117, 0.4139, 0.4162, 0.4184, 0.4206, 0.4227, 0.4249, 0.4270, 
1060       0.4291, 0.4313, 0.4334, 0.4354, 0.4375, 0.4395, 0.4415, 0.4435, 
1061       0.4455, 0.4474, 0.4493, 0.4512, 0.4531, 0.4550, 0.4568, 0.4586, 
1062       0.4604, 0.4622, 0.4639, 0.4657, 0.4674, 0.4691, 0.4708, 0.4725, 
1063       0.4742, 0.4758, 0.4773, 0.4788, 0.4803, 0.4819, 0.4836, 0.4852, 
1064       0.4869, 0.4885, 0.4901, 0.4917, 0.4933, 0.4948, 0.4964, 0.4979
1065     },
1066     {
1067       0.0085, 0.0189, 0.0288, 0.0389, 0.0497, 0.0603, 0.0699, 0.0792, 
1068       0.0887, 0.0985, 0.1082, 0.1170, 0.1253, 0.1336, 0.1421, 0.1505, 
1069       0.1587, 0.1662, 0.1733, 0.1803, 0.1874, 0.1945, 0.2014, 0.2081, 
1070       0.2143, 0.2201, 0.2259, 0.2316, 0.2374, 0.2431, 0.2487, 0.2541, 
1071       0.2593, 0.2642, 0.2689, 0.2735, 0.2781, 0.2826, 0.2872, 0.2917, 
1072       0.2961, 0.3003, 0.3045, 0.3086, 0.3125, 0.3162, 0.3198, 0.3235, 
1073       0.3270, 0.3306, 0.3342, 0.3377, 0.3411, 0.3446, 0.3479, 0.3511, 
1074       0.3543, 0.3575, 0.3605, 0.3634, 0.3663, 0.3691, 0.3720, 0.3748, 
1075       0.3775, 0.3803, 0.3830, 0.3857, 0.3884, 0.3911, 0.3937, 0.3962, 
1076       0.3987, 0.4012, 0.4036, 0.4060, 0.4084, 0.4107, 0.4129, 0.4152, 
1077       0.4174, 0.4196, 0.4218, 0.4239, 0.4261, 0.4282, 0.4303, 0.4324, 
1078       0.4344, 0.4365, 0.4385, 0.4405, 0.4425, 0.4445, 0.4464, 0.4483, 
1079       0.4502, 0.4521, 0.4539, 0.4558, 0.4576, 0.4593, 0.4611, 0.4629, 
1080       0.4646, 0.4663, 0.4680, 0.4697, 0.4714, 0.4730, 0.4747, 0.4759, 
1081       0.4769, 0.4780, 0.4790, 0.4800, 0.4811, 0.4827, 0.4843, 0.4859, 
1082       0.4874, 0.4889, 0.4905, 0.4920, 0.4935, 0.4950, 0.4965, 0.4979
1083     }
1084   }; 
1085
1086   if(!fgLUT) fgLUT = new Double_t[AliTRDgeometry::kNlayer*fgkNlut];
1087
1088   for (Int_t ilayer = 0; ilayer < AliTRDgeometry::kNlayer; ilayer++) {
1089     for (Int_t ilut  = 0; ilut  < fgkNlut; ilut++  ) {
1090       fgLUT[ilayer*fgkNlut+ilut] = lut[ilayer][ilut];
1091     }
1092   }
1093 }
1094