]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/HWCFemulator/AliHLTTPCHWClusterMerger.cxx
CMake: Retrieve Git information
[u/mrichter/AliRoot.git] / HLT / TPCLib / HWCFemulator / AliHLTTPCHWClusterMerger.cxx
CommitLineData
9c0b3f5b 1// $Id$
2
3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* Sergey Gorbunov *
9//* for The ALICE HLT Project. *
10//* *
11//* Permission to use, copy, modify and distribute this software and its *
12//* documentation strictly for non-commercial purposes is hereby granted *
13//* without fee, provided that the above copyright notice appears in all *
14//* copies and that both the copyright notice and this permission notice *
15//* appear in the supporting documentation. The authors make no claims *
16//* about the suitability of this software for any purpose. It is *
17//* provided "as is" without express or implied warranty. *
18//**************************************************************************
19
20// @file AliHLTTPCHWClusterMerger.cxx
21// @author Matthias Richter, Sergey Gorbunov
22// @date 2011-11-25
23// @brief Merger class for HLT TPC Hardware clusters
24// Handles merging of branch border clusters
25
b2232a19 26#include <algorithm>
27
9c0b3f5b 28#include "AliHLTTPCHWClusterMerger.h"
29#include "AliHLTTPCTransform.h"
30#include "AliHLTTPCSpacePointData.h"
f550d850 31#include "AliHLTTPCHWCFSupport.h"
9c0b3f5b 32
33/** ROOT macro for the implementation of ROOT specific class methods */
34ClassImp(AliHLTTPCHWClusterMerger)
35
9c0b3f5b 36AliHLTTPCHWClusterMerger::AliHLTTPCHWClusterMerger()
37 : AliHLTLogging()
f550d850 38 , fMapping(0)
39 , fNRows(0)
40 , fNRowPads(0)
41 , fNBorders(0)
42 , fBorders(0)
43 , fBorderNClusters(0)
44 , fBorderFirstCluster(0)
45 , fBorderClusters(0)
46 , fBorderNClustersTotal(0)
9c0b3f5b 47 , fClusters()
48 , fRemovedClusterIds()
9c0b3f5b 49 , fIter()
50 , fEnd()
51{
52 // see header file for class documentation
53 // or
54 // refer to README to build package
55 // or
56 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
57 // constructor
58}
59
60AliHLTTPCHWClusterMerger::~AliHLTTPCHWClusterMerger()
61{
62 // destructor
f550d850 63 delete[] fMapping;
64 delete [] fBorders;
65 delete[] fBorderNClusters;
66 delete[] fBorderFirstCluster;
67 delete[] fBorderClusters;
9c0b3f5b 68}
69
f550d850 70void AliHLTTPCHWClusterMerger::Init()
71{
72 // initialisation
73
74 delete[] fMapping;
75 delete[] fBorders;
76 delete[] fBorderNClusters;
77 delete[] fBorderFirstCluster;
78 delete[] fBorderClusters;
79 fMapping = 0;
80 fBorders = 0;
81 fBorderNClusters = 0;
82 fBorderFirstCluster = 0;
83 fBorderClusters = 0;
84 fBorderNClustersTotal = 0;
85 fNRows = AliHLTTPCTransform::GetNRows();
86 fNRowPads = 0;
87 fNBorders = 0;
88 for( int i=0; i<fNRows; i++ ){
89 int nPads = AliHLTTPCTransform::GetNPads(i);
90 if( fNRowPads<nPads ) fNRowPads = nPads;
91 }
92 int nPadsTotal = fNRows*fNRowPads;
93 fMapping = new AliHLTInt16_t [nPadsTotal];
94
95 if( !fMapping ){
96 HLTError("Can not allocate memory: %d bytes", nPadsTotal*sizeof(AliHLTInt16_t));
97 return;
98 }
99 for( int i=0; i<nPadsTotal; i++ ){
100 fMapping[i] = -1;
101 }
102
103 AliHLTTPCHWCFSupport support;
104
105 for( int iPart=0; iPart<6; iPart++ ){
106 const AliHLTUInt32_t *m = support.GetMapping(0,iPart);
107 int nHWAddress=m[0];
108 for( int iHW=0; iHW<nHWAddress; iHW++ ){
109 AliHLTUInt32_t configWord = m[iHW+1];
110 int row = (configWord>>8) & 0x3F;
111 int pad = configWord & 0xFF;
112 bool border = (configWord>>14) & 0x1;
113 if( !border ) continue;
114 row+=AliHLTTPCTransform::GetFirstRow(iPart);
115 if( row>fNRows ) continue;
116 if( pad>=AliHLTTPCTransform::GetNPads(iPart) ) continue;
117 fMapping[row*fNRowPads + pad] = -2;
118 }
119 }
120
121 std::vector<AliHLTFloat32_t> vBorders;
122 for( int row=0; row<fNRows; row++ ){
123 for( int pad=0; pad<fNRowPads-1; pad++ ){
124 AliHLTInt16_t *m = fMapping + row*fNRowPads;
125 if( m[pad]==-2 && m[pad+1]==-2 ){
126 m[pad] = fNBorders;
127 for( int i=1; i<fkMergeWidth; i++ ){
128 if( pad-i<0 || m[pad-i]!=-1 ) break;
129 m[pad-i] = fNBorders;
130 }
131 m[pad+1] = fNBorders+1;
132 for( int i=1; i<fkMergeWidth; i++ ){
133 if( pad+1+i>=fNRowPads || m[pad+1+i]!=-1 ) break;
134 m[pad+1+i] = fNBorders+1;
135 }
136 fNBorders+=2;
137 vBorders.push_back(pad+1.);
138 vBorders.push_back(pad+1.);
139 }
140 }
03839a45 141 }
142
143 //cout<<" NBorders = "<<fNBorders/2<<endl;
144
145 /*
f550d850 146 cout<<"Borders:"<<endl;
147 for( int row=0; row<fNRows; row++ ){
148 for( int pad=0; pad<fNRowPads; pad++ ){
149 AliHLTInt16_t *m = fMapping + row*fNRowPads;
150 if( m[pad]>=0 ) {
151 cout<<row<<" "<<pad<<" "<<m[pad]%2<<endl;
152 }
153 }
154 }
155 */
03839a45 156
f550d850 157 fBorders = new AliHLTFloat32_t [fNBorders];
158 if( !fBorders ){
159 HLTError("Can not allocate memory: %d bytes", fNBorders*sizeof(AliHLTFloat32_t));
160 fNBorders = 0;
161 return;
162 }
163 for( int i=0; i<fNBorders; i++ ){
164 fBorders[i] = vBorders[i];
165 }
166 fBorderNClusters = new int[fkNSlices*fNBorders];
167 if( !fBorderNClusters ){
168 HLTError("Can not allocate memory: %d bytes", fkNSlices*fNBorders*sizeof(int));
169 return;
170 }
171
172 fBorderFirstCluster = new int[fkNSlices*fNBorders];
173 if( !fBorderFirstCluster ){
174 HLTError("Can not allocate memory: %d bytes", fkNSlices*fNBorders*sizeof(int));
175 return;
176 }
177
178 for( int i=0; i<fkNSlices*fNBorders; i++){
179 fBorderNClusters[i] = 0;
180 fBorderFirstCluster[i] = 0;
181 }
182}
183
184bool AliHLTTPCHWClusterMerger::CheckCandidate(int /*slice*/, int partition, int partitionrow, float pad, float /*time*/, float sigmaPad2
185)
9c0b3f5b 186{
187 /// check cluster if it is a candidate for merging
188 int slicerow=partitionrow+AliHLTTPCTransform::GetFirstRow(partition);
03839a45 189
f550d850 190 if( !fMapping ) Init();
191 if( !fMapping ) return 0;
192 if( slicerow <0 || slicerow>= fNRows ) return 0;
193 int iPad = (int) pad;
194 if( iPad<0 || iPad>=fNRowPads ) return 0;
03839a45 195 int atBorder = fMapping[slicerow*fNRowPads+iPad];
f550d850 196 if( atBorder<0 ) return 0;
197 float dPad = pad - fBorders[atBorder];
198 if( sigmaPad2>1.e-4 ){
199 if( dPad*dPad > 12.*sigmaPad2 ) return 0;
200 } else {
201 if( fabs(dPad)>1. ) return 0;
9c0b3f5b 202 }
f550d850 203 return 1;
9c0b3f5b 204}
205
206int AliHLTTPCHWClusterMerger::AddCandidate(int slice,
207 int partition,
208 short partitionrow,
209 float pad,
210 float time,
211 float sigmaY2,
212 float sigmaZ2,
213 unsigned short charge,
214 unsigned short qmax,
9efbb86c 215 AliHLTUInt32_t id,
2abac65f 216 const AliHLTTPCClusterMCLabel *mc
9c0b3f5b 217 )
218{
219 /// add a candidate for merging and register in the index grid
f550d850 220
221 int iBorder = -1;
222 int iPad = (int) pad;
223 if( !fMapping ) Init();
03839a45 224
225 int slicerow=partitionrow+AliHLTTPCTransform::GetFirstRow(partition);
226
9c0b3f5b 227 if (id!=~AliHLTUInt32_t(0)) {
228 if (slice<0) {
229 slice=AliHLTTPCSpacePointData::GetSlice(id);
230 } else if ((unsigned)slice!=AliHLTTPCSpacePointData::GetSlice(id)) {
231 HLTError("cluster id 0x%08x is not consistent with specified slice %d", id, slice);
232 }
233 if (partition<0) {
234 partition=AliHLTTPCSpacePointData::GetPatch(id);
235 } else if ((unsigned)partition!=AliHLTTPCSpacePointData::GetPatch(id)) {
236 HLTError("cluster id 0x%08x is not consistent with specified partition %d", id, partition);
237 }
238 }
03839a45 239
f550d850 240 if( slice<0 || slice>=fkNSlices ){
241 HLTError("cluster id 0x%08x has wrong slice number %d", id, slice);
242 }
03839a45 243
f550d850 244 if( partition<0 || partition>=6 ){
245 HLTError("cluster id 0x%08x has wrong partition number %d", id, partition);
246 }
247
03839a45 248 if( slice>=0 && slice<fkNSlices && slicerow>=0 && slicerow <fNRows && fMapping && iPad>=0 && iPad < fNRowPads ){
249 iBorder = fMapping[slicerow*fNRowPads+iPad];
250
f550d850 251 if( iBorder>=0 ){
252 float dPad = pad - fBorders[iBorder];
253 if( sigmaY2>1.e-4 ){
254 if( dPad*dPad > 12.*sigmaY2 ) iBorder = -1;
255 } else {
256 if( fabs(dPad)>1. ) iBorder = -1;
257 }
258 }
03839a45 259 if( iBorder>=0 ) iBorder = slice*fNBorders + iBorder;
f550d850 260 }
261
03839a45 262 fClusters.push_back(AliClusterRecord(slice, partition, iBorder, -1, id,
2abac65f 263 AliHLTTPCRawCluster(partitionrow, pad, time, sigmaY2, sigmaZ2, charge, qmax),
264 mc!=NULL?*mc:AliHLTTPCClusterMCLabel() ));
9c0b3f5b 265
f550d850 266 if( iBorder>=0 ){
267 fBorderNClusters[iBorder]++;
268 fBorderNClustersTotal++;
269 }
03839a45 270 return fClusters.size()-1;
9c0b3f5b 271}
272
f550d850 273int AliHLTTPCHWClusterMerger::FillIndex()
274{
275 /// loop over cached raw clusters and fill index
276
277 delete[] fBorderClusters;
278 fBorderClusters = 0;
279 fBorderClusters = new AliBorderRecord[fBorderNClustersTotal];
280
281 fBorderFirstCluster[0] = 0;
282 for(int i=1; i<fkNSlices*fNBorders; i++ ){
283 fBorderFirstCluster[i] = fBorderFirstCluster[i-1] + fBorderNClusters[i-1];
284 fBorderNClusters[i-1] = 0;
285 }
286 fBorderNClusters[fkNSlices*fNBorders-1]=0;
287 for (AliHLTUInt32_t pos=0; pos<fClusters.size(); pos++) {
288 int iBorder = fClusters[pos].GetBorder();
289 if( iBorder<0 ) continue;
290 AliBorderRecord &b = fBorderClusters[fBorderFirstCluster[iBorder]+fBorderNClusters[iBorder]];
291 b.fClusterRecordID = pos;
292 b.fTimeBin = (int)fClusters[pos].GetCluster().GetTime();
293 fBorderNClusters[iBorder]++;
294 }
295 /*
296 cout<<"Border clusters: "<<endl;
297 for( int iSlice=0; iSlice<fkNSlices; iSlice++){
298 for( int ib = 0; ib<fNBorders; ib++ ){
299 int ind = iSlice*fNBorders+ib;
300 cout<<iSlice<<" "<<ib<<" :"<<fBorderFirstCluster[ind]<<", "<<fBorderNClusters[ind]<<endl;
301 }
302 }
303 */
03839a45 304 /*
305 for( int ib=1; ib<fkNSlices*fNBorders; ib++ ){
306 if( fBorderFirstCluster[ib] != fBorderFirstCluster[ib-1]+fBorderNClusters[ib-1] ){
307 cout<<"Something wrong with cluster borders !!! "<<endl;
308 }
309 }
310 */
f550d850 311 return 0;
312}
313
314void AliHLTTPCHWClusterMerger::Clear()
315{
316 /// cleanup
317 fClusters.clear();
318 fRemovedClusterIds.clear();
319
320 delete[] fBorderClusters;
321 fBorderClusters = 0;
322 for( int i=0; i<fkNSlices*fNBorders; i++){
323 fBorderNClusters[i] = 0;
324 fBorderFirstCluster[i] = 0;
325 }
326 fBorderNClustersTotal = 0;
327}
328
329
9c0b3f5b 330int AliHLTTPCHWClusterMerger::Merge()
331{
332 /// merge clusters
333 /// first all candidates are filled into the index grid, looping over all clusters
334 /// in the grid automatically results in time ordered clusters per row (ordering with
335 /// respect to cells, within a cell two clusters can be reversed)
f550d850 336
337 if( !fMapping ) Init();
338 if( !fMapping ) return 0;
339 //static int sLeft = 0, sRight = 0, sMerged = 0;
9c0b3f5b 340 int iResult=0;
341 int count=0;
342 if ((iResult=FillIndex())<0) {
343 return iResult;
344 }
f550d850 345 // sort
346 for( int i=0; i<fkNSlices*fNBorders; i++){
347 std::sort(fBorderClusters+fBorderFirstCluster[i],fBorderClusters+fBorderFirstCluster[i]+fBorderNClusters[i], CompareTime);
348 }
9c0b3f5b 349
f550d850 350 for( int iBorder=0; iBorder<fkNSlices*fNBorders; iBorder+=2){
351 AliBorderRecord *border1 = fBorderClusters+fBorderFirstCluster[iBorder];
352 AliBorderRecord *border2 = fBorderClusters+fBorderFirstCluster[iBorder+1];
353 int n1 = fBorderNClusters[iBorder];
354 int n2 = fBorderNClusters[iBorder+1];
355 /*
356sLeft+=n1;
357 sRight+=n2;
358 bool prn = (n1>0) && (n2>0);
359 if( prn ){
360 cout<<"Border "<<iBorder/2<<", left: "<<n1<<" clusters :"<<endl;
361 for( int ib=0; ib<n1; ib++ ){
362 cout<<ib<<": "<<border1[ib].fTimeBin<<endl;
9c0b3f5b 363 }
f550d850 364 cout<<"Border "<<iBorder/2<<", right: "<<n2<<" clusters :"<<endl;
365 for( int ib=0; ib<n2; ib++ ){
366 cout<<ib<<": "<<border2[ib].fTimeBin<<endl;
9c0b3f5b 367 }
9c0b3f5b 368 }
f550d850 369 */
370 int ib1 = 0;
371 for( int ib2 = 0; (ib1<n1) && (ib2<n2); ib2++ ){
372 // search first cluster at border1 to merge
373
374 while( ib1<n1 && border1[ib1].fTimeBin>border2[ib2].fTimeBin+fkMergeTimeWindow ){
375 ib1++;
376 }
377
378 if( ib1>= n1 ) break;
379 if( border1[ib1].fTimeBin < border2[ib2].fTimeBin-fkMergeTimeWindow) continue;
380
381 // merge c2->c1
382 //if( prn ) cout<<"merge "<<ib2<<"->"<<ib1<<endl;
383 AliClusterRecord &c1 = fClusters[border1[ib1].fClusterRecordID];
384 AliClusterRecord &c2 = fClusters[border2[ib2].fClusterRecordID];
385
386 float w1 = c1.Cluster().fCharge;
387 float w2 = c2.Cluster().fCharge;
388 if( w1<=0 ) w1 = 1;
389 if( w2<=0 ) w2 = 1;
390 float w = 1./(w1+w2);
391 w1*=w;
392 w2*=w;
393
394 c1.Cluster().fCharge += c2.Cluster().fCharge;
082afe16 395 if( c1.Cluster().fQMax < c2.Cluster().fQMax ) c1.Cluster().fQMax = c2.Cluster().fQMax;
f550d850 396
397 c1.Cluster().fSigmaY2 =
398 w1*c1.Cluster().fSigmaY2 + w2*c2.Cluster().fSigmaY2
399 + (c1.Cluster().fPad - c2.Cluster().fPad)*(c1.Cluster().fPad - c2.Cluster().fPad)*w1*w2;
400
401 c1.Cluster().fSigmaZ2 =
402 w1*c1.Cluster().fSigmaZ2 + w2*c2.Cluster().fSigmaZ2
403 + (c1.Cluster().fTime - c2.Cluster().fTime)*(c1.Cluster().fTime - c2.Cluster().fTime)*w1*w2;
404
405 c1.Cluster().fPad = w1*c1.Cluster().fPad + w2*c2.Cluster().fPad;
406 c1.Cluster().fTime = w1*c1.Cluster().fTime + w2*c2.Cluster().fTime;
407
9efbb86c 408 // merge MC labels
f550d850 409
9efbb86c 410 AliHLTTPCClusterMCWeight labels[6] = {
411 c1.GetMCLabel().fClusterID[0],
412 c1.GetMCLabel().fClusterID[1],
413 c1.GetMCLabel().fClusterID[2],
414 c2.GetMCLabel().fClusterID[0],
415 c2.GetMCLabel().fClusterID[1],
416 c2.GetMCLabel().fClusterID[2]
417 };
418
419 sort(labels, labels+6, CompareMCLabels);
420 for( unsigned int i=1; i<6; i++ ){
421 if(labels[i-1].fMCID==labels[i].fMCID ){
422 labels[i].fWeight+=labels[i-1].fWeight;
423 labels[i-1].fWeight = 0;
424 }
425 }
426
427 sort(labels, labels+6, CompareMCWeights );
428
082afe16 429 for( unsigned int i=0; i<3; i++ ){
9efbb86c 430 c1.MCLabel().fClusterID[i] = labels[i];
431 }
432
f550d850 433 // wipe c2
434 fRemovedClusterIds.push_back(c2.GetId());
435 HLTDebug("merging %d into %d", border2[ib2].fClusterRecordID, border1[ib1].fClusterRecordID);
436 //cout<<"Set merged flag at position "<<border2[ib2].fClusterRecordID<<endl;
03839a45 437 c2.SetMergedTo(border1[ib1].fClusterRecordID);
438 count++;
f550d850 439 // do not merge c1 anymore
440 ib1++;
441 }
442 } // iBorder
443
444 //cout<<"Merged "<<count<<" clusters "<<" out of "<<fClusters.size()<<endl;
445 //sMerged+= count;
446 // cout<<"L "<<sLeft<<" r "<<sRight<<" m "<<sMerged<<endl;
9c0b3f5b 447 if (iResult<0) return iResult;
448 return count;
449}
450