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