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