Line data Source code
1 : // $Id: AliHLTTPCHWClusterDecoderComponent.cxx 59611 2012-11-15 16:23:28Z 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: Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de *
8 : //* for The ALICE HLT Project. *
9 : //* *
10 : //* Permission to use, copy, modify and distribute this software and its *
11 : //* documentation strictly for non-commercial purposes is hereby granted *
12 : //* without fee, provided that the above copyright notice appears in all *
13 : //* copies and that both the copyright notice and this permission notice *
14 : //* appear in the supporting documentation. The authors make no claims *
15 : //* about the suitability of this software for any purpose. It is *
16 : //* provided "as is" without express or implied warranty. *
17 : //***************************************************************************
18 :
19 :
20 : /** @file AliHLTTPCHWClusterDecoderComponent.cxx
21 : @author Sergey Gorbunov
22 : @date
23 : @brief
24 : */
25 :
26 : #include "AliHLTTPCHWClusterDecoderComponent.h"
27 : #include "AliHLTTPCHWClusterMergerV1.h"
28 : #include "AliHLTTPCDefinitions.h"
29 : #include "AliHLTTPCSpacePointData.h"
30 : #include "AliHLTTPCClusterDataFormat.h"
31 : #include "AliHLTCDHWrapper.h"
32 : #include "AliHLTTPCRawCluster.h"
33 : #include "AliHLTTPCHWCFEmulator.h"
34 : #include "AliHLTTPCHWCFData.h"
35 : #include "AliHLTErrorGuard.h"
36 : #include "AliHLTTPCRawClustersDescriptor.h"
37 : #include "AliGRPManager.h"
38 : #include "AliGRPObject.h"
39 : #include "AliDAQ.h"
40 :
41 : #include "AliCDBManager.h"
42 : #include "AliCDBEntry.h"
43 :
44 : #include "TMath.h"
45 : #include "TObjString.h"
46 : #include <cstdlib>
47 : #include <cerrno>
48 : #include <sys/time.h>
49 :
50 : using namespace std;
51 :
52 6 : ClassImp(AliHLTTPCHWClusterDecoderComponent) //ROOT macro for the implementation of ROOT specific class methods
53 :
54 : const char* AliHLTTPCHWClusterDecoderComponent::fgkOCDBEntry="HLT/ConfigTPC/TPCHWClusterDecoder";
55 :
56 :
57 3 : AliHLTTPCHWClusterDecoderComponent::AliHLTTPCHWClusterDecoderComponent()
58 : :
59 3 : fpDecoder(NULL),
60 3 : fpClusterMerger(NULL),
61 3 : fDoMerge(1),
62 3 : fAlreadyMerged(0),
63 3 : fTPCPresent(0),
64 3 : fProcessingRCU2Data(0),
65 3 : fBenchmark("HWClusterDecoder")
66 15 : {
67 : // see header file for class documentation
68 : // or
69 : // refer to README to build package
70 : // or
71 : // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
72 :
73 3 : fBenchmark.Reset();
74 3 : fBenchmark.SetTimer(0,"total");
75 6 : }
76 :
77 : AliHLTTPCHWClusterDecoderComponent::~AliHLTTPCHWClusterDecoderComponent()
78 18 : {
79 : // destructor
80 3 : delete fpDecoder;
81 3 : delete fpClusterMerger;
82 9 : }
83 :
84 : const char* AliHLTTPCHWClusterDecoderComponent::GetComponentID()
85 : {
86 : // see header file for class documentation
87 396 : return "TPCHWClusterDecoder";
88 : }
89 :
90 :
91 :
92 : void AliHLTTPCHWClusterDecoderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) {
93 : // see header file for class documentation
94 :
95 0 : list.clear();
96 0 : list.push_back( AliHLTTPCDefinitions::HWClustersDataType() | kAliHLTDataOriginTPC );
97 0 : list.push_back( AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo() | kAliHLTDataOriginTPC );
98 0 : list.push_back( AliHLTTPCDefinitions::RawClustersDataType() | kAliHLTDataOriginTPC );
99 0 : list.push_back( AliHLTTPCDefinitions::RawClustersDescriptorDataType() | kAliHLTDataOriginTPC );
100 0 : }
101 :
102 : AliHLTComponentDataType AliHLTTPCHWClusterDecoderComponent::GetOutputDataType() {
103 : // see header file for class documentation
104 :
105 0 : return kAliHLTMultipleDataType;
106 : }
107 :
108 : int AliHLTTPCHWClusterDecoderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) {
109 : // see header file for class documentation
110 :
111 0 : tgtList.clear();
112 0 : tgtList.push_back( AliHLTTPCDefinitions::RawClustersDataType() | kAliHLTDataOriginTPC );
113 0 : tgtList.push_back( AliHLTTPCDefinitions::RawClustersDescriptorDataType() | kAliHLTDataOriginTPC );
114 0 : tgtList.push_back( AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo() | kAliHLTDataOriginTPC );
115 0 : return tgtList.size();
116 : }
117 :
118 : void AliHLTTPCHWClusterDecoderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) {
119 : // see header file for class documentation
120 0 : constBase = 0;
121 0 : inputMultiplier = 2.0;
122 0 : }
123 :
124 : AliHLTComponent* AliHLTTPCHWClusterDecoderComponent::Spawn() {
125 : // see header file for class documentation
126 :
127 0 : return new AliHLTTPCHWClusterDecoderComponent();
128 0 : }
129 :
130 : int AliHLTTPCHWClusterDecoderComponent::DoInit( int argc, const char** argv )
131 : {
132 : // see header file for class documentation
133 :
134 : int iResult=0;
135 :
136 0 : AliGRPManager mgr;
137 0 : mgr.ReadGRPEntry();
138 0 : fTPCPresent = ((mgr.GetGRPData()->GetDetectorMask() & AliDAQ::kTPC) != 0);
139 :
140 0 : if (!fTPCPresent)
141 : {
142 0 : HLTWarning("TPC missing in detector mask, disabling TPC Processing");
143 0 : return(iResult);
144 : }
145 :
146 0 : fpDecoder=new AliHLTTPCHWCFData;
147 0 : if (!fpDecoder) iResult=-ENOMEM;
148 :
149 0 : fDoMerge = 1;
150 0 : fAlreadyMerged = 0;
151 0 : fProcessingRCU2Data = 0;
152 :
153 0 : if (iResult>=0) iResult = ConfigureFromCDBTObjString(fgkOCDBEntry, NULL, true);
154 :
155 0 : if (iResult>=0 && argc>0) iResult = ConfigureFromArgumentString(argc, argv);
156 :
157 0 : if ( iResult>=0 ) iResult = InitClusterMerger();
158 :
159 0 : return iResult;
160 0 : } // end DoInit()
161 :
162 : int AliHLTTPCHWClusterDecoderComponent::DoDeinit() {
163 : // see header file for class documentation
164 0 : if (!fTPCPresent) return 0;
165 0 : if (!fpDecoder) delete fpDecoder;
166 0 : fpDecoder=NULL;
167 0 : delete fpClusterMerger;
168 0 : fpClusterMerger = NULL;
169 0 : return 0;
170 0 : }
171 :
172 : int AliHLTTPCHWClusterDecoderComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/) {
173 : // see header file for class documentation
174 :
175 0 : fDoMerge = 1;
176 0 : fAlreadyMerged = 0;
177 0 : fProcessingRCU2Data = 0;
178 : int iResult = 0;
179 0 : iResult = ConfigureFromCDBTObjString( fgkOCDBEntry, NULL, true );
180 0 : if ( iResult>=0 ) iResult = InitClusterMerger();
181 0 : return iResult;
182 : }
183 :
184 : int AliHLTTPCHWClusterDecoderComponent::ScanConfigurationArgument(int argc, const char** argv){
185 :
186 : // see header file for class documentation
187 :
188 0 : if (argc<=0) return 0;
189 : int i=0;
190 0 : TString argument=argv[i];
191 :
192 0 : if (argument.CompareTo("-do-merge")==0){
193 0 : fDoMerge = 1;
194 0 : fAlreadyMerged = 0;
195 0 : return 1;
196 : }
197 :
198 0 : if (argument.CompareTo("-do-not-merge")==0){
199 0 : fDoMerge = 0;
200 0 : return 1;
201 : }
202 :
203 0 : if (argument.CompareTo("-already-merged") == 0)
204 : {
205 0 : fDoMerge = 0;
206 0 : fAlreadyMerged = 1;
207 0 : return 1;
208 : }
209 :
210 0 : if (argument.CompareTo("-rcu2-data") == 0)
211 : {
212 0 : fDoMerge = 1;
213 0 : fAlreadyMerged = 0;
214 0 : fProcessingRCU2Data = 1;
215 0 : return 1;
216 : }
217 :
218 : // unknown argument
219 0 : return -EINVAL;
220 0 : }
221 :
222 : int AliHLTTPCHWClusterDecoderComponent::InitClusterMerger()
223 : {
224 : //
225 : // init merger
226 : //
227 : int iResult = 0;
228 0 : if( !fDoMerge ){
229 0 : delete fpClusterMerger;
230 0 : fpClusterMerger = NULL;
231 0 : return iResult;
232 : }
233 0 : if ( !fpClusterMerger ) {
234 0 : fpClusterMerger = new AliHLTTPCHWClusterMergerV1;
235 0 : if( !fpClusterMerger ) return -ENOMEM;
236 : }
237 :
238 0 : iResult = fpClusterMerger->Init( fProcessingRCU2Data );
239 0 : if( iResult<0 ){
240 0 : HLTError("Can not initialise cluster merger");
241 0 : delete fpClusterMerger;
242 0 : fpClusterMerger = 0;
243 0 : }
244 0 : return iResult;
245 0 : }
246 :
247 : void AliHLTTPCHWClusterDecoderComponent::GetOCDBObjectDescription( TMap* const targetMap)
248 : {
249 : // Get a list of OCDB object description needed for the particular component
250 : if (!targetMap) return;
251 :
252 : // OCDB entries for component arguments
253 : //targetMap->Add(new TObjString(fgkOCDBEntry), new TObjString("component argument for HW cluster decoder")); //We do not require this, we fall back to config string "" if non-existing
254 0 : }
255 :
256 :
257 : int AliHLTTPCHWClusterDecoderComponent::DoEvent(const AliHLTComponentEventData& evtData,
258 : const AliHLTComponentBlockData* blocks,
259 : AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
260 : AliHLTUInt32_t& size,
261 : vector<AliHLTComponentBlockData>& outputBlocks ){
262 : // see header file for class documentation
263 :
264 0 : UInt_t maxOutSize = size;
265 0 : size = 0;
266 : int iResult = 0;
267 0 : if (!fTPCPresent) return 0;
268 0 : if(!IsDataEvent()) return 0;
269 :
270 0 : if (!fpDecoder) return -ENODEV;
271 :
272 0 : fBenchmark.StartNewEvent();
273 0 : fBenchmark.Start(0);
274 :
275 : AliHLTUInt8_t* origOutputPtr = outputPtr;
276 0 : UInt_t origOutputBlocksSize = outputBlocks.size();
277 :
278 : bool isInputPresent = kFALSE;
279 :
280 : static int nCluTotal = 0;
281 : static int nCluDeconvolutedTime = 0;
282 : static int nCluDeconvolutedPad = 0;
283 : static int nCluDeconvolutedPadAndTime = 0;
284 : static int nCluDeconvolutedPadOrTime = 0;
285 :
286 0 : for( unsigned long ndx=0; ndx<evtData.fBlockCnt; ndx++ ){
287 :
288 0 : const AliHLTComponentBlockData *iter = blocks+ndx;
289 :
290 0 : fBenchmark.AddInput(iter->fSize);
291 :
292 : HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
293 : evtData.fEventID, evtData.fEventID,
294 : DataType2Text( iter->fDataType).c_str(),
295 : DataType2Text(AliHLTTPCDefinitions::fgkHWClustersDataType).c_str());
296 :
297 0 : if(iter->fDataType == (AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC) ){
298 : // simply forward MC labels
299 :
300 0 : if( size+iter->fSize > maxOutSize ){
301 0 : HLTWarning( "Output buffer (%db) is too small, required %db", maxOutSize, size+iter->fSize);
302 : iResult = -ENOSPC;
303 0 : break;
304 : }
305 :
306 0 : memcpy( outputPtr, iter->fPtr, iter->fSize );
307 :
308 0 : AliHLTComponentBlockData bd;
309 0 : FillBlockData( bd );
310 0 : bd.fOffset = size;
311 0 : bd.fSize = iter->fSize;
312 0 : bd.fSpecification = iter->fSpecification;
313 0 : bd.fDataType = iter->fDataType;
314 0 : outputBlocks.push_back( bd );
315 0 : size += bd.fSize;
316 0 : outputPtr += bd.fSize;
317 0 : fBenchmark.AddOutput(bd.fSize);
318 : continue;
319 0 : }
320 :
321 0 : if( iter->fDataType == (AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC) ){
322 :
323 : isInputPresent = 1;
324 :
325 : HLTDebug("minSlice: %d, minPartition: %d", AliHLTTPCDefinitions::GetMinSliceNr(*iter), AliHLTTPCDefinitions::GetMinPatchNr(*iter));
326 :
327 0 : long maxRawClusters = ((long)maxOutSize-size-sizeof(AliHLTTPCRawClusterData))/sizeof(AliHLTTPCRawCluster) - 1; //Subract 1 to correct for rounding
328 :
329 0 : if( maxRawClusters<=0 ) {
330 0 : HLTWarning("No more space to add raw clusters, exiting!");
331 : iResult = -ENOSPC;
332 0 : continue;
333 : }
334 :
335 : // copy raw cluster data from input
336 :
337 0 : AliHLTTPCRawClusterData* outputRaw= (AliHLTTPCRawClusterData*)(outputPtr);
338 :
339 0 : outputRaw->fVersion = 0;
340 0 : outputRaw->fCount = 0;
341 :
342 0 : AliHLTUInt32_t *buffer = (AliHLTUInt32_t*)iter->fPtr;
343 0 : AliHLTCDHWrapper header(buffer);
344 :
345 : // skip the first 8 32-bit CDH words
346 0 : buffer += header.GetHeaderSize()/sizeof(AliHLTUInt32_t);
347 0 : UInt_t bufferSize32 = ((Int_t)iter->fSize - header.GetHeaderSize() )/sizeof(AliHLTUInt32_t);
348 :
349 0 : if (fpDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))>=0 && fpDecoder->CheckVersion()>=0) {
350 :
351 0 : for (AliHLTTPCHWCFData::iterator cl=fpDecoder->begin(); cl!=fpDecoder->end(); ++cl) {
352 :
353 0 : if(outputRaw->fCount>=maxRawClusters){
354 0 : HLTWarning("No more space to add clusters, exiting!");
355 : iResult = -ENOSPC;
356 0 : break;
357 : }
358 0 : AliHLTTPCRawCluster &c = outputRaw->fClusters[outputRaw->fCount];
359 0 : c.SetPadRow(cl.GetPadRow());
360 0 : c.SetCharge(cl.GetCharge());
361 0 : c.SetPad(cl.GetPad());
362 0 : c.SetTime(cl.GetTime());
363 0 : c.SetSigmaPad2(cl.GetSigmaY2());
364 0 : c.SetSigmaTime2(cl.GetSigmaZ2());
365 0 : c.SetQMax(cl.GetQMax());
366 0 : outputRaw->fCount++;
367 : //if( cl.GetSigmaY2()>0 && cl.GetSigmaZ2()>0 )
368 : {
369 0 : nCluTotal ++;
370 0 : c.ClearFlags();
371 0 : if( cl.IsDeconvolutedPad() )
372 : {
373 0 : nCluDeconvolutedPad++;
374 0 : c.SetFlagSplitPad();
375 0 : }
376 0 : if( cl.IsDeconvolutedTime() )
377 : {
378 0 : nCluDeconvolutedTime++;
379 0 : c.SetFlagSplitTime();
380 0 : }
381 0 : if( cl.IsDeconvolutedPad() && cl.IsDeconvolutedTime() ) nCluDeconvolutedPadAndTime++;
382 0 : if( cl.IsDeconvolutedPad() || cl.IsDeconvolutedTime() ) nCluDeconvolutedPadOrTime++;
383 : }
384 : }
385 0 : }
386 : // fill into HLT output data
387 0 : AliHLTComponentBlockData bdRawClusters;
388 0 : FillBlockData( bdRawClusters );
389 0 : bdRawClusters.fOffset = size;
390 0 : bdRawClusters.fSize = sizeof(AliHLTTPCRawClusterData)+outputRaw->fCount*sizeof(AliHLTTPCRawCluster);
391 0 : bdRawClusters.fSpecification = iter->fSpecification;
392 0 : bdRawClusters.fDataType = AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC;
393 0 : outputBlocks.push_back( bdRawClusters );
394 0 : fBenchmark.AddOutput(bdRawClusters.fSize);
395 0 : size += bdRawClusters.fSize;
396 0 : outputPtr += bdRawClusters.fSize;
397 0 : }
398 :
399 0 : } // end of loop over data blocks
400 :
401 0 : double tmp = nCluTotal>0 ?100./nCluTotal :0;
402 :
403 0 : HLTInfo(" decoded clusters total %d, deconvoluted pad %f\%, time %f\%, pd&&tm %f\%, pd||tm %f\%",
404 : nCluTotal,(nCluDeconvolutedPad*tmp), (nCluDeconvolutedTime*tmp), (nCluDeconvolutedPadAndTime*tmp), (nCluDeconvolutedPadOrTime*tmp) );
405 :
406 0 : if( fDoMerge && fpClusterMerger ){
407 0 : fpClusterMerger->Clear();
408 0 : fpClusterMerger->SetDataPointer(origOutputPtr);
409 0 : for( UInt_t i=origOutputBlocksSize; i<outputBlocks.size(); i++){
410 0 : fpClusterMerger->SetDataBlock(&(outputBlocks[i]));
411 : }
412 0 : int nMerged = fpClusterMerger->Merge();
413 0 : fpClusterMerger->Clear();
414 0 : HLTInfo("Merged %d clusters",nMerged);
415 0 : }
416 :
417 0 : AliHLTTPCRawClustersDescriptor desc;
418 0 : desc.SetMergedClustersFlag( (fDoMerge || fAlreadyMerged) ? 1 : 0);
419 :
420 : // Write header block
421 0 : if( isInputPresent ){
422 0 : AliHLTComponent_BlockData bd;
423 0 : FillBlockData(bd);
424 0 : bd.fOffset = size;
425 0 : bd.fSize = sizeof(AliHLTTPCRawClustersDescriptor);
426 0 : bd.fDataType = AliHLTTPCDefinitions::RawClustersDescriptorDataType() | kAliHLTDataOriginTPC;
427 0 : if( maxOutSize < size + bd.fSize ){
428 0 : HLTWarning( "Output buffer (%db) is too small, required %db", maxOutSize, size+bd.fSize);
429 : iResult = -ENOSPC;
430 0 : return iResult;
431 : }
432 0 : *(AliHLTTPCRawClustersDescriptor*)(outputPtr ) = desc;
433 0 : outputBlocks.push_back(bd);
434 0 : size += bd.fSize;
435 0 : outputPtr += bd.fSize;
436 0 : fBenchmark.AddOutput(bd.fSize);
437 0 : HLTBenchmark("header data block of size %d", bd.fSize);
438 0 : }
439 :
440 0 : if( iResult>=0 ){
441 : //
442 : // forward unpacked clusters if they are present
443 : // to forward input data, one should only forward the block descriptors, without copying the data.
444 : // The framework will recognise that these blocks are forwarded, as they have fPtr field !=NULL, and take the data from fPtr pointer
445 : //
446 0 : for( unsigned long ndx = 0; ndx < evtData.fBlockCnt; ndx++ ){
447 0 : const AliHLTComponentBlockData* iter = blocks+ndx;
448 0 : if( iter->fDataType == AliHLTTPCDefinitions::RawClustersDataType() || iter->fDataType == AliHLTTPCDefinitions::RawClustersDescriptorDataType() ){
449 0 : if( !iter->fPtr ) continue;
450 0 : fBenchmark.AddOutput(iter->fSize);
451 0 : outputBlocks.push_back( *iter );
452 : }
453 0 : }
454 0 : }
455 :
456 0 : fBenchmark.Stop(0);
457 0 : HLTInfo(fBenchmark.GetStatistics());
458 :
459 0 : return iResult;
460 0 : } // end DoEvent()
461 :
462 :
463 :
464 : void AliHLTTPCHWClusterDecoderComponent::PrintDebug(AliHLTUInt32_t *buffer, Int_t size){
465 : // see header file for class documentation
466 :
467 0 : HLTInfo("The size is: %d", size);
468 0 : for(Int_t n32bit=0; n32bit<size; n32bit++){
469 :
470 0 : AliHLTUInt8_t *wordPtr = reinterpret_cast<AliHLTUInt8_t*>(&buffer[n32bit]);
471 : // cout << "word ptr initialized"<<endl;
472 0 : for(Int_t w=3;w>=0;w--){
473 : // cout <<"accessing word"<<endl;
474 0 : AliHLTUInt8_t word = wordPtr[w];
475 : // cout<< "word was accessed"<<endl;
476 0 : for(int n=7; n>=0; n--){
477 : //print the byte values
478 0 : if((((word>>n)<<7)&0x80) != 0){
479 0 : printf("1");
480 0 : }
481 : else{
482 0 : printf("0");
483 : }
484 : }
485 0 : printf(" ");
486 : }
487 0 : printf("\n");
488 : }
489 0 : } // end of PrintDebug
490 :
|