]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/TPCLib/HWCFemulator/AliHLTTPCHWClusterMergerV1.cxx
bug fix
[u/mrichter/AliRoot.git] / HLT / TPCLib / HWCFemulator / AliHLTTPCHWClusterMergerV1.cxx
CommitLineData
0e3c57d2 1// $Id: AliHLTTPCHWClusterMergerV1.cxx 53494 2011-12-09 06:24:43Z sgorbuno $
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 AliHLTTPCHWClusterMergerV1.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
26
27#include "AliHLTTPCHWClusterMergerV1.h"
28#include "AliHLTTPCHWCFSupport.h"
29#include "AliHLTTPCDefinitions.h"
30#include "AliHLTTPCTransform.h"
31#include "AliHLTTPCRawCluster.h"
32#include <algorithm>
33
34/** ROOT macro for the implementation of ROOT specific class methods */
35
36AliHLTTPCHWClusterMergerV1::AliHLTTPCHWClusterMergerV1()
37 : AliHLTLogging()
38 , fNRows(0)
39 , fNRowPads(0)
40 , fNBorders(0)
41 , fMapping(0)
42 , fBorders()
e43f6920 43 , fpData(NULL)
0e3c57d2 44 , fRawClusterBlocks(NULL)
45 , fMCBlocks(NULL)
46{
47 // see header file for class documentation
48 // or
49 // refer to README to build package
50 // or
51 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
52 // constructor
53
54 const int kNPatchesTotal = fkNSlices*fkNPatches;
55
56 fRawClusterBlocks = new AliHLTComponentBlockData* [kNPatchesTotal];
57 fMCBlocks = new AliHLTComponentBlockData* [kNPatchesTotal];
58 for( int i=0; i<kNPatchesTotal; i++){
59 fRawClusterBlocks[i] = NULL;
60 fMCBlocks[i] = NULL;
61 }
62}
63
64AliHLTTPCHWClusterMergerV1::~AliHLTTPCHWClusterMergerV1()
65{
66 // destructor
67 delete[] fMapping;
68 delete[] fRawClusterBlocks;
69 delete[] fMCBlocks;
70}
71
72Int_t AliHLTTPCHWClusterMergerV1::Init()
73{
74 // initialisation
75
76 Int_t iResult=0;
77
78 delete[] fMapping;
79 fMapping = 0;
80 fNRows = AliHLTTPCTransform::GetNRows();
81 fNRowPads = 0;
82 fNBorders = 0;
83 for( int i=0; i<fNRows; i++ ){
84 int nPads = AliHLTTPCTransform::GetNPads(i);
85 if( fNRowPads<nPads ) fNRowPads = nPads;
86 }
87 int nPadsTotal = fNRows*fNRowPads;
88 fMapping = new AliHLTInt16_t [nPadsTotal];
89
90 if( !fMapping ){
91 HLTError("Can not allocate memory: %d bytes", nPadsTotal*sizeof(AliHLTInt16_t));
92 return -ENOMEM;
93 }
94 for( int i=0; i<nPadsTotal; i++ ){
95 fMapping[i] = -1;
96 }
97
98 AliHLTTPCHWCFSupport support;
99
100 for( int iPart=0; iPart<6; iPart++ ){
101 const AliHLTUInt32_t *m = support.GetMapping(0,iPart);
102 if( !m ){
103 HLTError("Can not get mapping for partition %d", iPart);
104 iResult = -1;
105 continue;
106 }
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-iPart;
118 }
119 }
120
121 fBorders.clear();
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]<-1 && m[pad+1]<-1 ){
126 fBorders.push_back( AliBorderParam( pad+1., -m[pad]-2) ); // pad, patch
127 fBorders.push_back( AliBorderParam( pad+1., -m[pad+1]-2) ); // pad, patch
128
129 m[pad] = fNBorders;
130 for( int i=1; i<fkMergeWidth; i++ ){
131 if( pad-i<0 || m[pad-i]!=-1 ) break;
132 m[pad-i] = fNBorders;
133 }
134 m[pad+1] = fNBorders+1;
135 for( int i=1; i<fkMergeWidth; i++ ){
136 if( pad+1+i>=fNRowPads || m[pad+1+i]!=-1 ) break;
137 m[pad+1+i] = fNBorders+1;
138 }
139 fNBorders+=2;
140 }
141 }
142 }
143
e43f6920 144 Clear();
145
0e3c57d2 146 return iResult;
147}
148
149
150
151Int_t AliHLTTPCHWClusterMergerV1::SetDataBlock( AliHLTComponentBlockData *block)
152{
153 //
154 // set block of clusters or MC labels
155 //
156
157 if( !block ){
158 HLTError("Input NULL pointer to data block");
159 return -1;
160 }
0e3c57d2 161
162 Int_t blockType=0;
163
164 if( block->fDataType == (AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC) ) blockType=1;
165 else if( block->fDataType == (AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC) ) blockType=2;
166
167 if( blockType==0 ){
168 HLTError("Unexpected type of input block: %d", block->fDataType);
169 return -1;
170 }
171
172 UInt_t minSlice = AliHLTTPCDefinitions::GetMinSliceNr(*block);
173 UInt_t minPartition = AliHLTTPCDefinitions::GetMinPatchNr(*block);
174 UInt_t maxSlice = AliHLTTPCDefinitions::GetMaxSliceNr(*block);
175 UInt_t maxPartition = AliHLTTPCDefinitions::GetMaxPatchNr(*block);
176 if( maxSlice!=minSlice || maxPartition!=minPartition ){
177 HLTError("Unexpected input block (slices %d-%d, patches %d-%d): only one TPC partition per block is expected", minSlice, maxSlice, minPartition, maxPartition );
178 return -1;
179 }
180
181 if( minSlice>=(UInt_t)fkNSlices || minPartition >=(UInt_t)fkNPatches ){
182 HLTError("Wrong Slice/Patch number of input block: slice %d, patch %d", minSlice, minPartition );
183 return -1;
184 }
185
186 Int_t iSlicePatch = minSlice*fkNPatches + minPartition;
187
188 if( blockType == 1 ) fRawClusterBlocks[iSlicePatch] = block;
189 else if( blockType == 2 ) fMCBlocks[iSlicePatch] = block;
190
191 return 0;
192}
193
194
195void AliHLTTPCHWClusterMergerV1::Clear()
196{
197 /// cleanup
198
199 // fClusters.~vector<AliClusterRecord>();
200 // new(&fClusters) vector<AliClusterRecord>;
201
e43f6920 202 fpData = NULL;
0e3c57d2 203 for( int i=0; i<fkNSlices*fkNPatches; i++){
204 fRawClusterBlocks[i] = NULL;
205 fMCBlocks[i] = NULL;
206 }
207}
208
209
210int AliHLTTPCHWClusterMergerV1::Merge()
211{
212 /// merge clusters
213
214 if( !fMapping ) Init();
215 if( !fMapping ) return 0;
216
e43f6920 217 if( !fpData ){
218 HLTError("Pointer to input data is not set");
219 return -1;
220 }
221
222
0e3c57d2 223 int iResult = 0;
224 int count = 0;
225
226 vector<AliBorderRecord> *fBorderClusters = new vector<AliBorderRecord> [fNBorders];
227
228 for( int iSlice=0; iSlice<fkNSlices; iSlice++){
229
230 for( int iBorder=0; iBorder<fNBorders; iBorder++) fBorderClusters[iBorder].clear();
231
232 for( int iPatch=0; iPatch<fkNPatches; iPatch++){
e43f6920 233 int iSlicePatch = iSlice*fkNPatches+iPatch;
0e3c57d2 234 AliHLTComponentBlockData *block = fRawClusterBlocks[iSlicePatch];
235 if( !block ) continue;
e43f6920 236 AliHLTTPCRawClusterData* clusters= (AliHLTTPCRawClusterData*)( fpData + block->fOffset);
0e3c57d2 237 if(!clusters) continue;
238
239 AliHLTComponentBlockData *mcblock = fMCBlocks[iSlicePatch];
240 AliHLTTPCClusterMCData* mclabels = 0;
e43f6920 241 if( mcblock ) mclabels = (AliHLTTPCClusterMCData*)(fpData + mcblock->fOffset );
0e3c57d2 242 if( mclabels && mclabels->fCount != clusters->fCount ){
243 HLTError("Slice %d, patch %d: Number of MC labels (%d) not equal to N clusters (%d)", iSlice, iPatch, mclabels->fCount, clusters->fCount );
244 mclabels->fCount = 0;
245 mcblock->fSize = sizeof(AliHLTTPCClusterMCData);
246 mclabels = 0;
247 fMCBlocks[iSlicePatch] = 0;
248 }
e43f6920 249
0e3c57d2 250 for( UInt_t iCluster=0; iCluster<clusters->fCount; iCluster++){
251 AliHLTTPCRawCluster &cluster = clusters->fClusters[iCluster];
252
253 // check if the cluster is at the branch border
254 Int_t patchRow = cluster.GetPadRow();
255 int sliceRow=patchRow+AliHLTTPCTransform::GetFirstRow(iPatch);
256 float pad = cluster.GetPad();
257 int iPad = (int) pad;
258
259 int iBorder = -1;
260
261 if( sliceRow>=0 && sliceRow <fNRows && iPad>=0 && iPad < fNRowPads ){
262 iBorder = fMapping[sliceRow*fNRowPads+iPad];
263 if( iBorder>=0 ){
264 float dPad = pad - fBorders[iBorder].fPadPosition;
265 if( cluster.GetSigmaY2()>1.e-4 ){
266 if( dPad*dPad > 12.*cluster.GetSigmaY2() ) iBorder = -1;
267 } else {
268 if( fabs(dPad)>1. ) iBorder = -1;
269 }
270 }
271 }
272 if( iBorder>=0 ){
273 AliHLTTPCClusterMCLabel *mc=0;
274 if( mclabels ) mc = &( mclabels->fLabels[iCluster] );
275 fBorderClusters[iBorder].push_back( AliBorderRecord( &cluster, mc, (int)cluster.GetTime()) );
276 }
277 }
278 } // patches
279
280
e43f6920 281 for( int iBorder=0; iBorder<fNBorders; iBorder+=2){
0e3c57d2 282 vector<AliBorderRecord> &border1 = fBorderClusters[iBorder];
283 vector<AliBorderRecord> &border2 = fBorderClusters[iBorder+1];
284 UInt_t n1 = border1.size();
e43f6920 285 UInt_t n2 = border2.size();
0e3c57d2 286 if( n1==0 || n2==0 ) continue;
287
288 // sort
289
290 std::sort(border1.begin(),border1.end(), CompareTime);
291 std::sort(border2.begin(),border2.end(), CompareTime);
292
293 // merge
294
295 UInt_t ib1 = 0;
296 for( UInt_t ib2 = 0; (ib1<n1) && (ib2<n2); ib2++ ){
297
298 // search first cluster at border1 to merge
299
300 while( ib1<n1 && border1[ib1].fTimeBin>border2[ib2].fTimeBin+fkMergeTimeWindow ){
301 ib1++;
302 }
303
304 if( ib1>= n1 ) break;
305 if( border1[ib1].fTimeBin < border2[ib2].fTimeBin-fkMergeTimeWindow) continue;
306
307 // merge c2->c1
308
309 AliHLTTPCRawCluster *c1 = border1[ib1].fCluster;
310 AliHLTTPCRawCluster *c2 = border2[ib2].fCluster;
311 AliHLTTPCClusterMCLabel *mc1 = border1[ib1].fMC;
312 AliHLTTPCClusterMCLabel *mc2 = border2[ib2].fMC;
313
314
315 if( c1->GetPad()<-1 || c2->GetPad()<-1 ) continue;
316
317 float w1 = c1->GetCharge();
318 float w2 = c2->GetCharge();
319 if( w1<=0 ) w1 = 1;
320 if( w2<=0 ) w2 = 1;
321 float w = 1./(w1+w2);
322 w1*=w;
323 w2*=w;
324
325 c1->SetCharge( c1->GetCharge() + c2->GetCharge() );
326 if( c1->GetQMax() < c2->GetQMax() ) c1->SetQMax( c2->GetQMax() );
327
328 c1->SetSigmaY2( w1*c1->GetSigmaY2() + w2*c2->GetSigmaY2()
329 + (c1->GetPad() - c2->GetPad())*(c1->GetPad() - c2->GetPad())*w1*w2 );
330
331 c1->SetSigmaZ2( w1*c1->GetSigmaZ2() + w2*c2->GetSigmaZ2()
332 + (c1->GetTime() - c2->GetTime())*(c1->GetTime() - c2->GetTime())*w1*w2 );
333
334 c1->SetPad( w1*c1->GetPad() + w2*c2->GetPad() );
335 c1->SetTime( w1*c1->GetTime() + w2*c2->GetTime() );
336
337 // merge MC labels
338 if( mc1 && mc2 ){
339
340 AliHLTTPCClusterMCWeight labels[6] = {
341 mc1->fClusterID[0],
342 mc1->fClusterID[1],
343 mc1->fClusterID[2],
344 mc2->fClusterID[0],
345 mc2->fClusterID[1],
346 mc2->fClusterID[2]
347 };
348
349 sort(labels, labels+6, CompareMCLabels);
350 for( unsigned int i=1; i<6; i++ ){
351 if(labels[i-1].fMCID==labels[i].fMCID ){
352 labels[i].fWeight+=labels[i-1].fWeight;
353 labels[i-1].fWeight = 0;
354 }
355 }
356
357 sort(labels, labels+6, CompareMCWeights );
358
359 for( unsigned int i=0; i<3; i++ ){
360 mc1->fClusterID[i] = labels[i];
361 }
362
363 } // MC labels
364
365 // wipe c2
366 c2->SetPad(-10);
367
368 count++;
369 // do not merge to c1 anymore
370 ib1++;
371 }
372 } // iBorder
373
e43f6920 374
0e3c57d2 375 // remove merged clusters from data
376
377 for( int iPatch=0; iPatch<fkNPatches; iPatch++){
e43f6920 378 int iSlicePatch = iSlice*fkNPatches+iPatch;
0e3c57d2 379 AliHLTComponentBlockData *block = fRawClusterBlocks[iSlicePatch];
380 if( !block ) continue;
e43f6920 381 AliHLTTPCRawClusterData* clusters= (AliHLTTPCRawClusterData*)(fpData + block->fOffset);
0e3c57d2 382 if(!clusters) continue;
383 AliHLTUInt32_t nClustersOrig = clusters->fCount;
384
385 AliHLTComponentBlockData *mcblock = fMCBlocks[iSlicePatch];
386 AliHLTTPCClusterMCData* mclabels = 0;
e43f6920 387 if( mcblock ) mclabels = (AliHLTTPCClusterMCData*)(fpData + mcblock->fOffset);
0e3c57d2 388 if( mclabels && mclabels->fCount != nClustersOrig ) mclabels = 0;
389
390 clusters->fCount=0;
391 for( UInt_t iCluster=0; iCluster<nClustersOrig; iCluster++){
392 AliHLTTPCRawCluster &cluster = clusters->fClusters[iCluster];
393 if( cluster.GetPad()<-1 ) continue; // the cluster has been merged
b332ccfe 394 if( clusters->fCount != iCluster ){
395 clusters->fClusters[clusters->fCount] = cluster;
396 if( mclabels ) mclabels->fLabels[clusters->fCount] = mclabels->fLabels[iCluster];
397 }
0e3c57d2 398 clusters->fCount++;
399 }
400
401 block->fSize = sizeof(AliHLTTPCRawClusterData) + clusters->fCount*sizeof(AliHLTTPCRawCluster);
402 if( mclabels ){
403 mclabels->fCount = clusters->fCount;
404 mcblock->fSize = sizeof(AliHLTTPCClusterMCData) + mclabels->fCount*sizeof(AliHLTTPCClusterMCLabel);
405 }
406 }
407
408 } // iSlice
409
410 delete[] fBorderClusters;
411
412 if (iResult<0) return iResult;
413 return count;
414}
415