]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TRD/AliTRDcluster.cxx
fix broken compilation
[u/mrichter/AliRoot.git] / TRD / AliTRDcluster.cxx
CommitLineData
46d29e70 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
88cb7938 16/* $Id$ */
b9d0a01d 17
88cb7938 18
19///////////////////////////////////////////////////////////////////////////////
20// //
21// TRD cluster //
22// //
23///////////////////////////////////////////////////////////////////////////////
46d29e70 24
5843e420 25#include "TMath.h"
26
203967fc 27#include "AliLog.h"
46d29e70 28#include "AliTRDcluster.h"
46d29e70 29
46d29e70 30ClassImp(AliTRDcluster)
bdb68f8c 31
6d50f529 32//___________________________________________________________________________
33AliTRDcluster::AliTRDcluster()
34 :AliCluster()
af26ce80 35 ,fPadCol(0)
36 ,fPadRow(0)
37 ,fPadTime(0)
f5375dcb 38 ,fLocalTimeBin(0)
39 ,fNPads(0)
40 ,fClusterMasking(0)
41 ,fDetector(0)
42 ,fQ(0)
43 ,fCenter(0)
6d50f529 44{
bdb68f8c 45 //
a6dd11e9 46 // Default constructor
bdb68f8c 47 //
6d50f529 48
49 for (Int_t i = 0; i < 7; i++) {
50 fSignals[i] = 0;
51 }
52
bdb68f8c 53}
6d50f529 54
34eaaa7e 55//___________________________________________________________________________
56AliTRDcluster::AliTRDcluster(Int_t det, Float_t q
57 , Float_t *pos, Float_t *sig
58 , Int_t *tracks, Char_t npads, Short_t *signals
af26ce80 59 , UChar_t col, UChar_t row, UChar_t time
60 , Char_t timebin, Float_t center, UShort_t volid)
61 :AliCluster(volid,pos[0],pos[1],pos[2],sig[0],sig[1],0.0,0x0)
af26ce80 62 ,fPadCol(col)
63 ,fPadRow(row)
64 ,fPadTime(time)
f5375dcb 65 ,fLocalTimeBin(timebin)
66 ,fNPads(npads)
67 ,fClusterMasking(0)
68 ,fDetector(det)
69 ,fQ(q)
70 ,fCenter(center)
34eaaa7e 71{
72 //
73 // Constructor
74 //
75
76 for (Int_t i = 0; i < 7; i++) {
77 fSignals[i] = signals[i];
78 }
79
80 if (tracks) {
81 AddTrackIndex(tracks);
82 }
83
84}
85
bbf92647 86//_____________________________________________________________________________
6d50f529 87AliTRDcluster::AliTRDcluster(const AliTRDcluster &c)
34eaaa7e 88 :AliCluster(c)
af26ce80 89 ,fPadCol(c.fPadCol)
90 ,fPadRow(c.fPadRow)
91 ,fPadTime(c.fPadTime)
f5375dcb 92 ,fLocalTimeBin(c.fLocalTimeBin)
93 ,fNPads(c.fNPads)
94 ,fClusterMasking(c.fClusterMasking)
95 ,fDetector(c.fDetector)
96 ,fQ(c.fQ)
97 ,fCenter(c.fCenter)
bbf92647 98{
99 //
100 // Copy constructor
101 //
102
0ae89c5d 103 SetBit(kInChamber, c.IsInChamber());
75fb37cc 104 SetLabel(c.GetLabel(0),0);
105 SetLabel(c.GetLabel(1),1);
106 SetLabel(c.GetLabel(2),2);
6d50f529 107
75fb37cc 108 SetY(c.GetY());
109 SetZ(c.GetZ());
110 SetSigmaY2(c.GetSigmaY2());
111 SetSigmaZ2(c.GetSigmaZ2());
6d50f529 112
113 for (Int_t i = 0; i < 7; i++) {
114 fSignals[i] = c.fSignals[i];
115 }
116
a2b90f83 117}
118
a2b90f83 119//_____________________________________________________________________________
120void AliTRDcluster::AddTrackIndex(Int_t *track)
121{
122 //
123 // Adds track index. Currently assumed that track is an array of
124 // size 9, and up to 3 track indexes are stored in fTracks[3].
125 // Indexes are sorted according to:
126 // 1) index of max number of appearances is stored first
127 // 2) if two or more indexes appear equal number of times, the lowest
128 // ones are stored first;
129 //
bbf92647 130
88cb7938 131 const Int_t kSize = 9;
6d50f529 132 Int_t entries[kSize][2];
a2b90f83 133
6d50f529 134 Int_t i = 0;
135 Int_t j = 0;
136 Int_t k = 0;
137 Int_t index;
88cb7938 138 Bool_t indexAdded;
a2b90f83 139
6d50f529 140 for (i = 0; i < kSize; i++) {
141 entries[i][0] = -1;
142 entries[i][1] = 0;
5443e65e 143 }
a2b90f83 144
6d50f529 145 for (k = 0; k < kSize; k++) {
146
147 index = track[k];
148 indexAdded = kFALSE;
149
150 j = 0;
a2b90f83 151 if (index >= 0) {
6d50f529 152 while ((!indexAdded) && (j < kSize)) {
153 if ((entries[j][0] == index) ||
154 (entries[j][1] == 0)) {
155 entries[j][0] = index;
156 entries[j][1] = entries[j][1] + 1;
157 indexAdded = kTRUE;
a2b90f83 158 }
159 j++;
160 }
161 }
6d50f529 162
163 }
164
165 // Sort by number of appearances and index value
166 Int_t swap = 1;
167 Int_t tmp0;
168 Int_t tmp1;
169 while (swap > 0) {
170 swap = 0;
171 for (i = 0; i < (kSize - 1); i++) {
172 if ((entries[i][0] >= 0) &&
173 (entries[i+1][0] >= 0)) {
a2b90f83 174 if ((entries[i][1] < entries[i+1][1]) ||
175 ((entries[i][1] == entries[i+1][1]) &&
6d50f529 176 (entries[i][0] > entries[i+1][0]))) {
177 tmp0 = entries[i][0];
178 tmp1 = entries[i][1];
179 entries[i][0] = entries[i+1][0];
180 entries[i][1] = entries[i+1][1];
181 entries[i+1][0] = tmp0;
182 entries[i+1][1] = tmp1;
183 swap++;
a2b90f83 184 }
185 }
186 }
5443e65e 187 }
a2b90f83 188
6d50f529 189 // Set track indexes
190 for (i = 0; i < 3; i++) {
191 SetLabel(entries[i][0],i);
192 }
a2b90f83 193
194 return;
46d29e70 195
5443e65e 196}
46d29e70 197
203967fc 198//_____________________________________________________________________________
199void AliTRDcluster::Clear(Option_t *)
200{
201 //
202 // Reset all member to the default value
203 //
204 fPadCol=0;
205 fPadRow=0;
206 fPadTime=0;
207 fLocalTimeBin=0;
208 fNPads=0;
209 fClusterMasking=0;
210 fDetector=0;
211 for (Int_t i=0; i < 7; i++) fSignals[i]=0;
212 fQ = 0;
213 fCenter = 0;
214 for (Int_t i = 0; i < 3; i++) SetLabel(0,i);
215 SetX(0);
216 SetY(0);
217 SetZ(0);
218 SetSigmaY2(0);
219 SetSigmaZ2(0);
220 SetVolumeId(0);
221}
222
6d50f529 223//_____________________________________________________________________________
bdb68f8c 224Float_t AliTRDcluster::GetSumS() const
225{
226 //
6d50f529 227 // Returns the total charge from a not unfolded cluster
bdb68f8c 228 //
6d50f529 229
230 Float_t sum = 0.0;
231 for (Int_t i = 0; i < 7; i++) {
232 sum += fSignals[i];
bdb68f8c 233 }
6d50f529 234
235 return sum;
bdb68f8c 236
237}
f5375dcb 238
5843e420 239//_____________________________________________________________________________
240Float_t AliTRDcluster::GetXpos(Float_t t0, Float_t vd, Float_t *const q)
241{
242//
243// (Re)Calculate cluster position in the x direction in local chamber coordinates using all available information from tracking.
244// Input parameters:
245// t0 - calibration aware trigger delay
246// vd - drift velocity in the region of the cluster
247// q - array of chrges from previous clusters in the tracklet
248// Output values :
249// return x position of the cluster from all information
250//
251// X-position calculation
252// The estimation of the radial position is based on calculating the drift time and the drift velocity at the point of
253// estimation. The drift time can be estimated according to the expression:
254// BEGIN_LATEX
255// t_{drift} = t_{bin} - t_{0} - t_{cause}(x) - t_{TC}(q_{i-1}, q_{i-2}, ...)
256// END_LATEX
257// where t_0 is the delay of the trigger signal. t_cause is the causality delay between ionisation electrons hitting
258// the anode and the registration of maximum signal by the electronics - it is due to the rising time of the TRF
259// convoluted with the diffusion width. t_TC is the residual charge from previous bins due to residual tails after tail
260// cancellation.
261//
262// The drift velocity is considered to vary linearly with the drift length (independent of the distance to the anode wire
263// in the z direction). Thus one can write the calculate iteratively the drift length from the expression:
264// BEGIN_LATEX
265// x = t_{drift}(x)*v_{drfit}(x)
266// END_LATEX
267//
268// Authors
269// Alex Bercuci <A.Bercuci@gsi.de>
270//
271
272 Double_t td = fPadTime + .5; // center of the time bin
273 if(td < t0+2.5) return 0.; // do not calculate radial posion of clusters in the amplification region
274
275 // correction for t0
276 td -= t0;
277
278 Double_t x = vd*td, xold=0.;
279 Float_t tc0 = 0.244, // TRF rising time 0.2us
280 dtcdx = 0.009, // diffusion contribution to the rising time of the signal
281 kTC = 0., // tail cancellation residual
282 kVD = 0.; // variation of the drift velocity with drift length
283 while(TMath::Abs(x-xold)>1.e-3){ // convergence on 10um level
284 xold = x;
285 Float_t tc = tc0 - dtcdx*x;
286 Float_t tq = 0.;
287 if(q){
288 for(Int_t iq=0; iq<3; iq++) tq += q[iq]*TMath::Exp(-kTC*x);
289 }
290 Float_t dvd = TMath::Exp(-kVD*x);
291 x = (td - tc - tq) * (vd + dvd);
292 }
293 return x;
294}
295
296//_____________________________________________________________________________
297Float_t AliTRDcluster::GetYpos(Float_t s2, Float_t W, Float_t *const yPos1, Float_t *const yPos2)
298{
299//
300// (Re)Calculate cluster position in the y direction in local chamber coordinates using all available information from tracking.
301// Input parameters:
302// s2 - sigma of gaussian parameterization (see bellow for the exact parameterization)
303// W - pad width
304// Output values :
305// y1 and y2 - partial positions based on 2 pads clusters
306// return y position of the cluster from all information
307//
308// Y-position calculation
309// Estimation of y coordinate is based on the gaussian approximation of the PRF. Thus one may
310// calculate the y position knowing the signals q_i-1, q_i and q_i+1 in the 3 adiacent pads by:
311// BEGIN_LATEX
312// 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}}}}
313// END_LATEX
314// where W is the pad width, y_0 is the position of the center pad and s^2 is given by
315// BEGIN_LATEX
316// s^{2} = s^{2}_{0} + s^{2}_{diff} (x,B) + #frac{tg^{2}(#phi-#alpha_{L})*l^{2}}{12}
317// END_LATEX
318// with s_0 being the PRF for 0 drift and track incidence phi equal to the lorentz angle a_L and the diffusion term
319// being described by:
320// BEGIN_LATEX
321// s_{diff} (x,B) = #frac{D_{L}#sqrt{x}}{1+#(){#omega#tau}^{2}}
322// END_LATEX
323// 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
324//
325
326 Float_t y0 = GetY()-W*fCenter;
327 Double_t w1 = fSignals[2]*fSignals[2];
328 Double_t w2 = fSignals[4]*fSignals[4];
329 Float_t y1 = fSignals[2]>0 ? (y0 - .5*W + s2*TMath::Log(fSignals[3]/(Float_t)fSignals[2])/W) : 0.;
330 Float_t y2 = fSignals[4]>0 ? (y0 + .5*W + s2*TMath::Log(fSignals[4]/(Float_t)fSignals[3])/W) : 0.;
331
332 if(yPos1 && yPos2){
333 *yPos1 = y1;
334 *yPos2 = y2;
335 }
336
337 return (w1*y1+w2*y2)/(w1+w2);
338}
203967fc 339
340//_____________________________________________________________________________
341Bool_t AliTRDcluster::IsEqual(const TObject *o) const
342{
343 //
344 // Compare relevant information of this cluster with another one
345 //
346
347 const AliTRDcluster *inCluster = dynamic_cast<const AliTRDcluster*>(o);
348 if (!o || !inCluster) return kFALSE;
349
350 if ( AliCluster::GetX() != inCluster->GetX() ) return kFALSE;
351 if ( AliCluster::GetY() != inCluster->GetY() ) return kFALSE;
352 if ( AliCluster::GetZ() != inCluster->GetZ() ) return kFALSE;
353 if ( fQ != inCluster->fQ ) return kFALSE;
354 if ( fDetector != inCluster->fDetector ) return kFALSE;
355 if ( fPadCol != inCluster->fPadCol ) return kFALSE;
356 if ( fPadRow != inCluster->fPadRow ) return kFALSE;
357 if ( fPadTime != inCluster->fPadTime ) return kFALSE;
358 if ( fClusterMasking != inCluster->fClusterMasking ) return kFALSE;
359 if ( IsInChamber() != inCluster->IsInChamber() ) return kFALSE;
360 if ( IsShared() != inCluster->IsShared() ) return kFALSE;
361 if ( IsUsed() != inCluster->IsUsed() ) return kFALSE;
362
363 return kTRUE;
364}
365
366//_____________________________________________________________________________
367void AliTRDcluster::Print(Option_t *o) const
368{
369 AliInfo(Form("Det[%3d] LTrC[%7.2f %7.2f %7.2f] Q[%f] Stat[in(%c) use(%c) sh(%c)]",
370 fDetector, GetX(), GetY(), GetZ(), fQ,
371 IsInChamber() ? 'y' : 'n', IsUsed() ? 'y' : 'n', IsShared() ? 'y' : 'n'));
372
373 if(strcmp(o, "a")!=0) return;
374 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));
375 AliInfo(Form("Signals[%3d %3d %3d %3d %3d %3d %3d]", fSignals[0], fSignals[1], fSignals[2], fSignals[3], fSignals[4], fSignals[5], fSignals[6]));
376}
377
378
f5375dcb 379//_____________________________________________________________________________
380void AliTRDcluster::SetPadMaskedPosition(UChar_t position)
381{
382 //
383 // store the pad corruption position code
384 //
385 // Code: 1 = left cluster
386 // 2 = middle cluster;
387 // 4 = right cluster
388 //
389 for(Int_t ipos = 0; ipos < 3; ipos++)
390 if(TESTBIT(position, ipos))
391 SETBIT(fClusterMasking, ipos);
392}
393
394//_____________________________________________________________________________
395void AliTRDcluster::SetPadMaskedStatus(UChar_t status)
396{
397 //
398 // store the status of the corrupted pad
399 //
400 // Code: 2 = noisy
401 // 4 = Bridged Left
402 // 8 = Bridged Right
403 // 32 = Not Connected
404 for(Int_t ipos = 0; ipos < 5; ipos++)
405 if(TESTBIT(status, ipos))
406 SETBIT(fClusterMasking, ipos + 3);
407}