]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/HWCFemulator/AliHLTTPCHWClusterMerger.cxx
bug fix for outer sectors, extra interface
[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,
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,
9efbb86c 263 AliHLTTPCRawCluster(partitionrow, pad, time, sigmaY2, sigmaZ2, charge, qmax), mc ));
9c0b3f5b 264
f550d850 265 if( iBorder>=0 ){
266 fBorderNClusters[iBorder]++;
267 fBorderNClustersTotal++;
268 }
03839a45 269 return fClusters.size()-1;
9c0b3f5b 270}
271
f550d850 272int AliHLTTPCHWClusterMerger::FillIndex()
273{
274 /// loop over cached raw clusters and fill index
275
276 delete[] fBorderClusters;
277 fBorderClusters = 0;
278 fBorderClusters = new AliBorderRecord[fBorderNClustersTotal];
279
280 fBorderFirstCluster[0] = 0;
281 for(int i=1; i<fkNSlices*fNBorders; i++ ){
282 fBorderFirstCluster[i] = fBorderFirstCluster[i-1] + fBorderNClusters[i-1];
283 fBorderNClusters[i-1] = 0;
284 }
285 fBorderNClusters[fkNSlices*fNBorders-1]=0;
286 for (AliHLTUInt32_t pos=0; pos<fClusters.size(); pos++) {
287 int iBorder = fClusters[pos].GetBorder();
288 if( iBorder<0 ) continue;
289 AliBorderRecord &b = fBorderClusters[fBorderFirstCluster[iBorder]+fBorderNClusters[iBorder]];
290 b.fClusterRecordID = pos;
291 b.fTimeBin = (int)fClusters[pos].GetCluster().GetTime();
292 fBorderNClusters[iBorder]++;
293 }
294 /*
295 cout<<"Border clusters: "<<endl;
296 for( int iSlice=0; iSlice<fkNSlices; iSlice++){
297 for( int ib = 0; ib<fNBorders; ib++ ){
298 int ind = iSlice*fNBorders+ib;
299 cout<<iSlice<<" "<<ib<<" :"<<fBorderFirstCluster[ind]<<", "<<fBorderNClusters[ind]<<endl;
300 }
301 }
302 */
03839a45 303 /*
304 for( int ib=1; ib<fkNSlices*fNBorders; ib++ ){
305 if( fBorderFirstCluster[ib] != fBorderFirstCluster[ib-1]+fBorderNClusters[ib-1] ){
306 cout<<"Something wrong with cluster borders !!! "<<endl;
307 }
308 }
309 */
f550d850 310 return 0;
311}
312
313void AliHLTTPCHWClusterMerger::Clear()
314{
315 /// cleanup
316 fClusters.clear();
317 fRemovedClusterIds.clear();
318
319 delete[] fBorderClusters;
320 fBorderClusters = 0;
321 for( int i=0; i<fkNSlices*fNBorders; i++){
322 fBorderNClusters[i] = 0;
323 fBorderFirstCluster[i] = 0;
324 }
325 fBorderNClustersTotal = 0;
326}
327
328
9c0b3f5b 329int AliHLTTPCHWClusterMerger::Merge()
330{
331 /// merge clusters
332 /// first all candidates are filled into the index grid, looping over all clusters
333 /// in the grid automatically results in time ordered clusters per row (ordering with
334 /// respect to cells, within a cell two clusters can be reversed)
f550d850 335
336 if( !fMapping ) Init();
337 if( !fMapping ) return 0;
338 //static int sLeft = 0, sRight = 0, sMerged = 0;
9c0b3f5b 339 int iResult=0;
340 int count=0;
341 if ((iResult=FillIndex())<0) {
342 return iResult;
343 }
f550d850 344 // sort
345 for( int i=0; i<fkNSlices*fNBorders; i++){
346 std::sort(fBorderClusters+fBorderFirstCluster[i],fBorderClusters+fBorderFirstCluster[i]+fBorderNClusters[i], CompareTime);
347 }
9c0b3f5b 348
f550d850 349 for( int iBorder=0; iBorder<fkNSlices*fNBorders; iBorder+=2){
350 AliBorderRecord *border1 = fBorderClusters+fBorderFirstCluster[iBorder];
351 AliBorderRecord *border2 = fBorderClusters+fBorderFirstCluster[iBorder+1];
352 int n1 = fBorderNClusters[iBorder];
353 int n2 = fBorderNClusters[iBorder+1];
354 /*
355sLeft+=n1;
356 sRight+=n2;
357 bool prn = (n1>0) && (n2>0);
358 if( prn ){
359 cout<<"Border "<<iBorder/2<<", left: "<<n1<<" clusters :"<<endl;
360 for( int ib=0; ib<n1; ib++ ){
361 cout<<ib<<": "<<border1[ib].fTimeBin<<endl;
9c0b3f5b 362 }
f550d850 363 cout<<"Border "<<iBorder/2<<", right: "<<n2<<" clusters :"<<endl;
364 for( int ib=0; ib<n2; ib++ ){
365 cout<<ib<<": "<<border2[ib].fTimeBin<<endl;
9c0b3f5b 366 }
9c0b3f5b 367 }
f550d850 368 */
369 int ib1 = 0;
370 for( int ib2 = 0; (ib1<n1) && (ib2<n2); ib2++ ){
371 // search first cluster at border1 to merge
372
373 while( ib1<n1 && border1[ib1].fTimeBin>border2[ib2].fTimeBin+fkMergeTimeWindow ){
374 ib1++;
375 }
376
377 if( ib1>= n1 ) break;
378 if( border1[ib1].fTimeBin < border2[ib2].fTimeBin-fkMergeTimeWindow) continue;
379
380 // merge c2->c1
381 //if( prn ) cout<<"merge "<<ib2<<"->"<<ib1<<endl;
382 AliClusterRecord &c1 = fClusters[border1[ib1].fClusterRecordID];
383 AliClusterRecord &c2 = fClusters[border2[ib2].fClusterRecordID];
384
385 float w1 = c1.Cluster().fCharge;
386 float w2 = c2.Cluster().fCharge;
387 if( w1<=0 ) w1 = 1;
388 if( w2<=0 ) w2 = 1;
389 float w = 1./(w1+w2);
390 w1*=w;
391 w2*=w;
392
393 c1.Cluster().fCharge += c2.Cluster().fCharge;
394 c1.Cluster().fQMax += c2.Cluster().fQMax;
395
396 c1.Cluster().fSigmaY2 =
397 w1*c1.Cluster().fSigmaY2 + w2*c2.Cluster().fSigmaY2
398 + (c1.Cluster().fPad - c2.Cluster().fPad)*(c1.Cluster().fPad - c2.Cluster().fPad)*w1*w2;
399
400 c1.Cluster().fSigmaZ2 =
401 w1*c1.Cluster().fSigmaZ2 + w2*c2.Cluster().fSigmaZ2
402 + (c1.Cluster().fTime - c2.Cluster().fTime)*(c1.Cluster().fTime - c2.Cluster().fTime)*w1*w2;
403
404 c1.Cluster().fPad = w1*c1.Cluster().fPad + w2*c2.Cluster().fPad;
405 c1.Cluster().fTime = w1*c1.Cluster().fTime + w2*c2.Cluster().fTime;
406
9efbb86c 407 // merge MC labels
f550d850 408
9efbb86c 409 AliHLTTPCClusterMCWeight labels[6] = {
410 c1.GetMCLabel().fClusterID[0],
411 c1.GetMCLabel().fClusterID[1],
412 c1.GetMCLabel().fClusterID[2],
413 c2.GetMCLabel().fClusterID[0],
414 c2.GetMCLabel().fClusterID[1],
415 c2.GetMCLabel().fClusterID[2]
416 };
417
418 sort(labels, labels+6, CompareMCLabels);
419 for( unsigned int i=1; i<6; i++ ){
420 if(labels[i-1].fMCID==labels[i].fMCID ){
421 labels[i].fWeight+=labels[i-1].fWeight;
422 labels[i-1].fWeight = 0;
423 }
424 }
425
426 sort(labels, labels+6, CompareMCWeights );
427
428 for( unsigned int i=0; i<3 && i<6; i++ ){
429 c1.MCLabel().fClusterID[i] = labels[i];
430 }
431
f550d850 432 // wipe c2
433 fRemovedClusterIds.push_back(c2.GetId());
434 HLTDebug("merging %d into %d", border2[ib2].fClusterRecordID, border1[ib1].fClusterRecordID);
435 //cout<<"Set merged flag at position "<<border2[ib2].fClusterRecordID<<endl;
03839a45 436 c2.SetMergedTo(border1[ib1].fClusterRecordID);
437 count++;
f550d850 438 // do not merge c1 anymore
439 ib1++;
440 }
441 } // iBorder
442
443 //cout<<"Merged "<<count<<" clusters "<<" out of "<<fClusters.size()<<endl;
444 //sMerged+= count;
445 // cout<<"L "<<sLeft<<" r "<<sRight<<" m "<<sMerged<<endl;
9c0b3f5b 446 if (iResult<0) return iResult;
447 return count;
448}
449