]>
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 | |
290 | for(Int_t i = 0; i < fN; i++){ | |
291 | // boundary check | |
292 | AliTRDcluster *cl = *(cliter++); | |
293 | UChar_t rowIndex = cl->GetPadRow(); | |
294 | // Insert Leaf | |
295 | Int_t pos = FindYPosition(cl->GetY(), rowIndex, i); | |
296 | if(pos == -1){ // zbin is empty; | |
297 | Int_t upper = (rowIndex == fNRows - 1) ? nClStack : fPositions[rowIndex + 1]; | |
298 | memmove(fClusters + upper + 1, fClusters + upper, (sizeof(AliTRDcluster *))*(nClStack-upper)); | |
299 | memmove(fIndex + upper + 1, fIndex + upper, (sizeof(UInt_t))*(nClStack-upper)); | |
300 | fClusters[upper] = cl; | |
301 | fIndex[upper] = helpInd[i]; | |
302 | // Move All pointer one position back | |
303 | for(UChar_t j = rowIndex + 1; j < fNRows; j++) fPositions[j]++; | |
304 | nClStack++; | |
305 | } else { // zbin not empty | |
306 | memmove(fClusters + pos + 2, fClusters + pos+1, (sizeof(AliTRDcluster *))*(nClStack-(pos+1))); | |
307 | memmove(fIndex + pos + 2, fIndex + pos+1, (sizeof(UInt_t))*(nClStack-(pos+1))); | |
308 | fClusters[pos + 1] = cl; //fIndex[i]; | |
309 | fIndex[pos + 1] = helpInd[i]; | |
310 | // Move All pointer one position back | |
311 | for(UChar_t j = rowIndex + 1; j < fNRows; j++) fPositions[j]++; | |
312 | nClStack++; | |
313 | } | |
314 | ||
315 | // calculate mean x | |
316 | fX += cl->GetX(); | |
317 | ||
318 | // Debug Streaming | |
a2fbb6ec | 319 | if(fkReconstructor->GetRecoParam()->GetStreamLevel(AliTRDrecoParam::kTracker) >= 3){ |
0b433f72 | 320 | AliTRDcluster dcl(*cl); |
a2fbb6ec | 321 | TTreeSRedirector &cstream = *fkReconstructor->GetDebugStream(AliTRDrecoParam::kTracker); |
2a4a428a | 322 | cstream << "BuildIndices" |
323 | << "Plane=" << fPlane | |
324 | << "Stack=" << fStack | |
325 | << "Sector=" << fSector | |
326 | << "Iter=" << iter | |
0b433f72 | 327 | << "C.=" << &dcl |
2a4a428a | 328 | << "rowIndex=" << rowIndex |
329 | << "\n"; | |
330 | } | |
331 | } | |
332 | ||
333 | // AliInfo("Positions"); | |
334 | // for(int ir=0; ir<fNRows; ir++) printf("pos[%d] %d\n", ir, fPositions[ir]); | |
335 | ||
336 | fX /= fN; | |
337 | } | |
338 | ||
339 | //_____________________________________________________________________________ | |
340 | Int_t AliTRDchamberTimeBin::Find(Float_t y) const | |
341 | { | |
342 | // | |
343 | // Returns index of the cluster nearest in Y | |
344 | // | |
345 | ||
346 | if (fN <= 0) return 0; | |
347 | ||
348 | if (y <= fClusters[0]->GetY()) return 0; | |
349 | ||
350 | if (y > fClusters[fN-1]->GetY()) return fN; | |
351 | ||
352 | ||
353 | Int_t b = 0; | |
354 | Int_t e = fN - 1; | |
355 | Int_t m = (b + e) / 2; | |
356 | ||
357 | for ( ; b < e; m = (b + e) / 2) { | |
358 | if (y > fClusters[m]->GetY()) b = m + 1; | |
359 | else e = m; | |
360 | } | |
361 | ||
362 | return m; | |
363 | } | |
364 | ||
365 | //_____________________________________________________________________________ | |
366 | Int_t AliTRDchamberTimeBin::FindYPosition(Double_t y, UChar_t z, Int_t nClusters) const | |
367 | { | |
368 | // | |
369 | // Tree search Algorithm to find the nearest left cluster for a given | |
370 | // y-position in a certain z-bin (in fact AVL-tree). | |
371 | // Making use of the fact that clusters are sorted in y-direction. | |
372 | // | |
373 | // Parameters: | |
374 | // y : y position of the reference point in tracking coordinates | |
375 | // z : z reference bin. | |
376 | // nClusters : | |
377 | // | |
378 | // Output : | |
379 | // Index of the nearest left cluster in the StackLayer indexing (-1 if no clusters are found) | |
380 | // | |
381 | ||
382 | Int_t start = fPositions[z]; // starting Position of the bin | |
383 | Int_t upper = (Int_t)((z != fNRows - 1) ? fPositions[z+1] : nClusters); // ending Position of the bin | |
384 | Int_t end = upper - 1; // ending Position of the bin | |
385 | if(end < start) return -1; // Bin is empty | |
386 | Int_t middle = static_cast<Int_t>((start + end)/2); | |
387 | // 1st Part: climb down the tree: get the next cluster BEFORE ypos | |
388 | while(start + 1 < end){ | |
389 | if(y >= fClusters[middle]->GetY()) start = middle; | |
390 | else end = middle; | |
391 | middle = static_cast<Int_t>((start + end)/2); | |
392 | } | |
393 | if(y > fClusters[end]->GetY()) return end; | |
394 | return start; | |
395 | } | |
396 | ||
397 | //_____________________________________________________________________________ | |
398 | Int_t AliTRDchamberTimeBin::FindNearestYCluster(Double_t y, UChar_t z) const | |
399 | { | |
400 | // | |
401 | // Tree search Algorithm to find the nearest cluster for a given | |
402 | // y-position in a certain z-bin (in fact AVL-tree). | |
403 | // Making use of the fact that clusters are sorted in y-direction. | |
404 | // | |
405 | // Parameters: | |
406 | // y : y position of the reference point in tracking coordinates | |
407 | // z : z reference bin. | |
408 | // | |
409 | // Output | |
410 | // Index of the nearest cluster in the StackLayer indexing (-1 if no clusters are found) | |
411 | // | |
412 | ||
413 | Int_t position = FindYPosition(y, z, fN); | |
414 | if(position == -1) return position; // bin empty | |
415 | // FindYPosition always returns the left Neighbor. We don't know if the left or the right Neighbor is nearest | |
416 | // to the Reference y-position, so test both | |
417 | Int_t upper = (Int_t)((z < fNRows-1) ? fPositions[z+1] : fN); // ending Position of the bin | |
418 | if((position + 1) < (upper)){ | |
419 | if(TMath::Abs(y - fClusters[position + 1]->GetY()) < TMath::Abs(y - fClusters[position]->GetY())) return position + 1; | |
420 | else return position; | |
421 | } | |
422 | return position; | |
423 | } | |
424 | ||
425 | //_____________________________________________________________________________ | |
426 | Int_t AliTRDchamberTimeBin::SearchNearestCluster(Double_t y, Double_t z, Double_t maxroady, Double_t maxroadz) const | |
427 | { | |
428 | // | |
429 | // Finds the nearest cluster from a given point in a defined range. | |
430 | // Distance is determined in a 2D space by the 2-Norm. | |
431 | // | |
432 | // Parameters : | |
433 | // y : y position of the reference point in tracking coordinates | |
434 | // z : z reference bin. | |
435 | // maxroady : maximum searching distance in y direction | |
436 | // maxroadz : maximum searching distance in z direction | |
437 | // | |
438 | // Output | |
439 | // Index of the nearest cluster in the StackLayer indexing (-1 if no cluster is found). | |
440 | // Cluster can be accessed with the operator[] or GetCluster(Int_t index) | |
441 | // | |
442 | // Detail description | |
443 | // | |
444 | // The following steps are perfomed: | |
445 | // 1. Get the expected z bins inside maxroadz. | |
446 | // 2. For each z bin find nearest y cluster. | |
447 | // 3. Select best candidate | |
448 | // | |
449 | Int_t index = -1; | |
450 | // initial minimal distance will be represented as ellipse: semi-major = z-direction | |
451 | // later 2-Norm will be used | |
452 | // Float_t nExcentricity = TMath::Sqrt(maxroadz*maxroadz - maxroad*maxroad)/maxroadz; | |
453 | Float_t mindist = maxroadz; | |
454 | ||
455 | // not very nice but unfortunately neccessarry: we have ho check the neighbors in both directions (+ and -) too. How | |
456 | // much neighbors depends on the Quotient maxroadz/fZLength | |
457 | UChar_t maxRows = 3; | |
458 | UChar_t zpos[kMaxRows]; | |
459 | // Float_t mindist = TMath::Sqrt(maxroad*maxroad + maxroadz*maxroadz); | |
460 | // UChar_t myZbin = FindTreePosition(z, fZ0 + fZLength/2, fZLength/4, 8, 8, kFALSE); | |
461 | UChar_t myZbin = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - z)/fZLength * fNRows); | |
462 | if(z < fZ0) myZbin = fNRows - 1; | |
463 | if(z > fZ0 + fZLength) myZbin = 0; | |
464 | //printf("\n%f < %f < %f [%d]\n", fZ0, z, fZ0 + fZLength, myZbin); | |
465 | //for(int ic=0; ic<fN; ic++) printf("%d z = %f row %d\n", ic, fClusters[ic]->GetZ(), fClusters[ic]->GetPadRow()); | |
466 | ||
467 | UChar_t nNeighbors = 0; | |
468 | for(UChar_t i = 0; i < maxRows; i++){ | |
469 | if((myZbin - 1 + i) < 0) continue; | |
470 | if((myZbin - 1 + i) > fNRows - 1) break; | |
471 | zpos[nNeighbors] = myZbin - 1 + i; | |
472 | nNeighbors++; | |
473 | } | |
474 | Float_t ycl = 0, zcl = 0; | |
475 | for(UChar_t neighbor = 0; neighbor < nNeighbors; neighbor++){ // Always test the neighbors too | |
476 | Int_t pos = FindNearestYCluster(y, zpos[neighbor]); | |
477 | if(pos == -1) continue; // No cluster in bin | |
478 | AliTRDcluster *c = (AliTRDcluster *) (fClusters[pos]); | |
479 | if(c->IsUsed()) continue; // we are only interested in unused clusters | |
480 | ycl = c->GetY(); | |
481 | // Too far away in y-direction (Prearrangement) | |
482 | if (TMath::Abs(ycl - y) > maxroady){ | |
483 | //printf("y[%f] ycl[%f] roady[%f]\n", y, ycl, maxroady); | |
484 | continue; | |
485 | } | |
486 | zcl = c->GetZ(); | |
487 | // Too far away in z-Direction | |
488 | // (Prearrangement since we have not so many bins to test) | |
489 | if (TMath::Abs(zcl - z) > maxroadz) continue; | |
490 | ||
491 | Float_t dist; // distance defined as 2-Norm | |
492 | // if we havent found a Particle that is in the ellipse around (y,z) with maxroad as semi-minor and | |
493 | // maxroadz as semi-major, we take the radius of the ellipse concerning the cluster as mindist, later we | |
494 | // take the 2-Norm when we found a cluster inside the ellipse (The value 10000 is taken because it is surely | |
495 | // large enough to be usable as an indicator whether we have found a nearer cluster or not) | |
496 | // if(mindist > 10000.){ | |
497 | // Float_t phi = ((zcl - z) == 0) ? TMath::Pi()/2 : TMath::ATan((ycl - y)/(zcl - z)); | |
498 | // mindist = maxroad/TMath::Sqrt(1 - nExcentricity*nExcentricity * (TMath::Cos(phi))*(TMath::Cos(phi))); | |
499 | // } | |
500 | dist = TMath::Max(TMath::Abs(y-ycl),TMath::Abs(z-zcl)); // infinity Norm | |
501 | // dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z)); | |
502 | if((Int_t)(dist * 100000) < (Int_t)(mindist * 100000)){ | |
503 | //if((dist = TMath::Sqrt((ycl - y)*(ycl - y) + (zcl - z)*(zcl - z))) < mindist){ | |
504 | mindist = dist; | |
505 | index = pos; | |
506 | } | |
507 | } | |
508 | // This is the Array Position in fIndex2D of the Nearest cluster: if a | |
509 | // cluster is called, then the function has to retrieve the Information | |
510 | // which is Stored in the Array called, the function | |
511 | return index; | |
512 | } | |
513 | ||
514 | //_____________________________________________________________________________ | |
4d6aee34 | 515 | void AliTRDchamberTimeBin::BuildCond(AliTRDcluster * const cl, Double_t *cond, UChar_t Layer, Double_t theta, Double_t phi) |
2a4a428a | 516 | { |
517 | // Helper function to calculate the area where to expect a cluster in THIS | |
518 | // layer. | |
519 | // | |
520 | // Parameters : | |
521 | // cl : | |
522 | // cond : | |
523 | // Layer : | |
524 | // theta : | |
525 | // phi : | |
526 | // | |
527 | // Detail description | |
528 | // | |
529 | // Helper function to calculate the area where to expect a cluster in THIS | |
530 | // layer. by using the information of a former cluster in another layer | |
531 | // and the angle in theta- and phi-direction between layer 0 and layer 3. | |
532 | // If the layer is zero, initial conditions are calculated. Otherwise a | |
533 | // linear interpolation is performed. | |
534 | //Begin_Html | |
535 | //<img src="gif/build_cond.gif"> | |
536 | //End_Html | |
537 | // | |
538 | ||
4d6aee34 | 539 | if(!fkReconstructor){ |
2a4a428a | 540 | AliError("Reconstructor not set."); |
541 | return; | |
542 | } | |
543 | ||
544 | if(Layer == 0){ | |
545 | cond[0] = cl->GetY(); // center: y-Direction | |
546 | cond[1] = cl->GetZ(); // center: z-Direction | |
4d6aee34 | 547 | cond[2] = fkReconstructor->GetRecoParam()->GetMaxPhi() * (cl->GetX() - GetX()) + 1.0; // deviation: y-Direction |
548 | cond[3] = fkReconstructor->GetRecoParam()->GetMaxTheta() * (cl->GetX() - GetX()) + 1.0; // deviation: z-Direction | |
2a4a428a | 549 | } else { |
550 | cond[0] = cl->GetY() + phi * (GetX() - cl->GetX()); | |
551 | cond[1] = cl->GetZ() + theta * (GetX() - cl->GetX()); | |
4d6aee34 | 552 | cond[2] = fkReconstructor->GetRecoParam()->GetRoad0y() + phi; |
553 | cond[3] = fkReconstructor->GetRecoParam()->GetRoad0z(); | |
2a4a428a | 554 | } |
555 | } | |
556 | ||
557 | //_____________________________________________________________________________ | |
4d6aee34 | 558 | void AliTRDchamberTimeBin::GetClusters(const Double_t * const cond, Int_t *index, Int_t& ncl, Int_t BufferSize) |
2a4a428a | 559 | { |
560 | // Finds all clusters situated in this layer inside a rectangle given by the center an ranges. | |
561 | // | |
562 | // Parameters : | |
563 | // cond : | |
564 | // index : | |
565 | // ncl : | |
566 | // BufferSize : | |
567 | // | |
568 | // Output : | |
569 | // | |
570 | // Detail description | |
571 | // | |
572 | // Function returs an array containing the indices in the stacklayer of | |
573 | // the clusters found an the number of found clusters in the stacklayer | |
574 | ||
575 | ncl = 0; | |
576 | memset(index, 0, BufferSize*sizeof(Int_t)); | |
577 | if(fN == 0) return; | |
578 | ||
579 | //Boundary checks | |
580 | Double_t zvals[2]; | |
581 | if(((cond[1] - cond[3]) >= (fZ0 + fZLength)) || (cond[1] + cond[3]) <= fZ0) return; // We are outside of the chamvber | |
582 | zvals[0] = ((cond[1] - cond[3]) < fZ0) ? fZ0 : (cond[1] - cond[3]); | |
583 | zvals[1] = ((cond[1] + cond[3]) < fZ0 + fZLength) ? (cond[1] + cond[3]) : fZ0 + fZLength - 1.E-3; | |
584 | ||
585 | UChar_t zhi = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - zvals[0])/fZLength * fNRows); | |
586 | UChar_t zlo = fNRows - 1 - (UChar_t)(TMath::Abs(fZ0 - zvals[1])/fZLength * fNRows); | |
587 | ||
588 | /* AliInfo(Form("yc[%f] zc[%f] dy[%f] dz[%f]", cond[0], cond[1], cond[2], cond[3])); | |
589 | PrintClusters(); | |
590 | AliInfo(Form("zlo[%f] zhi[%f]", zvals[0], zvals[1])); | |
591 | AliInfo(Form("zlo[%d] zhi[%d]", zlo, zhi));*/ | |
fd40f855 | 592 | |
593 | Double_t ylo = cond[0] - cond[2], | |
594 | yhi = cond[0] + cond[2]; | |
595 | //printf("CTB : ylo[%f] yhi[%f]\n", ylo, yhi); | |
2a4a428a | 596 | //Preordering in Direction z saves a lot of loops (boundary checked) |
597 | for(UChar_t z = zlo; z <= zhi; z++){ | |
598 | UInt_t upper = (z < fNRows-1) ? fPositions[z+1] : fN; | |
599 | //AliInfo(Form("z[%d] y [%d %d]", z, fPositions[z], upper)); | |
600 | for(Int_t y = fPositions[z]; y < (Int_t)upper; y++){ | |
601 | if(ncl == BufferSize){ | |
6e3b00f9 | 602 | AliInfo("Buffer size riched. Some clusters may be lost."); |
2a4a428a | 603 | return; //Buffer filled |
604 | } | |
605 | ||
fd40f855 | 606 | if(fClusters[y]->GetY() > yhi) break; // Abbortion conditions!!! |
607 | if(fClusters[y]->GetY() < ylo) continue; // Too small | |
2a4a428a | 608 | 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;} |
609 | index[ncl] = y; | |
610 | ncl++; | |
611 | } | |
612 | } | |
613 | if(ncl>fN) AliError(Form("Clusters found %d > %d (clusters in layer)", ncl, fN)); | |
614 | } | |
615 | ||
616 | //_____________________________________________________________________________ | |
617 | AliTRDcluster *AliTRDchamberTimeBin::GetNearestCluster(Double_t *cond) | |
618 | { | |
619 | // Function returning a pointer to the nearest cluster (nullpointer if not successfull). | |
620 | // | |
621 | // Parameters : | |
622 | // cond : | |
623 | // | |
624 | // Output : | |
625 | // pointer to the nearest cluster (nullpointer if not successfull). | |
626 | // | |
627 | // Detail description | |
628 | // | |
629 | // returns a pointer to the nearest cluster (nullpointer if not | |
630 | // successfull) by the help of the method FindNearestCluster | |
631 | ||
632 | ||
4d6aee34 | 633 | Double_t maxroad = fkReconstructor->GetRecoParam()->GetRoad2y(); |
634 | Double_t maxroadz = fkReconstructor->GetRecoParam()->GetRoad2z(); | |
2a4a428a | 635 | |
636 | Int_t index = SearchNearestCluster(cond[0],cond[1],maxroad,maxroadz); | |
4d6aee34 | 637 | AliTRDcluster *returnCluster = NULL; |
2a4a428a | 638 | if(index != -1) returnCluster = (AliTRDcluster *) fClusters[index]; |
639 | return returnCluster; | |
640 | } | |
641 | ||
642 | //_____________________________________________________________________________ | |
6c207d50 | 643 | void AliTRDchamberTimeBin::Print(Option_t *) const |
2a4a428a | 644 | { |
645 | // Prints the position of each cluster in the stacklayer on the stdout | |
646 | // | |
6c207d50 | 647 | if(!fN) return; |
ac1dec3b | 648 | AliInfo(Form("Layer[%d] Stack[%d] Sector[%2d] nRows[%2d]", fPlane, fStack, fSector, fNRows)); |
6c207d50 | 649 | AliInfo(Form("Z0[%7.3f] Z1[%7.3f]", fZ0, fZ0+fZLength)); |
650 | AliTRDcluster* const* icl = &fClusters[0]; | |
651 | for(Int_t jcl = 0; jcl < fN; jcl++, icl++){ | |
652 | 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(), | |
653 | (*icl)->IsUsed() ? "y" : "n")); | |
2a4a428a | 654 | } |
ac1dec3b | 655 | Int_t irow = 0; |
656 | for(UChar_t const* pos = &fPositions[0]; irow<fNRows; pos++, irow++){ | |
657 | if((*pos) != 0xff) AliInfo(Form("r[%2d] pos[%d]", irow, (*pos))); | |
658 | } | |
2a4a428a | 659 | } |