]>
Commit | Line | Data |
---|---|---|
e4f2f73d | 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 | // 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> | |
34 | #include <TROOT.h> | |
35 | #include <TMath.h> | |
36 | #include <TStopwatch.h> | |
37 | #include <TTreeStream.h> | |
38 | ||
39 | #include "AliLog.h" | |
40 | #include "AliTRDcluster.h" | |
41 | ||
42 | #include "AliTRDstackLayer.h" | |
43 | #include "AliTRDrecoParam.h" | |
44 | #include "AliTRDReconstructor.h" | |
45 | ||
46 | #define DEBUG | |
47 | ||
48 | ClassImp(AliTRDstackLayer) | |
49 | ||
50 | //_____________________________________________________________________________ | |
51 | AliTRDstackLayer::AliTRDstackLayer(Double_t z0, Double_t zLength | |
52 | , UChar_t stackNr, AliTRDrecoParam *p) | |
53 | :AliTRDpropagationLayer() | |
54 | ,fOwner(kFALSE) | |
55 | ,fStackNr(stackNr) | |
56 | ,fNRows(kMaxRows) | |
57 | ,fZ0(z0) | |
58 | ,fZLength(zLength) | |
59 | ,fRecoParam(p) | |
60 | ,fDebugStream(0x0) | |
61 | { | |
62 | // | |
63 | // Default constructor (Only provided to use AliTRDstackLayer with arrays) | |
64 | // | |
65 | ||
66 | for(int i=0; i<kMaxRows; i++) fPositions[i] = 0; | |
67 | } | |
68 | ||
69 | //_____________________________________________________________________________ | |
70 | AliTRDstackLayer::AliTRDstackLayer(const AliTRDpropagationLayer &layer, Double_t | |
71 | z0, Double_t zLength, UChar_t stackNr, AliTRDrecoParam *p): | |
72 | AliTRDpropagationLayer(layer) | |
73 | ,fOwner(kFALSE) | |
74 | ,fStackNr(stackNr) | |
75 | ,fNRows(kMaxRows) | |
76 | ,fZ0(z0) | |
77 | ,fZLength(zLength) | |
78 | ,fRecoParam(p) | |
79 | ,fDebugStream(0x0) | |
80 | { | |
81 | // Standard constructor. | |
82 | // Initialize also the underlying AliTRDpropagationLayer using the copy constructor. | |
83 | ||
bcb6fb78 | 84 | SetT0(layer.IsT0()); |
e4f2f73d | 85 | for(int i=0; i<kMaxRows; i++) fPositions[i] = 0; |
86 | } | |
87 | ||
88 | //_____________________________________________________________________________ | |
89 | AliTRDstackLayer::AliTRDstackLayer(const AliTRDpropagationLayer &layer): | |
90 | AliTRDpropagationLayer(layer) | |
91 | ,fOwner(kFALSE) | |
92 | ,fStackNr(0) | |
93 | ,fNRows(kMaxRows) | |
94 | ,fZ0(0) | |
95 | ,fZLength(0) | |
96 | ,fRecoParam(0x0) | |
97 | ,fDebugStream(0x0) | |
98 | { | |
99 | // Standard constructor using only AliTRDpropagationLayer. | |
100 | ||
bcb6fb78 | 101 | SetT0(layer.IsT0()); |
e4f2f73d | 102 | for(int i=0; i<kMaxRows; i++) fPositions[i] = 0; |
103 | } | |
104 | ||
105 | //_____________________________________________________________________________ | |
106 | AliTRDstackLayer::AliTRDstackLayer(const AliTRDstackLayer &layer): | |
107 | AliTRDpropagationLayer(layer) | |
108 | ,fOwner(layer.fOwner) | |
109 | ,fStackNr(layer.fStackNr) | |
110 | ,fNRows(layer.fNRows) | |
111 | ,fZ0(layer.fZ0) | |
112 | ,fZLength(layer.fZLength) | |
113 | ,fRecoParam(layer.fRecoParam) | |
114 | ,fDebugStream(layer.fDebugStream) | |
115 | { | |
116 | // Copy Constructor (performs a deep copy) | |
117 | ||
bcb6fb78 | 118 | SetT0(layer.IsT0()); |
e4f2f73d | 119 | for(Int_t i = 0; i < kMaxRows; i++) fPositions[i] = layer.fPositions[i]; |
120 | // BuildIndices(); | |
121 | } | |
122 | ||
123 | //_____________________________________________________________________________ | |
124 | AliTRDstackLayer &AliTRDstackLayer::operator=(const AliTRDpropagationLayer &layer) | |
125 | { | |
126 | // Assignment operator from an AliTRDpropagationLayer | |
127 | ||
128 | if (this != &layer) layer.Copy(*this); | |
129 | return *this; | |
130 | } | |
131 | ||
132 | //_____________________________________________________________________________ | |
133 | AliTRDstackLayer &AliTRDstackLayer::operator=(const AliTRDstackLayer &layer) | |
134 | { | |
135 | // Assignment operator | |
136 | ||
137 | if (this != &layer) layer.Copy(*this); | |
138 | return *this; | |
139 | } | |
140 | ||
141 | //_____________________________________________________________________________ | |
142 | void AliTRDstackLayer::Copy(TObject &o) const | |
143 | { | |
144 | // Copy method. Performs a deep copy of all data from this object to object o. | |
145 | ||
146 | AliTRDstackLayer &layer = (AliTRDstackLayer &)o; | |
147 | layer.fZ0 = fZ0; | |
148 | layer.fOwner = kFALSE; | |
149 | layer.fNRows = fNRows; | |
150 | layer.fZLength = fZLength; | |
151 | layer.fStackNr = fStackNr; | |
152 | layer.fDebugStream = fDebugStream; | |
153 | layer.fRecoParam = fRecoParam; | |
bcb6fb78 | 154 | layer.SetT0(IsT0()); |
e4f2f73d | 155 | |
156 | AliTRDpropagationLayer::Copy(layer); // copies everything into layer | |
157 | for(UChar_t i = 0; i < kMaxRows; i++) layer.fPositions[i] = 0; | |
158 | // layer.BuildIndices(); | |
159 | } | |
160 | ||
161 | //_____________________________________________________________________________ | |
162 | AliTRDstackLayer::~AliTRDstackLayer() | |
163 | { | |
164 | // Destructor | |
165 | if(fOwner) for(int ic=0; ic<fN; ic++) delete fClusters[ic]; | |
166 | } | |
167 | ||
168 | //_____________________________________________________________________________ | |
169 | void AliTRDstackLayer::SetRange(const Float_t z0, const Float_t zLength) | |
170 | { | |
171 | // Sets the range in z-direction | |
172 | // | |
173 | // Parameters: | |
174 | // z0 : starting position of layer in the z direction | |
175 | // zLength : length of layer in the z direction | |
176 | ||
177 | fZ0 = (z0 <= z0 + zLength) ? z0 : z0 + zLength; | |
178 | fZLength = TMath::Abs(zLength); | |
179 | } | |
180 | ||
181 | //_____________________________________________________________________________ | |
182 | void AliTRDstackLayer::BuildIndices(Int_t iter) | |
183 | { | |
184 | // Rearrangement of the clusters belonging to the propagation layer for the stack. | |
185 | // | |
186 | // Detailed description | |
187 | // | |
188 | // The array indices of all clusters in one PropagationLayer are stored in | |
189 | // array. The array is divided into several bins. | |
190 | // The clusters are sorted in increasing order of their y coordinate. | |
191 | // | |
192 | // Sorting algorithm: TreeSearch | |
193 | // | |
194 | ||
195 | if(!fN) return; | |
196 | ||
197 | // Select clusters that belong to the Stack | |
198 | Int_t nClStack = 0; // Internal counter | |
199 | for(Int_t i = 0; i < fN; i++){ | |
200 | Double_t zval = fClusters[i]->GetZ(); | |
201 | if(zval < fZ0 || zval > fZ0 + fZLength || fClusters[i]->IsUsed()){ | |
202 | fClusters[i] = 0x0; | |
203 | fIndex[i] = 9999; | |
204 | } else nClStack++; | |
205 | } | |
206 | if(nClStack > kMaxClustersLayer) AliWarning(Form("Number of clusters in stack %d exceed buffer size %d", nClStack, kMaxClustersLayer)); | |
207 | ||
208 | // Nothing in this Stack | |
209 | if(!nClStack){ | |
210 | delete fClusters; | |
211 | delete fIndex; | |
212 | fClusters = 0x0; | |
213 | fIndex = 0x0; | |
214 | fN = 0; | |
215 | memset(fPositions, 0, sizeof(UChar_t) * 16); | |
216 | return; | |
217 | } | |
218 | ||
219 | // Make a copy | |
220 | AliTRDcluster *helpCL[kMaxClustersLayer]; | |
221 | Int_t helpInd[kMaxClustersLayer]; | |
222 | nClStack = 0; | |
223 | for(Int_t i = 0; i < TMath::Min(fN, kMaxClustersLayer); i++){ | |
224 | if(!fClusters[i]) continue; | |
225 | helpCL[nClStack] = fClusters[i]; | |
226 | helpInd[nClStack] = fIndex[i]; | |
227 | fClusters[i] = 0x0; | |
228 | fIndex[i] = 9999; | |
229 | nClStack++; | |
230 | } | |
231 | ||
232 | // do clusters arrangement | |
233 | fN = nClStack; | |
234 | nClStack = 0; | |
235 | memset(fPositions,0,sizeof(UChar_t)*16); // Reset Positions array | |
236 | for(Int_t i = 0; i < fN; i++){ | |
237 | // boundarie check | |
238 | AliTRDcluster *cl = helpCL[i]; | |
239 | Double_t zval = cl->GetZ(); | |
d76231c8 | 240 | UChar_t treeIndex = (UChar_t)(TMath::Abs(fZ0 - zval)/fZLength * fNRows); |
241 | if(treeIndex > fNRows - 1) treeIndex = fNRows - 1; | |
e4f2f73d | 242 | // Insert Leaf |
d76231c8 | 243 | Int_t pos = FindYPosition(cl->GetY(), treeIndex, i); |
e4f2f73d | 244 | if(pos == -1){ // zbin is empty; |
d76231c8 | 245 | Int_t upper = (treeIndex == fNRows - 1) ? nClStack : fPositions[treeIndex + 1]; |
e4f2f73d | 246 | memmove(fClusters + upper + 1, fClusters + upper, (sizeof(AliTRDcluster *))*(nClStack-upper)); |
247 | memmove(fIndex + upper + 1, fIndex + upper, (sizeof(UInt_t))*(nClStack-upper)); | |
248 | fClusters[upper] = cl; | |
249 | fIndex[upper] = helpInd[i]; | |
250 | // Move All pointer one position back | |
d76231c8 | 251 | for(UChar_t j = treeIndex + 1; j < fNRows; j++) fPositions[j]++; |
e4f2f73d | 252 | nClStack++; |
253 | } else { // zbin not empty | |
254 | memmove(fClusters + pos + 2, fClusters + pos+1, (sizeof(AliTRDcluster *))*(nClStack-(pos+1))); | |
255 | memmove(fIndex + pos + 2, fIndex + pos+1, (sizeof(UInt_t))*(nClStack-(pos+1))); | |
256 | fClusters[pos + 1] = cl; //fIndex[i]; | |
257 | fIndex[pos + 1] = helpInd[i]; | |
258 | // Move All pointer one position back | |
d76231c8 | 259 | for(UChar_t j = treeIndex + 1; j < fNRows; j++) fPositions[j]++; |
e4f2f73d | 260 | nClStack++; |
261 | } | |
262 | ||
263 | ||
264 | // Debug Streaming | |
265 | #ifdef DEBUG | |
266 | if(fDebugStream && AliTRDReconstructor::StreamLevel() >= 3){ | |
267 | TTreeSRedirector &cstream = *fDebugStream; | |
268 | cstream << "BuildIndices" | |
269 | << "StackNr=" << fStackNr | |
270 | << "SectorNr=" << fSec | |
271 | << "Iter=" << iter | |
272 | << "C.=" << cl | |
d76231c8 | 273 | << "TreeIdx=" << treeIndex |
e4f2f73d | 274 | << "\n"; |
275 | } | |
276 | #endif | |
277 | } | |
278 | } | |
279 | ||
280 | //_____________________________________________________________________________ | |
281 | Int_t AliTRDstackLayer::FindYPosition(Double_t y, UChar_t z, Int_t nClusters) const | |
282 | { | |
283 | // | |
284 | // Tree search Algorithm to find the nearest left cluster for a given | |
285 | // y-position in a certain z-bin (in fact AVL-tree). | |
286 | // Making use of the fact that clusters are sorted in y-direction. | |
287 | // | |
288 | // Parameters: | |
289 | // y : y position of the reference point in tracking coordinates | |
290 | // z : z reference bin. | |
291 | // nClusters : | |
292 | // | |
293 | // Output : | |
294 | // Index of the nearest left cluster in the StackLayer indexing (-1 if no clusters are found) | |
295 | // | |
296 | ||
297 | Int_t start = fPositions[z]; // starting Position of the bin | |
298 | Int_t upper = (Int_t)((z != fNRows - 1) ? fPositions[z+1] : nClusters); // ending Position of the bin | |
299 | Int_t end = upper - 1; // ending Position of the bin | |
300 | if(end < start) return -1; // Bin is empty | |
301 | Int_t middle = static_cast<Int_t>((start + end)/2); | |
302 | // 1st Part: climb down the tree: get the next cluster BEFORE ypos | |
303 | while(start + 1 < end){ | |
304 | if(y >= fClusters[middle]->GetY()) start = middle; | |
305 | else end = middle; | |
306 | middle = static_cast<Int_t>((start + end)/2); | |
307 | } | |
308 | if(y > fClusters[end]->GetY()) return end; | |
309 | return start; | |
310 | } | |
311 | ||
312 | //_____________________________________________________________________________ | |
313 | Int_t AliTRDstackLayer::FindNearestYCluster(Double_t y, UChar_t z) const | |
314 | { | |
315 | // | |
316 | // Tree search Algorithm to find the nearest cluster for a given | |
317 | // y-position in a certain z-bin (in fact AVL-tree). | |
318 | // Making use of the fact that clusters are sorted in y-direction. | |
319 | // | |
320 | // Parameters: | |
321 | // y : y position of the reference point in tracking coordinates | |
322 | // z : z reference bin. | |
323 | // | |
324 | // Output | |
325 | // Index of the nearest cluster in the StackLayer indexing (-1 if no clusters are found) | |
326 | // | |
327 | ||
328 | Int_t position = FindYPosition(y, z, fN); | |
329 | if(position == -1) return position; // bin empty | |
330 | // FindYPosition always returns the left Neighbor. We don't know if the left or the right Neighbor is nearest | |
331 | // to the Reference y-position, so test both | |
332 | Int_t upper = (Int_t)((z < fNRows-1) ? fPositions[z+1] : fN); // ending Position of the bin | |
333 | if((position + 1) < (upper)){ | |
334 | if(TMath::Abs(y - fClusters[position + 1]->GetY()) < TMath::Abs(y - fClusters[position]->GetY())) return position + 1; | |
335 | else return position; | |
336 | } | |
337 | return position; | |
338 | } | |
339 | ||
340 | //_____________________________________________________________________________ | |
341 | Int_t AliTRDstackLayer::SearchNearestCluster(Double_t y, Double_t z, Double_t maxroady, Double_t maxroadz) const | |
342 | { | |
343 | // | |
344 | // Finds the nearest cluster from a given point in a defined range. | |
345 | // Distance is determined in a 2D space by the 2-Norm. | |
346 | // | |
347 | // Parameters : | |
348 | // y : y position of the reference point in tracking coordinates | |
349 | // z : z reference bin. | |
350 | // maxroady : maximum searching distance in y direction | |
351 | // maxroadz : maximum searching distance in z direction | |
352 | // | |
353 | // Output | |
354 | // Index of the nearest cluster in the StackLayer indexing (-1 if no cluster is found). | |
355 | // Cluster can be accessed with the operator[] or GetCluster(Int_t index) | |
356 | // | |
357 | // Detail description | |
358 | // | |
359 | // The following steps are perfomed: | |
360 | // 1. Get the expected z bins inside maxroadz. | |
361 | // 2. For each z bin find nearest y cluster. | |
362 | // 3. Select best candidate | |
363 | // | |
364 | Int_t index = -1; | |
365 | // initial minimal distance will be represented as ellipse: semi-major = z-direction | |
366 | // later 2-Norm will be used | |
367 | // Float_t nExcentricity = TMath::Sqrt(maxroadz*maxroadz - maxroad*maxroad)/maxroadz; | |
368 | Float_t mindist = maxroadz; | |
369 | ||
370 | // not very nice but unfortunately neccessarry: we have ho check the neighbors in both directions (+ and -) too. How | |
371 | // much neighbors depends on the Quotient maxroadz/fZLength | |
372 | UChar_t maxRows = 3; | |
373 | UChar_t zpos[kMaxRows]; | |
374 | // Float_t mindist = TMath::Sqrt(maxroad*maxroad + maxroadz*maxroadz); | |
375 | // UChar_t myZbin = FindTreePosition(z, fZ0 + fZLength/2, fZLength/4, 8, 8, kFALSE); | |
376 | UChar_t myZbin = (UChar_t)(TMath::Abs(fZ0 - z)/fZLength * fNRows); | |
377 | if(z < fZ0) myZbin = 0; | |
378 | if(z > fZ0 + fZLength) myZbin = fNRows - 1; | |
379 | ||
380 | UChar_t nNeighbors = 0; | |
381 | for(UChar_t i = 0; i < maxRows; i++){ | |
382 | if((myZbin - 1 + i) < 0) continue; | |
383 | if((myZbin - 1 + i) > fNRows - 1) break; | |
384 | zpos[nNeighbors] = myZbin - 1 + i; | |
385 | nNeighbors++; | |
386 | } | |
387 | Float_t ycl = 0, zcl = 0; | |
388 | for(UChar_t neighbor = 0; neighbor < nNeighbors; neighbor++){ // Always test the neighbors too | |
389 | Int_t pos = FindNearestYCluster(y,zpos[neighbor]); | |
390 | if(pos == -1) continue; // No cluster in bin | |
391 | AliTRDcluster *c = (AliTRDcluster *) (fClusters[pos]); | |
392 | if(c->IsUsed()) continue; // we are only interested in unused clusters | |
393 | ycl = c->GetY(); | |
394 | // Too far away in y-direction (Prearrangement) | |
395 | if (TMath::Abs(ycl - y) > maxroady) continue; | |
396 | ||
397 | zcl = c->GetZ(); | |
398 | // Too far away in z-Direction | |
399 | // (Prearrangement since we have not so many bins to test) | |
400 | if (TMath::Abs(zcl - z) > maxroadz) continue; | |
401 | ||
402 | Float_t dist; // distance defined as 2-Norm | |
403 | // if we havent found a Particle that is in the ellipse around (y,z) with maxroad as semi-minor and | |
404 | // maxroadz as semi-major, we take the radius of the ellipse concerning the cluster as mindist, later we | |
405 | // take the 2-Norm when we found a cluster inside the ellipse (The value 10000 is taken because it is surely | |
406 | // large enough to be usable as an indicator whether we have found a nearer cluster or not) | |
407 | // if(mindist > 10000.){ | |
408 | // Float_t phi = ((zcl - z) == 0) ? TMath::Pi()/2 : TMath::ATan((ycl - y)/(zcl - z)); | |
409 | // mindist = maxroad/TMath::Sqrt(1 - nExcentricity*nExcentricity * (TMath::Cos(phi))*(TMath::Cos(phi))); | |
410 | // } | |
411 | dist = TMath::Max(TMath::Abs(y-ycl),TMath::Abs(z-zcl)); // infinity Norm | |
412 | // dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z)); | |
413 | if((Int_t)(dist * 100000) < (Int_t)(mindist * 100000)){ | |
414 | //if((dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z))) < mindist){ | |
415 | mindist = dist; | |
416 | index = pos; | |
417 | } | |
418 | } | |
419 | // This is the Array Position in fIndex2D of the Nearest cluster: if a | |
420 | // cluster is called, then the function has to retrieve the Information | |
421 | // which is Stored in the Array called, the function | |
422 | return index; | |
423 | } | |
424 | ||
425 | //_____________________________________________________________________________ | |
426 | void AliTRDstackLayer::BuildCond(AliTRDcluster *cl, Double_t *cond, UChar_t Layer, Double_t theta, Double_t phi) | |
427 | { | |
428 | // Helper function to calculate the area where to expect a cluster in THIS | |
429 | // layer. | |
430 | // | |
431 | // Parameters : | |
432 | // cl : | |
433 | // cond : | |
434 | // Layer : | |
435 | // theta : | |
436 | // phi : | |
437 | // | |
438 | // Detail description | |
439 | // | |
440 | // Helper function to calculate the area where to expect a cluster in THIS | |
441 | // layer. by using the information of a former cluster in another layer | |
442 | // and the angle in theta- and phi-direction between layer 0 and layer 3. | |
443 | // If the layer is zero, initial conditions are calculated. Otherwise a | |
444 | // linear interpolation is performed. | |
445 | //Begin_Html | |
446 | //<img src="gif/build_cond.gif"> | |
447 | //End_Html | |
448 | // | |
449 | ||
450 | if(!fRecoParam){ | |
451 | AliError("Reconstruction parameters not initialized."); | |
452 | return; | |
453 | } | |
454 | ||
455 | if(Layer == 0){ | |
456 | cond[0] = cl->GetY(); // center: y-Direction | |
457 | cond[1] = cl->GetZ(); // center: z-Direction | |
458 | cond[2] = fRecoParam->GetMaxPhi() * (cl->GetX() - GetX()) + 1.0; // deviation: y-Direction | |
459 | cond[3] = fRecoParam->GetMaxTheta() * (cl->GetX() - GetX()) + 1.0; // deviation: z-Direction | |
460 | } else { | |
461 | cond[0] = cl->GetY() + phi * (GetX() - cl->GetX()); | |
462 | cond[1] = cl->GetZ() + theta * (GetX() - cl->GetX()); | |
463 | cond[2] = fRecoParam->GetRoad0y() + phi; | |
464 | cond[3] = fRecoParam->GetRoad0z(); | |
465 | } | |
466 | } | |
467 | ||
468 | //_____________________________________________________________________________ | |
469 | void AliTRDstackLayer::GetClusters(Double_t *cond, Int_t *index, Int_t& ncl, Int_t BufferSize) | |
470 | { | |
471 | // Finds all clusters situated in this layer inside a rectangle given by the center an ranges. | |
472 | // | |
473 | // Parameters : | |
474 | // cond : | |
475 | // index : | |
476 | // ncl : | |
477 | // BufferSize : | |
478 | // | |
479 | // Output : | |
480 | // | |
481 | // Detail description | |
482 | // | |
483 | // Function returs an array containing the indices in the stacklayer of | |
484 | // the clusters found an the number of found clusters in the stacklayer | |
485 | ||
486 | ncl = 0; | |
487 | memset(index, 0, BufferSize*sizeof(Int_t)); | |
488 | if(fN == 0) return; | |
489 | ||
490 | //Boundary checks | |
491 | Double_t zvals[2]; | |
492 | zvals[0] = ((cond[1] - cond[3]) < fZ0) ? fZ0 : (cond[1] - cond[3]); | |
493 | zvals[1] = ((cond[1] + cond[3]) < fZ0 + fZLength) ? (cond[1] + cond[3]) : fZ0 + fZLength; | |
494 | ||
495 | UChar_t zlo = (fZ0>zvals[0]) ? 0 : (UChar_t)(TMath::Abs(fZ0 - zvals[0])/fZLength * fNRows); | |
496 | UChar_t zhi = (fZ0+fZLength<zvals[1]) ? fNRows - 1 : (UChar_t)(TMath::Abs(fZ0 - zvals[1])/fZLength * fNRows); | |
497 | ||
498 | //Preordering in Direction z saves a lot of loops (boundary checked) | |
499 | for(UChar_t z = zlo; z <= zhi; z++){ | |
1e8d1d74 | 500 | UInt_t upper = (z < fNRows-1) ? fPositions[z+1] : fN; |
e4f2f73d | 501 | for(Int_t y = fPositions[z]; y < (Int_t)upper; y++){ |
502 | if(ncl == BufferSize){ | |
503 | AliWarning("Buffer size riched. Some clusters may be lost."); | |
504 | return; //Buffer filled | |
505 | } | |
506 | if(fClusters[y]->GetY() > (cond[0] + cond[2])) break; // Abbortion conditions!!! | |
507 | if(fClusters[y]->GetY() < (cond[0] - cond[2])) continue; // Too small | |
508 | if(((Int_t)((fClusters[y]->GetZ())*1000) < (Int_t)(zvals[0]*1000)) || ((Int_t)((fClusters[y]->GetZ())*1000) > (Int_t)(zvals[1]*1000))) continue; | |
509 | index[ncl] = y; | |
510 | ncl++; | |
511 | } | |
512 | } | |
513 | if(ncl>fN) AliError(Form("Clusters found %d > %d (clusters in layer)", ncl, fN)); | |
514 | } | |
515 | ||
516 | //_____________________________________________________________________________ | |
517 | AliTRDcluster *AliTRDstackLayer::GetNearestCluster(Double_t *cond) | |
518 | { | |
519 | // Function returning a pointer to the nearest cluster (nullpointer if not successfull). | |
520 | // | |
521 | // Parameters : | |
522 | // cond : | |
523 | // | |
524 | // Output : | |
525 | // pointer to the nearest cluster (nullpointer if not successfull). | |
526 | // | |
527 | // Detail description | |
528 | // | |
529 | // returns a pointer to the nearest cluster (nullpointer if not | |
530 | // successfull) by the help of the method FindNearestCluster | |
531 | ||
532 | ||
533 | Double_t maxroad = fRecoParam->GetRoad2y(); | |
534 | Double_t maxroadz = fRecoParam->GetRoad2z(); | |
535 | ||
536 | Int_t index = SearchNearestCluster(cond[0],cond[1],maxroad,maxroadz); | |
537 | AliTRDcluster *returnCluster = 0x0; | |
538 | if(index != -1) returnCluster = (AliTRDcluster *) fClusters[index]; | |
539 | return returnCluster; | |
540 | } | |
541 | ||
542 | //_____________________________________________________________________________ | |
543 | void AliTRDstackLayer::PrintClusters() const | |
544 | { | |
545 | // Prints the position of each cluster in the stacklayer on the stdout | |
546 | // | |
669ade02 | 547 | //printf("fDebugStream = %#o\n", ((Int_t) fDebugStream)); |
548 | //printf("fRecoParam = %#o\n", ((Int_t) fRecoParam)); | |
e4f2f73d | 549 | |
550 | for(Int_t i = 0; i < fN; i++){ | |
551 | printf("AliTRDstackLayer: index=%i, Cluster: X = %3.3f, Y = %3.3f, Z = %3.3f\n", i, fClusters[i]->GetX(),fClusters[i]->GetY(),fClusters[i]->GetZ()); | |
552 | if(fClusters[i]->IsUsed()) printf("cluster allready used. rejected in search algorithm\n"); | |
553 | } | |
554 | } |