]>
Commit | Line | Data |
---|---|---|
2a4a428a | 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: AliTRDchamberTimeBin.cxx 23313 2008-01-11 14:56:43Z cblume $ */ | |
17 | ||
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | // // | |
20 | // Organization of clusters at the level of 1 TRD chamber. // | |
21 | // The data structure is used for tracking at the stack level. // | |
22 | // // | |
23 | // Functionalities: // | |
24 | // 1. cluster organization and sorting // | |
25 | // 2. fast data navigation // | |
26 | // // | |
27 | // Authors: // | |
28 | // Alex Bercuci <A.Bercuci@gsi.de> // | |
29 | // Markus Fasel <M.Fasel@gsi.de> // | |
30 | // // | |
31 | /////////////////////////////////////////////////////////////////////////////// | |
32 | ||
33 | #include <TObject.h> | |
2a4a428a | 34 | #include <TMath.h> |
2a4a428a | 35 | #include <TTreeStream.h> |
36 | ||
37 | #include "AliLog.h" | |
4d6aee34 | 38 | #include "AliTRDcluster.h" |
ac1dec3b | 39 | #include "AliTRDgeometry.h" |
40 | #include "AliTRDpadPlane.h" | |
2a4a428a | 41 | #include "AliTRDchamberTimeBin.h" |
42 | #include "AliTRDrecoParam.h" | |
43 | #include "AliTRDReconstructor.h" | |
2a4a428a | 44 | |
45 | ClassImp(AliTRDchamberTimeBin) | |
46 | ||
47 | //_____________________________________________________________________________ | |
48 | AliTRDchamberTimeBin::AliTRDchamberTimeBin(Int_t plane, Int_t stack, Int_t sector, Double_t z0, Double_t zLength) | |
49 | :TObject() | |
4d6aee34 | 50 | ,fkReconstructor(NULL) |
2a4a428a | 51 | ,fPlane(plane) |
52 | ,fStack(stack) | |
53 | ,fSector(sector) | |
54 | ,fNRows(kMaxRows) | |
55 | ,fN(0) | |
56 | ,fX(0.) | |
57 | ,fZ0(z0) | |
58 | ,fZLength(zLength) | |
59 | { | |
60 | // | |
61 | // Default constructor (Only provided to use AliTRDchamberTimeBin with arrays) | |
62 | // | |
ac1dec3b | 63 | SetBit(kT0, kFALSE); |
64 | SetBit(kOwner, kFALSE); | |
afefec95 | 65 | memset(fPositions, 1, kMaxRows*sizeof(UChar_t)); |
66 | memset(fClusters, 0, kMaxClustersLayer*sizeof(AliTRDcluster*)); | |
67 | memset(fIndex, 1, kMaxClustersLayer*sizeof(UInt_t)); | |
2a4a428a | 68 | } |
69 | ||
2a4a428a | 70 | |
71 | //_____________________________________________________________________________ | |
72 | AliTRDchamberTimeBin::AliTRDchamberTimeBin(const AliTRDchamberTimeBin &layer): | |
73 | TObject() | |
4d6aee34 | 74 | ,fkReconstructor(layer.fkReconstructor) |
2a4a428a | 75 | ,fPlane(layer.fPlane) |
76 | ,fStack(layer.fStack) | |
77 | ,fSector(layer.fSector) | |
78 | ,fNRows(layer.fNRows) | |
79 | ,fN(layer.fN) | |
80 | ,fX(layer.fX) | |
81 | ,fZ0(layer.fZ0) | |
82 | ,fZLength(layer.fZLength) | |
83 | { | |
ac1dec3b | 84 | // Copy Constructor |
2a4a428a | 85 | |
ac1dec3b | 86 | SetBit(kT0, layer.IsT0()); |
87 | SetBit(kOwner, kFALSE); | |
2a4a428a | 88 | for(int i=0; i<kMaxRows; i++) fPositions[i] = layer.fPositions[i]; |
ac1dec3b | 89 | memcpy(&fClusters[0], &layer.fClusters[0], kMaxClustersLayer*sizeof(AliTRDcluster*)); |
2a4a428a | 90 | memcpy(&fIndex[0], &layer.fIndex[0], kMaxClustersLayer*sizeof(UInt_t)); |
91 | ||
92 | ||
93 | // BuildIndices(); | |
94 | } | |
95 | ||
96 | //_____________________________________________________________________________ | |
97 | AliTRDchamberTimeBin &AliTRDchamberTimeBin::operator=(const AliTRDchamberTimeBin &layer) | |
98 | { | |
99 | // Assignment operator | |
100 | ||
101 | if (this != &layer) layer.Copy(*this); | |
102 | return *this; | |
103 | } | |
104 | ||
105 | //_____________________________________________________________________________ | |
106 | void AliTRDchamberTimeBin::Clear(const Option_t *) | |
107 | { | |
4d6aee34 | 108 | // Reset the Chamber Timebin |
8f241a9a | 109 | if(IsOwner()) |
110 | for(Int_t it = 0; it<kMaxClustersLayer; it++) | |
111 | delete fClusters[it]; | |
112 | memset(fClusters,0,kMaxClustersLayer*sizeof(fClusters[0])); | |
2a4a428a | 113 | fN = 0; |
114 | } | |
115 | ||
116 | //_____________________________________________________________________________ | |
117 | void AliTRDchamberTimeBin::Copy(TObject &o) const | |
118 | { | |
119 | // Copy method. Performs a deep copy of all data from this object to object o. | |
120 | ||
121 | AliTRDchamberTimeBin &layer = (AliTRDchamberTimeBin &)o; | |
4d6aee34 | 122 | layer.fkReconstructor = fkReconstructor; |
2a4a428a | 123 | layer.fPlane = fPlane; |
124 | layer.fStack = fStack; | |
125 | layer.fSector = fSector; | |
126 | layer.fNRows = fNRows; | |
127 | layer.fN = fN; | |
128 | layer.fX = fX; | |
129 | layer.fZ0 = fZ0; | |
130 | layer.fZLength = fZLength; | |
131 | layer.SetT0(IsT0()); | |
ac1dec3b | 132 | layer.SetBit(kOwner, kFALSE); |
2a4a428a | 133 | |
134 | for(int i=0; i<kMaxRows; i++) layer.fPositions[i] = fPositions[i]; | |
ac1dec3b | 135 | memcpy(&layer.fClusters[0], &fClusters[0], kMaxClustersLayer*sizeof(AliTRDcluster*)); |
2a4a428a | 136 | memcpy(&layer.fIndex[0], &fIndex[0], kMaxClustersLayer*sizeof(UInt_t)); |
137 | ||
138 | TObject::Copy(layer); // copies everything into layer | |
139 | ||
140 | // layer.BuildIndices(); | |
141 | } | |
142 | ||
143 | //_____________________________________________________________________________ | |
144 | AliTRDchamberTimeBin::~AliTRDchamberTimeBin() | |
145 | { | |
146 | // Destructor | |
ac1dec3b | 147 | if(IsOwner()){ |
148 | for(AliTRDcluster **cit = &fClusters[0]; (*cit); cit++) delete (*cit); | |
149 | } | |
150 | } | |
151 | ||
152 | //_____________________________________________________________________________ | |
153 | void AliTRDchamberTimeBin::SetOwner(Bool_t copy) | |
154 | { | |
155 | // Sets the ownership of the clusters to this | |
156 | // If option "copy" is kTRUE [default] the clusters | |
157 | // are also copied otherwise only the ownership bit | |
158 | // is flipped. | |
159 | ||
160 | SetBit(kOwner, kTRUE); | |
161 | if(!copy) return; | |
162 | for(AliTRDcluster **cit = &fClusters[0]; (*cit); ++cit){ | |
163 | (*cit) = new AliTRDcluster(*(*cit)); | |
164 | } | |
2a4a428a | 165 | } |
166 | ||
167 | //_____________________________________________________________________________ | |
8368e0ee | 168 | void AliTRDchamberTimeBin::SetRange(Float_t z0, Float_t zLength) |
2a4a428a | 169 | { |
170 | // Sets the range in z-direction | |
171 | // | |
172 | // Parameters: | |
173 | // z0 : starting position of layer in the z direction | |
174 | // zLength : length of layer in the z direction | |
175 | ||
176 | fZ0 = (z0 <= z0 + zLength) ? z0 : z0 + zLength; | |
177 | fZLength = TMath::Abs(zLength); | |
178 | } | |
179 | ||
180 | //_____________________________________________________________________________ | |
181 | void AliTRDchamberTimeBin::InsertCluster(AliTRDcluster *c, UInt_t index) | |
182 | { | |
183 | // | |
184 | // Insert cluster in cluster array. | |
185 | // Clusters are sorted according to Y coordinate. | |
186 | // | |
187 | ||
188 | //if (fTimeBinIndex < 0) { | |
189 | //AliWarning("Attempt to insert cluster into non-sensitive time bin!\n"); | |
190 | //return; | |
191 | //} | |
192 | ||
193 | if (fN == (Int_t) kMaxClustersLayer) { | |
194 | //AliWarning("Too many clusters !\n"); | |
195 | return; | |
196 | } | |
197 | ||
198 | if (fN == 0) { | |
199 | fIndex[0] = index; | |
200 | fClusters[fN++] = c; | |
201 | return; | |
202 | } | |
203 | ||
204 | Int_t i = Find(c->GetY()); | |
205 | memmove(fClusters+i+1,fClusters+i,(fN-i)*sizeof(AliTRDcluster*)); | |
206 | memmove(fIndex +i+1,fIndex +i,(fN-i)*sizeof(UInt_t)); | |
207 | fIndex[i] = index; | |
208 | fClusters[i] = c; | |
209 | fN++; | |
ac1dec3b | 210 | } |
2a4a428a | 211 | |
ac1dec3b | 212 | //___________________________________________________ |
213 | void AliTRDchamberTimeBin::Bootstrap(const AliTRDReconstructor *rec, Int_t det) | |
214 | { | |
215 | // Reinitialize all data members from the clusters array | |
216 | // It has to be used after reading from disk | |
217 | ||
4d6aee34 | 218 | fkReconstructor = rec; |
ac1dec3b | 219 | fPlane = AliTRDgeometry::GetLayer(det); |
220 | fStack = AliTRDgeometry::GetStack(det); | |
221 | fSector = AliTRDgeometry::GetSector(det); | |
222 | AliTRDgeometry g; | |
223 | fNRows = g.GetPadPlane(fPlane, fStack)->GetNrows(); | |
224 | fN = 0; | |
225 | for(AliTRDcluster **cit = &fClusters[0]; (*cit); cit++) fN++; | |
226 | BuildIndices(); | |
227 | } | |
2a4a428a | 228 | |
229 | //_____________________________________________________________________________ | |
230 | void AliTRDchamberTimeBin::BuildIndices(Int_t iter) | |
231 | { | |
232 | // Rearrangement of the clusters belonging to the propagation layer for the stack. | |
233 | // | |
234 | // Detailed description | |
235 | // | |
236 | // The array indices of all clusters in one PropagationLayer are stored in | |
237 | // array. The array is divided into several bins. | |
238 | // The clusters are sorted in increasing order of their y coordinate. | |
239 | // | |
240 | // Sorting algorithm: TreeSearch | |
241 | // | |
242 | ||
243 | if(!fN) return; | |
244 | ||
245 | // Select clusters that belong to the Stack | |
246 | Int_t nClStack = 0; // Internal counter | |
247 | for(Int_t i = 0; i < fN; i++){ | |
fac58f00 | 248 | if(fClusters[i]->IsUsed() || fClusters[i]->IsShared()){ |
4d6aee34 | 249 | fClusters[i] = NULL; |
2a4a428a | 250 | fIndex[i] = 0xffff; |
251 | } else nClStack++; | |
252 | } | |
6e3b00f9 | 253 | if(nClStack > kMaxClustersLayer) AliInfo(Form("Number of clusters in stack %d exceed buffer size %d. Truncating.", nClStack, kMaxClustersLayer)); |
2a4a428a | 254 | |
255 | // Nothing in this time bin. Reset indexes | |
256 | if(!nClStack){ | |
257 | fN = 0; | |
258 | memset(&fPositions[0], 0xff, sizeof(UChar_t) * kMaxRows); | |
259 | memset(&fClusters[0], 0x0, sizeof(AliTRDcluster*) * kMaxClustersLayer); | |
260 | memset(&fIndex[0], 0xffff, sizeof(UInt_t) * kMaxClustersLayer); | |
261 | return; | |
262 | } | |
263 | ||
264 | // Make a copy | |
265 | AliTRDcluster *helpCL[kMaxClustersLayer]; | |
266 | UInt_t helpInd[kMaxClustersLayer]; | |
267 | nClStack = 0; | |
268 | // Defining iterators | |
269 | AliTRDcluster **fcliter = &fClusters[0], **hcliter = &helpCL[0]; UInt_t *finditer = &fIndex[0], *hinditer = &helpInd[0]; | |
4d6aee34 | 270 | AliTRDcluster *tmpcl = NULL; |
2a4a428a | 271 | for(Int_t i = 0; i < TMath::Min(fN, kMaxClustersLayer); i++){ |
272 | if(!(tmpcl = *(fcliter++))){ | |
273 | finditer++; | |
274 | continue; | |
275 | } | |
276 | *(hcliter++) = tmpcl; | |
277 | *(hinditer++) = *finditer; | |
4d6aee34 | 278 | tmpcl = NULL; |
2a4a428a | 279 | *(finditer++) = 0xffff; |
280 | nClStack++; | |
281 | } | |
282 | ||
283 | // do clusters arrangement | |
284 | fX = 0.; | |
285 | fN = nClStack; | |
286 | nClStack = 0; | |
287 | // Reset Positions array | |
288 | memset(fPositions, 0, sizeof(UChar_t)*kMaxRows); | |
289 | AliTRDcluster **cliter = &helpCL[0]; // Declare iterator running over the whole array | |
fc0882f3 | 290 | const AliTRDrecoParam* const recoParam = fkReconstructor->GetRecoParam(); //the dynamic cast in GetRecoParam is slow, so caching the pointer to it |
2a4a428a | 291 | for(Int_t i = 0; i < fN; i++){ |
292 | // boundary check | |
293 | AliTRDcluster *cl = *(cliter++); | |
294 | UChar_t rowIndex = cl->GetPadRow(); | |
295 | // Insert Leaf | |
296 | Int_t pos = FindYPosition(cl->GetY(), rowIndex, i); | |
297 | if(pos == -1){ // zbin is empty; | |
298 | Int_t upper = (rowIndex == fNRows - 1) ? nClStack : fPositions[rowIndex + 1]; | |
299 | memmove(fClusters + upper + 1, fClusters + upper, (sizeof(AliTRDcluster *))*(nClStack-upper)); | |
300 | memmove(fIndex + upper + 1, fIndex + upper, (sizeof(UInt_t))*(nClStack-upper)); | |
301 | fClusters[upper] = cl; | |
302 | fIndex[upper] = helpInd[i]; | |
303 | // Move All pointer one position back | |
304 | for(UChar_t j = rowIndex + 1; j < fNRows; j++) fPositions[j]++; | |
305 | nClStack++; | |
306 | } else { // zbin not empty | |
307 | memmove(fClusters + pos + 2, fClusters + pos+1, (sizeof(AliTRDcluster *))*(nClStack-(pos+1))); | |
308 | memmove(fIndex + pos + 2, fIndex + pos+1, (sizeof(UInt_t))*(nClStack-(pos+1))); | |
309 | fClusters[pos + 1] = cl; //fIndex[i]; | |
310 | fIndex[pos + 1] = helpInd[i]; | |
311 | // Move All pointer one position back | |
312 | for(UChar_t j = rowIndex + 1; j < fNRows; j++) fPositions[j]++; | |
313 | nClStack++; | |
314 | } | |
315 | ||
316 | // calculate mean x | |
317 | fX += cl->GetX(); | |
318 | ||
319 | // Debug Streaming | |
fc0882f3 | 320 | if(recoParam->GetStreamLevel(AliTRDrecoParam::kTracker) >= 3){ |
0b433f72 | 321 | AliTRDcluster dcl(*cl); |
a2fbb6ec | 322 | TTreeSRedirector &cstream = *fkReconstructor->GetDebugStream(AliTRDrecoParam::kTracker); |
2a4a428a | 323 | cstream << "BuildIndices" |
324 | << "Plane=" << fPlane | |
325 | << "Stack=" << fStack | |
326 | << "Sector=" << fSector | |
327 | << "Iter=" << iter | |
0b433f72 | 328 | << "C.=" << &dcl |
2a4a428a | 329 | << "rowIndex=" << rowIndex |
330 | << "\n"; | |
331 | } | |
332 | } | |
333 | ||
334 | // AliInfo("Positions"); | |
335 | // for(int ir=0; ir<fNRows; ir++) printf("pos[%d] %d\n", ir, fPositions[ir]); | |
336 | ||
337 | fX /= fN; | |
338 | } | |
339 | ||
340 | //_____________________________________________________________________________ | |
341 | Int_t AliTRDchamberTimeBin::Find(Float_t y) const | |
342 | { | |
343 | // | |
344 | // Returns index of the cluster nearest in Y | |
345 | // | |
346 | ||
347 | if (fN <= 0) return 0; | |
348 | ||
349 | if (y <= fClusters[0]->GetY()) return 0; | |
350 | ||
351 | if (y > fClusters[fN-1]->GetY()) return fN; | |
352 | ||
353 | ||
354 | Int_t b = 0; | |
355 | Int_t e = fN - 1; | |
356 | Int_t m = (b + e) / 2; | |
357 | ||
358 | for ( ; b < e; m = (b + e) / 2) { | |
359 | if (y > fClusters[m]->GetY()) b = m + 1; | |
360 | else e = m; | |
361 | } | |
362 | ||
363 | return m; | |
364 | } | |
365 | ||
366 | //_____________________________________________________________________________ | |
367 | Int_t AliTRDchamberTimeBin::FindYPosition(Double_t y, UChar_t z, Int_t nClusters) const | |
368 | { | |
369 | // | |
370 | // Tree search Algorithm to find the nearest left cluster for a given | |
371 | // y-position in a certain z-bin (in fact AVL-tree). | |
372 | // Making use of the fact that clusters are sorted in y-direction. | |
373 | // | |
374 | // Parameters: | |
375 | // y : y position of the reference point in tracking coordinates | |
376 | // z : z reference bin. | |
377 | // nClusters : | |
378 | // | |
379 | // Output : | |
380 | // Index of the nearest left cluster in the StackLayer indexing (-1 if no clusters are found) | |
381 | // | |
382 | ||
383 | Int_t start = fPositions[z]; // starting Position of the bin | |
384 | Int_t upper = (Int_t)((z != fNRows - 1) ? fPositions[z+1] : nClusters); // ending Position of the bin | |
385 | Int_t end = upper - 1; // ending Position of the bin | |
386 | if(end < start) return -1; // Bin is empty | |
387 | Int_t middle = static_cast<Int_t>((start + end)/2); | |
388 | // 1st Part: climb down the tree: get the next cluster BEFORE ypos | |
389 | while(start + 1 < end){ | |
390 | if(y >= fClusters[middle]->GetY()) start = middle; | |
391 | else end = middle; | |
392 | middle = static_cast<Int_t>((start + end)/2); | |
393 | } | |
394 | if(y > fClusters[end]->GetY()) return end; | |
395 | return start; | |
396 | } | |
397 | ||
398 | //_____________________________________________________________________________ | |
399 | Int_t AliTRDchamberTimeBin::FindNearestYCluster(Double_t y, UChar_t z) const | |
400 | { | |
401 | // | |
402 | // Tree search Algorithm to find the nearest cluster for a given | |
403 | // y-position in a certain z-bin (in fact AVL-tree). | |
404 | // Making use of the fact that clusters are sorted in y-direction. | |
405 | // | |
406 | // Parameters: | |
407 | // y : y position of the reference point in tracking coordinates | |
408 | // z : z reference bin. | |
409 | // | |
410 | // Output | |
411 | // Index of the nearest cluster in the StackLayer indexing (-1 if no clusters are found) | |
412 | // | |
413 | ||
414 | Int_t position = FindYPosition(y, z, fN); | |
415 | if(position == -1) return position; // bin empty | |
416 | // FindYPosition always returns the left Neighbor. We don't know if the left or the right Neighbor is nearest | |
417 | // to the Reference y-position, so test both | |
418 | Int_t upper = (Int_t)((z < fNRows-1) ? fPositions[z+1] : fN); // ending Position of the bin | |
419 | if((position + 1) < (upper)){ | |
420 | if(TMath::Abs(y - fClusters[position + 1]->GetY()) < TMath::Abs(y - fClusters[position]->GetY())) return position + 1; | |
421 | else return position; | |
422 | } | |
423 | return position; | |
424 | } | |
425 | ||
426 | //_____________________________________________________________________________ | |
427 | Int_t AliTRDchamberTimeBin::SearchNearestCluster(Double_t y, Double_t z, Double_t maxroady, Double_t maxroadz) const | |
428 | { | |
429 | // | |
430 | // Finds the nearest cluster from a given point in a defined range. | |
431 | // Distance is determined in a 2D space by the 2-Norm. | |
432 | // | |
433 | // Parameters : | |
434 | // y : y position of the reference point in tracking coordinates | |
435 | // z : z reference bin. | |
436 | // maxroady : maximum searching distance in y direction | |
437 | // maxroadz : maximum searching distance in z direction | |
438 | // | |
439 | // Output | |
440 | // Index of the nearest cluster in the StackLayer indexing (-1 if no cluster is found). | |
441 | // Cluster can be accessed with the operator[] or GetCluster(Int_t index) | |
442 | // | |
443 | // Detail description | |
444 | // | |
445 | // The following steps are perfomed: | |
446 | // 1. Get the expected z bins inside maxroadz. | |
447 | // 2. For each z bin find nearest y cluster. | |
448 | // 3. Select best candidate | |
449 | // | |
450 | Int_t index = -1; | |
451 | // initial minimal distance will be represented as ellipse: semi-major = z-direction | |
452 | // later 2-Norm will be used | |
453 | // Float_t nExcentricity = TMath::Sqrt(maxroadz*maxroadz - maxroad*maxroad)/maxroadz; | |
454 | Float_t mindist = maxroadz; | |
455 | ||
456 | // not very nice but unfortunately neccessarry: we have ho check the neighbors in both directions (+ and -) too. How | |
457 | // much neighbors depends on the Quotient maxroadz/fZLength | |
458 | UChar_t maxRows = 3; | |
459 | UChar_t zpos[kMaxRows]; | |
460 | // Float_t mindist = TMath::Sqrt(maxroad*maxroad + maxroadz*maxroadz); | |
461 | // UChar_t myZbin = FindTreePosition(z, fZ0 + fZLength/2, fZLength/4, 8, 8, kFALSE); | |
462 | UChar_t myZbin = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - z)/fZLength * fNRows); | |
463 | if(z < fZ0) myZbin = fNRows - 1; | |
464 | if(z > fZ0 + fZLength) myZbin = 0; | |
465 | //printf("\n%f < %f < %f [%d]\n", fZ0, z, fZ0 + fZLength, myZbin); | |
466 | //for(int ic=0; ic<fN; ic++) printf("%d z = %f row %d\n", ic, fClusters[ic]->GetZ(), fClusters[ic]->GetPadRow()); | |
467 | ||
468 | UChar_t nNeighbors = 0; | |
469 | for(UChar_t i = 0; i < maxRows; i++){ | |
470 | if((myZbin - 1 + i) < 0) continue; | |
471 | if((myZbin - 1 + i) > fNRows - 1) break; | |
472 | zpos[nNeighbors] = myZbin - 1 + i; | |
473 | nNeighbors++; | |
474 | } | |
475 | Float_t ycl = 0, zcl = 0; | |
476 | for(UChar_t neighbor = 0; neighbor < nNeighbors; neighbor++){ // Always test the neighbors too | |
477 | Int_t pos = FindNearestYCluster(y, zpos[neighbor]); | |
478 | if(pos == -1) continue; // No cluster in bin | |
479 | AliTRDcluster *c = (AliTRDcluster *) (fClusters[pos]); | |
480 | if(c->IsUsed()) continue; // we are only interested in unused clusters | |
481 | ycl = c->GetY(); | |
482 | // Too far away in y-direction (Prearrangement) | |
483 | if (TMath::Abs(ycl - y) > maxroady){ | |
484 | //printf("y[%f] ycl[%f] roady[%f]\n", y, ycl, maxroady); | |
485 | continue; | |
486 | } | |
487 | zcl = c->GetZ(); | |
488 | // Too far away in z-Direction | |
489 | // (Prearrangement since we have not so many bins to test) | |
490 | if (TMath::Abs(zcl - z) > maxroadz) continue; | |
491 | ||
492 | Float_t dist; // distance defined as 2-Norm | |
493 | // if we havent found a Particle that is in the ellipse around (y,z) with maxroad as semi-minor and | |
494 | // maxroadz as semi-major, we take the radius of the ellipse concerning the cluster as mindist, later we | |
495 | // take the 2-Norm when we found a cluster inside the ellipse (The value 10000 is taken because it is surely | |
496 | // large enough to be usable as an indicator whether we have found a nearer cluster or not) | |
497 | // if(mindist > 10000.){ | |
498 | // Float_t phi = ((zcl - z) == 0) ? TMath::Pi()/2 : TMath::ATan((ycl - y)/(zcl - z)); | |
499 | // mindist = maxroad/TMath::Sqrt(1 - nExcentricity*nExcentricity * (TMath::Cos(phi))*(TMath::Cos(phi))); | |
500 | // } | |
501 | dist = TMath::Max(TMath::Abs(y-ycl),TMath::Abs(z-zcl)); // infinity Norm | |
502 | // dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z)); | |
503 | if((Int_t)(dist * 100000) < (Int_t)(mindist * 100000)){ | |
504 | //if((dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z))) < mindist){ | |
505 | mindist = dist; | |
506 | index = pos; | |
507 | } | |
508 | } | |
509 | // This is the Array Position in fIndex2D of the Nearest cluster: if a | |
510 | // cluster is called, then the function has to retrieve the Information | |
511 | // which is Stored in the Array called, the function | |
512 | return index; | |
513 | } | |
514 | ||
515 | //_____________________________________________________________________________ | |
4d6aee34 | 516 | void AliTRDchamberTimeBin::BuildCond(AliTRDcluster * const cl, Double_t *cond, UChar_t Layer, Double_t theta, Double_t phi) |
2a4a428a | 517 | { |
518 | // Helper function to calculate the area where to expect a cluster in THIS | |
519 | // layer. | |
520 | // | |
521 | // Parameters : | |
522 | // cl : | |
523 | // cond : | |
524 | // Layer : | |
525 | // theta : | |
526 | // phi : | |
527 | // | |
528 | // Detail description | |
529 | // | |
530 | // Helper function to calculate the area where to expect a cluster in THIS | |
531 | // layer. by using the information of a former cluster in another layer | |
532 | // and the angle in theta- and phi-direction between layer 0 and layer 3. | |
533 | // If the layer is zero, initial conditions are calculated. Otherwise a | |
534 | // linear interpolation is performed. | |
535 | //Begin_Html | |
536 | //<img src="gif/build_cond.gif"> | |
537 | //End_Html | |
538 | // | |
539 | ||
4d6aee34 | 540 | if(!fkReconstructor){ |
2a4a428a | 541 | AliError("Reconstructor not set."); |
542 | return; | |
543 | } | |
544 | ||
545 | if(Layer == 0){ | |
546 | cond[0] = cl->GetY(); // center: y-Direction | |
547 | cond[1] = cl->GetZ(); // center: z-Direction | |
4d6aee34 | 548 | cond[2] = fkReconstructor->GetRecoParam()->GetMaxPhi() * (cl->GetX() - GetX()) + 1.0; // deviation: y-Direction |
549 | cond[3] = fkReconstructor->GetRecoParam()->GetMaxTheta() * (cl->GetX() - GetX()) + 1.0; // deviation: z-Direction | |
2a4a428a | 550 | } else { |
551 | cond[0] = cl->GetY() + phi * (GetX() - cl->GetX()); | |
552 | cond[1] = cl->GetZ() + theta * (GetX() - cl->GetX()); | |
4d6aee34 | 553 | cond[2] = fkReconstructor->GetRecoParam()->GetRoad0y() + phi; |
554 | cond[3] = fkReconstructor->GetRecoParam()->GetRoad0z(); | |
2a4a428a | 555 | } |
556 | } | |
557 | ||
558 | //_____________________________________________________________________________ | |
4d6aee34 | 559 | void AliTRDchamberTimeBin::GetClusters(const Double_t * const cond, Int_t *index, Int_t& ncl, Int_t BufferSize) |
2a4a428a | 560 | { |
561 | // Finds all clusters situated in this layer inside a rectangle given by the center an ranges. | |
562 | // | |
563 | // Parameters : | |
564 | // cond : | |
565 | // index : | |
566 | // ncl : | |
567 | // BufferSize : | |
568 | // | |
569 | // Output : | |
570 | // | |
571 | // Detail description | |
572 | // | |
573 | // Function returs an array containing the indices in the stacklayer of | |
574 | // the clusters found an the number of found clusters in the stacklayer | |
575 | ||
576 | ncl = 0; | |
577 | memset(index, 0, BufferSize*sizeof(Int_t)); | |
578 | if(fN == 0) return; | |
579 | ||
580 | //Boundary checks | |
581 | Double_t zvals[2]; | |
582 | if(((cond[1] - cond[3]) >= (fZ0 + fZLength)) || (cond[1] + cond[3]) <= fZ0) return; // We are outside of the chamvber | |
583 | zvals[0] = ((cond[1] - cond[3]) < fZ0) ? fZ0 : (cond[1] - cond[3]); | |
584 | zvals[1] = ((cond[1] + cond[3]) < fZ0 + fZLength) ? (cond[1] + cond[3]) : fZ0 + fZLength - 1.E-3; | |
585 | ||
586 | UChar_t zhi = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - zvals[0])/fZLength * fNRows); | |
587 | UChar_t zlo = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - zvals[1])/fZLength * fNRows); | |
588 | ||
589 | /* AliInfo(Form("yc[%f] zc[%f] dy[%f] dz[%f]", cond[0], cond[1], cond[2], cond[3])); | |
590 | PrintClusters(); | |
591 | AliInfo(Form("zlo[%f] zhi[%f]", zvals[0], zvals[1])); | |
592 | AliInfo(Form("zlo[%d] zhi[%d]", zlo, zhi));*/ | |
fd40f855 | 593 | |
594 | Double_t ylo = cond[0] - cond[2], | |
595 | yhi = cond[0] + cond[2]; | |
596 | //printf("CTB : ylo[%f] yhi[%f]\n", ylo, yhi); | |
2a4a428a | 597 | //Preordering in Direction z saves a lot of loops (boundary checked) |
598 | for(UChar_t z = zlo; z <= zhi; z++){ | |
599 | UInt_t upper = (z < fNRows-1) ? fPositions[z+1] : fN; | |
600 | //AliInfo(Form("z[%d] y [%d %d]", z, fPositions[z], upper)); | |
601 | for(Int_t y = fPositions[z]; y < (Int_t)upper; y++){ | |
602 | if(ncl == BufferSize){ | |
980d5a2a | 603 | AliDebug(1, Form("Buffer size [%d] riched. Some clusters may be lost.", BufferSize)); |
2a4a428a | 604 | return; //Buffer filled |
605 | } | |
606 | ||
fd40f855 | 607 | if(fClusters[y]->GetY() > yhi) break; // Abbortion conditions!!! |
608 | if(fClusters[y]->GetY() < ylo) continue; // Too small | |
2a4a428a | 609 | if(((Int_t)((fClusters[y]->GetZ())*1000) < (Int_t)(zvals[0]*1000)) || ((Int_t)((fClusters[y]->GetZ())*1000) > (Int_t)(zvals[1]*1000))){/*printf("exit z\n"); TODO*/ continue;} |
610 | index[ncl] = y; | |
611 | ncl++; | |
612 | } | |
613 | } | |
614 | if(ncl>fN) AliError(Form("Clusters found %d > %d (clusters in layer)", ncl, fN)); | |
615 | } | |
616 | ||
617 | //_____________________________________________________________________________ | |
618 | AliTRDcluster *AliTRDchamberTimeBin::GetNearestCluster(Double_t *cond) | |
619 | { | |
620 | // Function returning a pointer to the nearest cluster (nullpointer if not successfull). | |
621 | // | |
622 | // Parameters : | |
623 | // cond : | |
624 | // | |
625 | // Output : | |
626 | // pointer to the nearest cluster (nullpointer if not successfull). | |
627 | // | |
628 | // Detail description | |
629 | // | |
630 | // returns a pointer to the nearest cluster (nullpointer if not | |
631 | // successfull) by the help of the method FindNearestCluster | |
632 | ||
633 | ||
4d6aee34 | 634 | Double_t maxroad = fkReconstructor->GetRecoParam()->GetRoad2y(); |
635 | Double_t maxroadz = fkReconstructor->GetRecoParam()->GetRoad2z(); | |
2a4a428a | 636 | |
637 | Int_t index = SearchNearestCluster(cond[0],cond[1],maxroad,maxroadz); | |
4d6aee34 | 638 | AliTRDcluster *returnCluster = NULL; |
2a4a428a | 639 | if(index != -1) returnCluster = (AliTRDcluster *) fClusters[index]; |
640 | return returnCluster; | |
641 | } | |
642 | ||
643 | //_____________________________________________________________________________ | |
6c207d50 | 644 | void AliTRDchamberTimeBin::Print(Option_t *) const |
2a4a428a | 645 | { |
646 | // Prints the position of each cluster in the stacklayer on the stdout | |
647 | // | |
6c207d50 | 648 | if(!fN) return; |
ac1dec3b | 649 | AliInfo(Form("Layer[%d] Stack[%d] Sector[%2d] nRows[%2d]", fPlane, fStack, fSector, fNRows)); |
6c207d50 | 650 | AliInfo(Form("Z0[%7.3f] Z1[%7.3f]", fZ0, fZ0+fZLength)); |
651 | AliTRDcluster* const* icl = &fClusters[0]; | |
652 | for(Int_t jcl = 0; jcl < fN; jcl++, icl++){ | |
653 | AliInfo(Form("%2d X[%7.3f] Y[%7.3f] Z[%7.3f] tb[%2d] col[%3d] row[%2d] used[%s]", jcl, (*icl)->GetX(), (*icl)->GetY(), (*icl)->GetZ(), (*icl)->GetLocalTimeBin(), (*icl)->GetPadCol(), (*icl)->GetPadRow(), | |
654 | (*icl)->IsUsed() ? "y" : "n")); | |
2a4a428a | 655 | } |
ac1dec3b | 656 | Int_t irow = 0; |
657 | for(UChar_t const* pos = &fPositions[0]; irow<fNRows; pos++, irow++){ | |
658 | if((*pos) != 0xff) AliInfo(Form("r[%2d] pos[%d]", irow, (*pos))); | |
659 | } | |
2a4a428a | 660 | } |