1 //****************************************************************************
2 //* This file is property of and copyright by the ALICE HLT Project *
3 //* ALICE Experiment at CERN, All rights reserved. *
5 //* Primary Authors: Sergey Gorbunov, Torsten Alt *
6 //* Developers: Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de> *
7 //* Torsten Alt <talt@cern.ch> *
8 //* for The ALICE HLT Project. *
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 //****************************************************************************
19 // @file AliHLTTPCHWCFEmulatorComponent.cxx
20 // @author Sergey Gorbunov <sergey.gorbunov@fias.uni-frankfurt.de>
21 // @author Torsten Alt <talt@cern.ch>
22 // @brief HLT Component interface for for FPGA ClusterFinder Emulator for TPC
23 // @brief ( see AliHLTTPCHWCFEmulator class )
30 #include "AliHLTTPCHWCFEmulatorComponent.h"
32 #include "AliHLTTPCDefinitions.h"
33 #include "AliHLTTPCHWCFDataTypes.h"
34 #include "AliHLTTPCClusterMCData.h"
36 #include "AliGRPObject.h"
37 #include "AliCDBEntry.h"
38 #include "AliCDBManager.h"
39 #include "AliRawDataHeader.h"
43 #include "TObjString.h"
44 #include "TObjArray.h"
50 AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent()
57 fDoSinglePadSuppression(1),
59 fClusterLowerLimit(0),
64 fBenchmark("TPCHWClusterFinderEmulator")
66 // see header file for class documentation
68 // refer to README to build package
70 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
74 AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent(const AliHLTTPCHWCFEmulatorComponent&)
81 fDoSinglePadSuppression(1),
83 fClusterLowerLimit(0),
88 fBenchmark("TPCHWClusterFinderEmulator")
93 AliHLTTPCHWCFEmulatorComponent& AliHLTTPCHWCFEmulatorComponent::operator=(const AliHLTTPCHWCFEmulatorComponent&)
99 AliHLTTPCHWCFEmulatorComponent::~AliHLTTPCHWCFEmulatorComponent()
101 // see header file for class documentation
104 // Public functions to implement AliHLTComponent's interface.
105 // These functions are required for the registration process
107 const char* AliHLTTPCHWCFEmulatorComponent::GetComponentID()
109 // see header file for class documentation
110 return "TPCHWClusterFinderEmulator";
113 void AliHLTTPCHWCFEmulatorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
115 // see header file for class documentation
117 list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );
118 list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
121 AliHLTComponentDataType AliHLTTPCHWCFEmulatorComponent::GetOutputDataType()
123 // see header file for class documentation
124 return kAliHLTMultipleDataType;
127 int AliHLTTPCHWCFEmulatorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
129 // see header file for class documentation
131 tgtList.push_back(AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC );
132 tgtList.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
133 return tgtList.size();
137 void AliHLTTPCHWCFEmulatorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
139 // see header file for class documentation
140 // XXX TODO: Find more realistic values.
142 inputMultiplier = (6 * 0.4);
146 AliHLTComponent* AliHLTTPCHWCFEmulatorComponent::Spawn()
148 // see header file for class documentation
149 return new AliHLTTPCHWCFEmulatorComponent();
152 void AliHLTTPCHWCFEmulatorComponent::GetOCDBObjectDescription( TMap* const targetMap){
153 // Get a list of OCDB object description needed for the particular component
155 if (!targetMap) return;
157 // OCDB entries for component arguments
158 targetMap->Add(new TObjString("HLT/ConfigTPC/TPCHWClusterFinder"), new TObjString("component arguments, empty at the moment"));
162 int AliHLTTPCHWCFEmulatorComponent::DoInit( int argc, const char** argv )
164 // see header file for class documentation
166 TString arguments = "";
167 for ( int i = 0; i < argc; i++ ) {
168 if ( !arguments.IsNull() ) arguments += " ";
169 arguments += argv[i];
172 return Configure( NULL, NULL, arguments.Data() );
175 int AliHLTTPCHWCFEmulatorComponent::Reconfigure( const char* cdbEntry, const char* chainId )
177 // Reconfigure the component from OCDB
179 return Configure( cdbEntry, chainId, NULL );
182 int AliHLTTPCHWCFEmulatorComponent::ScanConfigurationArgument(int argc, const char** argv)
184 // see header file for class documentation
185 TString arguments = "";
186 for ( int i = 0; i < argc; i++ ) {
187 if ( !arguments.IsNull() ) arguments += " ";
188 arguments += argv[i];
190 return ReadConfigurationString(arguments);
195 void AliHLTTPCHWCFEmulatorComponent::SetDefaultConfiguration()
197 // Set default configuration for the FPGA ClusterFinder Emulator component
198 // Some parameters can be later overwritten from the OCDB
204 fDoSinglePadSuppression = 1;
206 fClusterLowerLimit = 0;
210 fBenchmark.SetTimer(0,"total");
211 fBenchmark.SetTimer(1,"reco");
214 int AliHLTTPCHWCFEmulatorComponent::ReadConfigurationString( const char* arguments )
216 // Set configuration parameters for the FPGA ClusterFinder Emulator component
220 if ( !arguments ) return iResult;
222 TString allArgs = arguments;
224 int bMissingParam = 0;
226 TObjArray* pTokens = allArgs.Tokenize( " " );
228 int nArgs = pTokens ? pTokens->GetEntries() : 0;
230 for ( int i = 0; i < nArgs; i++ ) {
231 argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
232 if ( argument.IsNull() ) continue;
234 if ( argument.CompareTo( "-deconvolute-time" ) == 0 ) {
235 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
236 fDoDeconvTime = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
237 HLTInfo( "Time deconvolution is set to: %d", fDoDeconvTime );
241 if ( argument.CompareTo( "-deconvolute-pad" ) == 0 ) {
242 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
243 fDoDeconvPad = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
244 HLTInfo( "Pad deconvolution is set to: %d", fDoDeconvPad );
248 if ( argument.CompareTo( "-deconvolute" ) == 0 ) {
249 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
250 fDoDeconvTime = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
251 fDoDeconvPad = fDoDeconvTime;
252 HLTInfo( "Time and pad deconvolution is set to: %d", fDoDeconvPad );
256 if ( argument.CompareTo( "-do-mc" ) == 0 ) {
257 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
258 fDoMC = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
259 HLTInfo( "MC processing is set to: %d", fDoMC );
263 if ( argument.CompareTo( "-flow-control" ) == 0 ) {
264 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
265 fDoFlowControl = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
266 HLTInfo( "Flow control is set to: %d", fDoFlowControl );
270 if ( argument.CompareTo( "-single-pad-suppression" ) == 0 ) {
271 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
272 fDoSinglePadSuppression = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
273 HLTInfo( "Single pad suppression is set to: %d", fDoSinglePadSuppression );
277 if ( argument.CompareTo( "-bypass-merger" ) == 0 ) {
278 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
279 fBypassMerger = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
280 HLTInfo( "Bypassing merger is set to: %d", fBypassMerger );
284 if ( argument.CompareTo( "-cluster-lower-limit" ) == 0 ) {
285 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
286 fClusterLowerLimit = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
287 HLTInfo( "Cluster lower limit is set to: %d", fClusterLowerLimit );
291 if ( argument.CompareTo( "-single-sequence-limit" ) == 0 ) {
292 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
293 fSingleSeqLimit = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
294 HLTInfo( "Single sequence limit is set to: %d", fSingleSeqLimit );
298 if ( argument.CompareTo( "-debug-level" ) == 0 ) {
299 if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
300 fDebug = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
301 HLTInfo( "Debug level is set to: %d", fDebug );
305 HLTError( "Unknown option \"%s\"", argument.Data() );
310 if ( bMissingParam ) {
311 HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
319 int AliHLTTPCHWCFEmulatorComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
321 // Read configuration from OCDB
323 const char* defaultNotify = "";
326 cdbEntry = "HLT/ConfigTPC/TPCHWClusterFinder";
327 defaultNotify = " (default)";
331 HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
332 AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
335 HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
339 TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
342 HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
346 HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
348 return ReadConfigurationString( pString->GetString().Data() );
352 int AliHLTTPCHWCFEmulatorComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
354 // Configure the component
355 // There are few levels of configuration,
356 // parameters which are set on one step can be overwritten on the next step
358 //* read hard-coded values
360 SetDefaultConfiguration();
362 //* read the default CDB entry
364 int iResult1 = ReadCDBEntry( NULL, chainId );
366 //* read the actual CDB entry if required
368 int iResult2 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
370 //* read extra parameters from input (if they are)
374 if ( commandLine && commandLine[0] != '\0' ) {
375 HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
376 iResult3 = ReadConfigurationString( commandLine );
379 if( fDebug>1 ) fCFEmulator.SetDebugLevel( fDebug );
380 else fCFEmulator.SetDebugLevel(0);
382 return iResult1 ? iResult1 : ( iResult2 ? iResult2 : iResult3 );
386 int AliHLTTPCHWCFEmulatorComponent::DoDeinit()
388 // see header file for class documentation
393 int AliHLTTPCHWCFEmulatorComponent::DoEvent( const AliHLTComponentEventData& evtData,
394 const AliHLTComponentBlockData* blocks,
395 AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr,
396 AliHLTUInt32_t& size,
397 vector<AliHLTComponentBlockData>& outputBlocks )
399 // see header file for class documentation
402 AliHLTUInt32_t maxSize = size;
409 fBenchmark.StartNewEvent();
412 AliHLTUInt32_t configWord = AliHLTTPCHWCFEmulator::CreateConfiguration
413 ( fDoDeconvTime, fDoDeconvPad, fDoFlowControl, fDoSinglePadSuppression, fBypassMerger, fClusterLowerLimit, fSingleSeqLimit );
415 for ( unsigned long ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
417 const AliHLTComponentBlockData* iter = blocks+ndx;
419 if ( iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC)
420 && iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
422 int slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
423 int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
425 const char *str=Form("slice %d patch %d:", slice, patch);
427 fBenchmark.AddInput(iter->fSize);
429 if (!iter->fPtr) continue;
431 // create input block for the HW cluster finder
433 const AliHLTUInt32_t *rawEvent=0;
434 const AliHLTTPCClusterMCLabel *mcLabels = 0;
435 AliHLTUInt32_t rawEventSize32 = 0;
436 AliHLTUInt32_t nMCLabels = 0;
438 if( fCFSupport.CreateRawEvent( iter, rawEvent, rawEventSize32, mcLabels, nMCLabels )<0 ) continue;
444 // book memory for the output
446 AliHLTUInt32_t maxNClusters = rawEventSize32 + 1; // N 32-bit words in input
447 AliHLTUInt32_t clustersSize32 = maxNClusters*5;
448 AliHLTUInt32_t nOutputMC = maxNClusters;
450 AliHLTUInt32_t headerSize = sizeof(AliRawDataHeader);
451 AliHLTUInt8_t *outBlock = new AliHLTUInt8_t[ headerSize+clustersSize32*sizeof(AliHLTUInt32_t) ];
453 AliHLTTPCClusterMCData *outMC = reinterpret_cast<AliHLTTPCClusterMCData *>(new AliHLTTPCClusterMCLabel[nOutputMC+1]);
455 if( !outBlock || !outMC ){
456 HLTWarning("%s Not enouth memory!!!", str);
462 // fill CDH header here, since the HW clusterfinder does not receive it
464 AliRawDataHeader *cdhHeader = reinterpret_cast<AliRawDataHeader*>(iter->fPtr);
465 AliRawDataHeader *outCDHHeader = reinterpret_cast<AliRawDataHeader*>(outBlock);
466 *outCDHHeader = *cdhHeader;
467 outCDHHeader->fSize = 0xFFFFFFFF;
469 AliHLTUInt32_t *outClusters = reinterpret_cast<AliHLTUInt32_t*> (outBlock + headerSize);
473 ( fCFSupport.GetMapping(slice,patch), configWord );
475 int err = fCFEmulator.FindClusters( rawEvent, rawEventSize32,
476 outClusters, clustersSize32,
480 if( err==-1 ){ HLTWarning("NULL input pointer (warning %d)",err);}
481 else if( err==-2 ){ HLTWarning("No space left in the output buffer (warning %d)",err); }
482 else if( err<0 ){ HLTWarning("HWCF emulator finished with error code %d",err); }
490 printf("\nHWCF Emulator: output clusters for slice%d patch %d:\n",slice,patch);
491 for( AliHLTUInt32_t i=0; i<clustersSize32; i+=5 ){
492 AliHLTUInt32_t *c = outClusters+i;
493 AliHLTUInt32_t flag = (c[0]>>30);
494 if( flag == 0x3){ //beginning of a cluster
495 int padRow = (c[0]>>24)&0x3f;
496 int q = (c[0]&0xFFFFFF)>>6;
497 double p = *((AliHLTFloat32_t*)&c[1]);
498 double t = *((AliHLTFloat32_t*)&c[2]);
499 AliHLTFloat32_t p2 = *((AliHLTFloat32_t*)&c[3]);
500 AliHLTFloat32_t t2 = *((AliHLTFloat32_t*)&c[4]);
501 printf("N: %3d R: %3d C: %4d P: %7.4f T: %8.4f DP: %6.4f DT: %6.4f\n",
502 i/5+1, padRow, q, p, t, sqrt(fabs(p2-p*p)), sqrt(fabs(t2-t*t)));
504 if( outMC && outMC->fCount>0 ){
505 printf(" MC: (%3d,%6.1f) (%3d,%6.1f) (%3d,%6.1f)\n",
506 outMC->fLabels[i/5].fClusterID[0].fMCID,outMC->fLabels[i/5].fClusterID[0].fWeight,
507 outMC->fLabels[i/5].fClusterID[1].fMCID,outMC->fLabels[i/5].fClusterID[1].fWeight,
508 outMC->fLabels[i/5].fClusterID[2].fMCID,outMC->fLabels[i/5].fClusterID[2].fWeight
516 AliHLTUInt32_t outSize = headerSize + clustersSize32*sizeof(AliHLTUInt32_t);
518 if( size + outSize <= maxSize ){
520 memcpy( outputPtr, outBlock, outSize );
522 AliHLTComponentBlockData bd;
526 bd.fSpecification = iter->fSpecification;
527 bd.fDataType = AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC;
528 outputBlocks.push_back( bd );
529 fBenchmark.AddOutput(bd.fSize);
533 HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+outSize);
537 if( fDoMC && outMC && outMC->fCount>0 ){
538 int s = sizeof(AliHLTTPCClusterMCData) + outMC->fCount*sizeof(AliHLTTPCClusterMCLabel);
539 if( size + s <= maxSize ){
540 memcpy( outputPtr, outMC, s );
541 AliHLTComponentBlockData bdMCInfo;
542 FillBlockData( bdMCInfo );
543 bdMCInfo.fOffset = size;
545 bdMCInfo.fSpecification = iter->fSpecification;
546 bdMCInfo.fDataType = AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC;
547 outputBlocks.push_back( bdMCInfo );
548 fBenchmark.AddOutput(bdMCInfo.fSize);
549 size+=bdMCInfo.fSize;
550 outputPtr+=bdMCInfo.fSize;
552 HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+s);
562 HLTInfo(fBenchmark.GetStatistics());