2 //****************************************************************************
3 //* This file is property of and copyright by the ALICE HLT Project *
4 //* ALICE Experiment at CERN, All rights reserved. *
6 //* Primary Authors: Sergey Gorbunov, Torsten Alt *
7 //* Developers: Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> *
8 //* Torsten Alt <talt@cern.ch> *
9 //* for The ALICE HLT Project. *
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 //****************************************************************************
20 // @file AliHLTTPCHWCFEmulatorComponent.cxx
21 // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
22 // @author Torsten Alt <talt@cern.ch>
23 // @brief HLT Component interface for for FPGA ClusterFinder Emulator for TPC
24 // @brief ( see AliHLTTPCHWCFEmulator class )
31 #include "AliHLTTPCHWCFEmulatorComponent.h"
33 #include "AliHLTTPCDefinitions.h"
34 #include "AliHLTTPCHWCFDataTypes.h"
35 #include "AliHLTTPCClusterMCData.h"
36 #include "AliHLTTPCHWCFData.h"
38 #include "AliGRPObject.h"
39 #include "AliCDBEntry.h"
40 #include "AliCDBManager.h"
41 #include "AliRawDataHeader.h"
45 #include "TObjString.h"
46 #include "TObjArray.h"
52 AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent()
59 fDoSinglePadSuppression(1),
61 fClusterLowerLimit(0),
67 fBenchmark("TPCHWClusterFinderEmulator")
69 // see header file for class documentation
71 // refer to README to build package
73 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
77 AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent(const AliHLTTPCHWCFEmulatorComponent&)
84 fDoSinglePadSuppression(1),
86 fClusterLowerLimit(0),
92 fBenchmark("TPCHWClusterFinderEmulator")
97 AliHLTTPCHWCFEmulatorComponent& AliHLTTPCHWCFEmulatorComponent::operator=(const AliHLTTPCHWCFEmulatorComponent&)
103 AliHLTTPCHWCFEmulatorComponent::~AliHLTTPCHWCFEmulatorComponent()
105 // see header file for class documentation
108 // Public functions to implement AliHLTComponent's interface.
109 // These functions are required for the registration process
111 const char* AliHLTTPCHWCFEmulatorComponent::GetComponentID()
113 // see header file for class documentation
114 return "TPCHWClusterFinderEmulator";
117 void AliHLTTPCHWCFEmulatorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
119 // see header file for class documentation
121 list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
122 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
125 AliHLTComponentDataType AliHLTTPCHWCFEmulatorComponent::GetOutputDataType()
127 // see header file for class documentation
128 return kAliHLTMultipleDataType;
131 int AliHLTTPCHWCFEmulatorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
133 // see header file for class documentation
135 tgtList.push_back(AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC );
136 tgtList.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
137 return tgtList.size();
141 void AliHLTTPCHWCFEmulatorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
143 // see header file for class documentation
144 // XXX TODO: Find more realistic values.
146 inputMultiplier = (6 * 0.4);
150 AliHLTComponent* AliHLTTPCHWCFEmulatorComponent::Spawn()
152 // see header file for class documentation
153 return new AliHLTTPCHWCFEmulatorComponent();
156 void AliHLTTPCHWCFEmulatorComponent::GetOCDBObjectDescription( TMap* const targetMap){
157 // Get a list of OCDB object description needed for the particular component
159 if (!targetMap) return;
161 // OCDB entries for component arguments
162 targetMap->Add(new TObjString("HLT/ConfigTPC/TPCHWClusterFinder"), new TObjString("component arguments, empty at the moment"));
166 int AliHLTTPCHWCFEmulatorComponent::DoInit( int argc, const char** argv )
168 // see header file for class documentation
170 TString arguments = "";
171 for ( int i = 0; i < argc; i++ ) {
172 if ( !arguments.IsNull() ) arguments += " ";
173 arguments += argv[i];
176 return Configure( NULL, NULL, arguments.Data() );
179 int AliHLTTPCHWCFEmulatorComponent::Reconfigure( const char* cdbEntry, const char* chainId )
181 // Reconfigure the component from OCDB
183 return Configure( cdbEntry, chainId, NULL );
186 int AliHLTTPCHWCFEmulatorComponent::ScanConfigurationArgument(int argc, const char** argv)
188 // see header file for class documentation
189 TString arguments = "";
190 for ( int i = 0; i < argc; i++ ) {
191 if ( !arguments.IsNull() ) arguments += " ";
192 arguments += argv[i];
194 return ReadConfigurationString(arguments);
199 void AliHLTTPCHWCFEmulatorComponent::SetDefaultConfiguration()
201 // Set default configuration for the FPGA ClusterFinder Emulator component
202 // Some parameters can be later overwritten from the OCDB
208 fDoSinglePadSuppression = 1;
210 fClusterLowerLimit = 0;
215 fBenchmark.SetTimer(0,"total");
216 fBenchmark.SetTimer(1,"reco");
219 int AliHLTTPCHWCFEmulatorComponent::ReadConfigurationString( const char* arguments )
221 // Set configuration parameters for the FPGA ClusterFinder Emulator component
225 if ( !arguments ) return iResult;
227 TString allArgs = arguments;
229 int bMissingParam = 0;
231 TObjArray* pTokens = allArgs.Tokenize( " " );
233 int nArgs = pTokens ? pTokens->GetEntries() : 0;
235 for ( int i = 0; i < nArgs; i++ ) {
236 argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
237 if ( argument.IsNull() ) continue;
239 if ( argument.CompareTo( "-deconvolute-time" ) == 0 ) {
240 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
241 fDoDeconvTime = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
242 HLTInfo( "Time deconvolution is set to: %d", fDoDeconvTime );
246 if ( argument.CompareTo( "-deconvolute-pad" ) == 0 ) {
247 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
248 fDoDeconvPad = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
249 HLTInfo( "Pad deconvolution is set to: %d", fDoDeconvPad );
253 if ( argument.CompareTo( "-deconvolute" ) == 0 ) {
254 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
255 fDoDeconvTime = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
256 fDoDeconvPad = fDoDeconvTime;
257 HLTInfo( "Time and pad deconvolution is set to: %d", fDoDeconvPad );
261 if ( argument.CompareTo( "-do-mc" ) == 0 ) {
262 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
263 fDoMC = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
264 HLTInfo( "MC processing is set to: %d", fDoMC );
268 if ( argument.CompareTo( "-flow-control" ) == 0 ) {
269 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
270 fDoFlowControl = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
271 HLTInfo( "Flow control is set to: %d", fDoFlowControl );
275 if ( argument.CompareTo( "-single-pad-suppression" ) == 0 ) {
276 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
277 fDoSinglePadSuppression = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
278 HLTInfo( "Single pad suppression is set to: %d", fDoSinglePadSuppression );
282 if ( argument.CompareTo( "-bypass-merger" ) == 0 ) {
283 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
284 fBypassMerger = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
285 HLTInfo( "Bypassing merger is set to: %d", fBypassMerger );
289 if ( argument.CompareTo( "-cluster-lower-limit" ) == 0 ) {
290 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
291 fClusterLowerLimit = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
292 HLTInfo( "Cluster lower limit is set to: %d", fClusterLowerLimit );
296 if ( argument.CompareTo( "-single-sequence-limit" ) == 0 ) {
297 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
298 fSingleSeqLimit = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
299 HLTInfo( "Single sequence limit is set to: %d", fSingleSeqLimit );
303 if ( argument.CompareTo( "-merger-distance" ) == 0 ) {
304 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
305 fMergerDistance = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
306 HLTInfo( "Merger distance is set to: %d", fMergerDistance );
310 if ( argument.CompareTo( "-debug-level" ) == 0 ) {
311 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
312 fDebug = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
313 HLTInfo( "Debug level is set to: %d", fDebug );
317 HLTError( "Unknown option \"%s\"", argument.Data() );
322 if ( bMissingParam ) {
323 HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
331 int AliHLTTPCHWCFEmulatorComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
333 // Read configuration from OCDB
335 const char* defaultNotify = "";
338 cdbEntry = "HLT/ConfigTPC/TPCHWClusterFinder";
339 defaultNotify = " (default)";
343 HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
344 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
347 HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
351 TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
354 HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
358 HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
360 return ReadConfigurationString( pString->GetString().Data() );
364 int AliHLTTPCHWCFEmulatorComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
366 // Configure the component
367 // There are few levels of configuration,
368 // parameters which are set on one step can be overwritten on the next step
370 //* read hard-coded values
372 SetDefaultConfiguration();
374 //* read the default CDB entry
376 int iResult1 = ReadCDBEntry( NULL, chainId );
378 //* read the actual CDB entry if required
380 int iResult2 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
382 //* read extra parameters from input (if they are)
386 if ( commandLine && commandLine[0] != '\0' ) {
387 HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
388 iResult3 = ReadConfigurationString( commandLine );
391 if( fDebug>1 ) fCFEmulator.SetDebugLevel( fDebug );
392 else fCFEmulator.SetDebugLevel(0);
394 return iResult1 ? iResult1 : ( iResult2 ? iResult2 : iResult3 );
398 int AliHLTTPCHWCFEmulatorComponent::DoDeinit()
400 // see header file for class documentation
405 int AliHLTTPCHWCFEmulatorComponent::DoEvent( const AliHLTComponentEventData& evtData,
406 const AliHLTComponentBlockData* blocks,
407 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
408 AliHLTUInt32_t& size,
409 vector<AliHLTComponentBlockData>& outputBlocks )
411 // see header file for class documentation
414 AliHLTUInt32_t maxSize = size;
421 fBenchmark.StartNewEvent();
424 AliHLTUInt32_t configWord1=0, configWord2=0;
425 AliHLTTPCHWCFEmulator::CreateConfiguration
426 ( fDoDeconvTime, fDoDeconvPad, fDoFlowControl, fDoSinglePadSuppression, fBypassMerger, fClusterLowerLimit, fSingleSeqLimit, fMergerDistance, configWord1, configWord2 );
428 for ( unsigned long ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
430 const AliHLTComponentBlockData* iter = blocks+ndx;
432 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC)
433 && iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
435 int slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
436 int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
438 const char *str=Form("slice %d patch %d:", slice, patch);
440 fBenchmark.AddInput(iter->fSize);
442 if (!iter->fPtr) continue;
444 // create input block for the HW cluster finder
446 const AliHLTUInt32_t *rawEvent=0;
447 const AliHLTTPCClusterMCLabel *mcLabels = 0;
448 AliHLTUInt32_t rawEventSize32 = 0;
449 AliHLTUInt32_t nMCLabels = 0;
451 if( fCFSupport.CreateRawEvent( iter, rawEvent, rawEventSize32, mcLabels, nMCLabels )<0 ) continue;
457 // book memory for the output
459 AliHLTUInt32_t maxNClusters = rawEventSize32 + 1; // N 32-bit words in input
460 AliHLTUInt32_t clustersSize32 = maxNClusters*AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize;
461 AliHLTUInt32_t nOutputMC = maxNClusters;
463 AliHLTUInt32_t headerSize = sizeof(AliRawDataHeader);
464 AliHLTUInt8_t *outBlock = new AliHLTUInt8_t[ headerSize+clustersSize32*sizeof(AliHLTUInt32_t) ];
466 AliHLTTPCClusterMCData *outMC = reinterpret_cast<AliHLTTPCClusterMCData *>(new AliHLTTPCClusterMCLabel[nOutputMC+1]);
468 if( !outBlock || !outMC ){
469 HLTWarning("%s Not enouth memory!!!", str);
475 // fill CDH header here, since the HW clusterfinder does not receive it
477 AliRawDataHeader *cdhHeader = reinterpret_cast<AliRawDataHeader*>(iter->fPtr);
478 AliRawDataHeader *outCDHHeader = reinterpret_cast<AliRawDataHeader*>(outBlock);
479 *outCDHHeader = *cdhHeader;
480 outCDHHeader->fSize = 0xFFFFFFFF;
482 AliHLTUInt32_t *outClusters = reinterpret_cast<AliHLTUInt32_t*> (outBlock + headerSize);
486 ( fCFSupport.GetMapping(slice,patch), configWord1, configWord2 );
488 int err = fCFEmulator.FindClusters( rawEvent, rawEventSize32,
489 outClusters, clustersSize32,
493 if( err==-1 ){ HLTWarning("NULL input pointer (warning %d)",err);}
494 else if( err==-2 ){ HLTWarning("No space left in the output buffer (warning %d)",err); }
495 else if( err<0 ){ HLTWarning("HWCF emulator finished with error code %d",err); }
503 int elsize=AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize;
504 printf("\nHWCF Emulator: output clusters for slice%d patch %d:\n",slice,patch);
505 for( AliHLTUInt32_t i=0; i<clustersSize32; i+=elsize ){
506 AliHLTUInt32_t *c = outClusters+i;
507 AliHLTUInt32_t flag = (c[0]>>30);
508 if( flag == 0x3){ //beginning of a cluster
509 int padRow = (c[0]>>24)&0x3f;
510 int q = (c[0]&0xFFFFFF)>>6;
511 double p = *((AliHLTFloat32_t*)&c[1]);
512 double t = *((AliHLTFloat32_t*)&c[2]);
513 AliHLTFloat32_t p2 = *((AliHLTFloat32_t*)&c[3]);
514 AliHLTFloat32_t t2 = *((AliHLTFloat32_t*)&c[4]);
515 printf("N: %3d R: %3d C: %4d P: %7.4f T: %8.4f DP: %6.4f DT: %6.4f\n",
516 i/elsize+1, padRow, q, p, t, sqrt(fabs(p2-p*p)), sqrt(fabs(t2-t*t)));
518 if( outMC && outMC->fCount>0 ){
519 printf(" MC: (%3d,%6.1f) (%3d,%6.1f) (%3d,%6.1f)\n",
520 outMC->fLabels[i/elsize].fClusterID[0].fMCID,outMC->fLabels[i/elsize].fClusterID[0].fWeight,
521 outMC->fLabels[i/elsize].fClusterID[1].fMCID,outMC->fLabels[i/elsize].fClusterID[1].fWeight,
522 outMC->fLabels[i/elsize].fClusterID[2].fMCID,outMC->fLabels[i/elsize].fClusterID[2].fWeight
530 AliHLTUInt32_t outSize = headerSize + clustersSize32*sizeof(AliHLTUInt32_t);
532 if( size + outSize <= maxSize ){
534 memcpy( outputPtr, outBlock, outSize );
536 AliHLTComponentBlockData bd;
540 bd.fSpecification = iter->fSpecification;
541 bd.fDataType = AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC;
542 outputBlocks.push_back( bd );
543 fBenchmark.AddOutput(bd.fSize);
547 HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+outSize);
551 if( fDoMC && outMC && outMC->fCount>0 ){
552 int s = sizeof(AliHLTTPCClusterMCData) + outMC->fCount*sizeof(AliHLTTPCClusterMCLabel);
553 if( size + s <= maxSize ){
554 memcpy( outputPtr, outMC, s );
555 AliHLTComponentBlockData bdMCInfo;
556 FillBlockData( bdMCInfo );
557 bdMCInfo.fOffset = size;
559 bdMCInfo.fSpecification = iter->fSpecification;
560 bdMCInfo.fDataType = AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC;
561 outputBlocks.push_back( bdMCInfo );
562 fBenchmark.AddOutput(bdMCInfo.fSize);
563 size+=bdMCInfo.fSize;
564 outputPtr+=bdMCInfo.fSize;
566 HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+s);
576 HLTInfo(fBenchmark.GetStatistics());