]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/HWCFemulator/AliHLTTPCHWCFEmulatorComponent.cxx
Gain calibration added to the HWCF emulation
[u/mrichter/AliRoot.git] / HLT / TPCLib / HWCFemulator / AliHLTTPCHWCFEmulatorComponent.cxx
1 //****************************************************************************
2 //* This file is property of and copyright by the ALICE HLT Project          * 
3 //* ALICE Experiment at CERN, All rights reserved.                           *
4 //*                                                                          *
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.                              *
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 //  @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 )
24 //  @note
25
26
27 #if __GNUC__>= 3
28 using namespace std;
29 #endif
30 #include "AliHLTTPCHWCFEmulatorComponent.h"
31
32 #include "AliHLTTPCDefinitions.h"
33 #include "AliHLTTPCHWCFDataTypes.h"
34 #include "AliHLTTPCClusterMCData.h"
35
36 #include "AliGRPObject.h"
37 #include "AliCDBEntry.h"
38 #include "AliCDBManager.h"
39 #include "AliRawDataHeader.h"
40 #include <cstdlib>
41 #include <cerrno>
42 #include "TString.h"
43 #include "TObjString.h"
44 #include "TObjArray.h"
45
46
47 #include <sys/time.h>
48 #include "TFile.h"
49
50 AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent()
51   :
52   AliHLTProcessor(),
53   fDoDeconvTime(1),
54   fDoDeconvPad(1),
55   fDoMC(1),
56   fDoFlowControl(0),
57   fDoSinglePadSuppression(1),
58   fBypassMerger(0),
59   fClusterLowerLimit(0),
60   fSingleSeqLimit(0),
61   fDebug(0),
62   fCFSupport(),
63   fCFEmulator(),
64   fBenchmark("TPCHWClusterFinderEmulator")
65 {
66   // see header file for class documentation
67   // or
68   // refer to README to build package
69   // or
70   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
71 }
72
73
74 AliHLTTPCHWCFEmulatorComponent::AliHLTTPCHWCFEmulatorComponent(const AliHLTTPCHWCFEmulatorComponent&)
75   :
76   AliHLTProcessor(),
77   fDoDeconvTime(1),
78   fDoDeconvPad(1),
79   fDoMC(1),
80   fDoFlowControl(0),
81   fDoSinglePadSuppression(1),
82   fBypassMerger(0),
83   fClusterLowerLimit(0),
84   fSingleSeqLimit(0),
85   fDebug(0),
86   fCFSupport(),
87   fCFEmulator(),
88   fBenchmark("TPCHWClusterFinderEmulator")
89 {
90   // dummy
91 }
92
93 AliHLTTPCHWCFEmulatorComponent& AliHLTTPCHWCFEmulatorComponent::operator=(const AliHLTTPCHWCFEmulatorComponent&)
94 {
95   // dummy
96   return *this;
97 }
98
99 AliHLTTPCHWCFEmulatorComponent::~AliHLTTPCHWCFEmulatorComponent()
100 {
101   // see header file for class documentation
102 }
103
104 // Public functions to implement AliHLTComponent's interface.
105 // These functions are required for the registration process
106
107 const char* AliHLTTPCHWCFEmulatorComponent::GetComponentID()
108 {
109   // see header file for class documentation
110   return "TPCHWClusterFinderEmulator";
111 }
112
113 void AliHLTTPCHWCFEmulatorComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
114 {
115   // see header file for class documentation
116   list.clear();
117   list.push_back( AliHLTTPCDefinitions::fgkUnpackedRawDataType );        
118   list.push_back( kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC );
119 }
120
121 AliHLTComponentDataType AliHLTTPCHWCFEmulatorComponent::GetOutputDataType()
122 {
123   // see header file for class documentation
124   return kAliHLTMultipleDataType;
125 }
126
127 int AliHLTTPCHWCFEmulatorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
128 {
129   // see header file for class documentation
130   tgtList.clear();
131   tgtList.push_back(AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC );
132   tgtList.push_back(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
133   return tgtList.size();
134 }
135
136
137 void AliHLTTPCHWCFEmulatorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
138 {
139   // see header file for class documentation
140   // XXX TODO: Find more realistic values.  
141   constBase = 0;
142   inputMultiplier = (6 * 0.4);
143 }
144
145
146 AliHLTComponent* AliHLTTPCHWCFEmulatorComponent::Spawn()
147 {
148   // see header file for class documentation
149   return new AliHLTTPCHWCFEmulatorComponent();
150 }
151
152 void AliHLTTPCHWCFEmulatorComponent::GetOCDBObjectDescription( TMap* const targetMap){
153 // Get a list of OCDB object description needed for the particular component
154   
155   if (!targetMap) return;
156   
157   // OCDB entries for component arguments
158   targetMap->Add(new TObjString("HLT/ConfigTPC/TPCHWClusterFinder"), new TObjString("component arguments, empty at the moment"));
159 }
160
161
162 int AliHLTTPCHWCFEmulatorComponent::DoInit( int argc, const char** argv )
163 {
164   // see header file for class documentation
165
166   TString arguments = "";
167   for ( int i = 0; i < argc; i++ ) {
168     if ( !arguments.IsNull() ) arguments += " ";
169     arguments += argv[i];
170   }
171
172   return Configure( NULL, NULL, arguments.Data()  );
173 }
174
175 int AliHLTTPCHWCFEmulatorComponent::Reconfigure( const char* cdbEntry, const char* chainId )
176 {
177   // Reconfigure the component from OCDB
178
179   return Configure( cdbEntry, chainId, NULL );
180 }
181
182 int AliHLTTPCHWCFEmulatorComponent::ScanConfigurationArgument(int argc, const char** argv)
183 {
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];
189   }
190   return ReadConfigurationString(arguments);
191 }
192
193
194
195 void AliHLTTPCHWCFEmulatorComponent::SetDefaultConfiguration()
196 {
197   // Set default configuration for the FPGA ClusterFinder Emulator component
198   // Some parameters can be later overwritten from the OCDB
199
200   fDoDeconvTime = 0;
201   fDoDeconvPad = 0;
202   fDoMC = 1;
203   fDoFlowControl = 0;
204   fDoSinglePadSuppression = 1;
205   fBypassMerger = 0;
206   fClusterLowerLimit = 0;
207   fSingleSeqLimit = 0;
208   fDebug = 0;
209   fBenchmark.Reset();
210   fBenchmark.SetTimer(0,"total");
211   fBenchmark.SetTimer(1,"reco");    
212 }
213
214 int AliHLTTPCHWCFEmulatorComponent::ReadConfigurationString(  const char* arguments )
215 {
216   // Set configuration parameters for the FPGA ClusterFinder Emulator component
217   // from the string
218
219   int iResult = 0;
220   if ( !arguments ) return iResult;
221
222   TString allArgs = arguments;
223   TString argument;
224   int bMissingParam = 0;
225
226   TObjArray* pTokens = allArgs.Tokenize( " " );
227
228   int nArgs =  pTokens ? pTokens->GetEntries() : 0;
229
230   for ( int i = 0; i < nArgs; i++ ) {
231     argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
232     if ( argument.IsNull() ) continue;
233
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 );
238       continue;
239     }
240
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 );
245       continue;
246     }
247
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 );
253       continue;
254     }
255  
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 );
260       continue;
261     }
262
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 );
267       continue;
268     }
269
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 );
274       continue;
275     }
276     
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 );
281       continue;
282     }
283
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 );
288       continue;
289     }
290
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 );
295       continue;
296     }
297     
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 );
302       continue;
303     }
304     
305     HLTError( "Unknown option \"%s\"", argument.Data() );
306     iResult = -EINVAL;
307   }
308   delete pTokens;
309
310   if ( bMissingParam ) {
311     HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
312     iResult = -EINVAL;
313   }
314
315   return iResult;
316 }
317
318
319 int AliHLTTPCHWCFEmulatorComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
320 {
321   // Read configuration from OCDB
322
323   const char* defaultNotify = "";
324
325   if ( !cdbEntry ){
326     cdbEntry = "HLT/ConfigTPC/TPCHWClusterFinder";
327     defaultNotify = " (default)";
328     chainId = 0;
329   }
330
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());
333   
334   if ( !pEntry ) {
335     HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
336     return -EINVAL;
337   }
338
339   TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
340
341   if ( !pString ) {
342     HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
343     return -EINVAL;
344   }
345
346   HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
347
348   return  ReadConfigurationString( pString->GetString().Data() );
349 }
350
351
352 int AliHLTTPCHWCFEmulatorComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
353 {
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
357
358   //* read hard-coded values
359
360   SetDefaultConfiguration();
361
362   //* read the default CDB entry
363
364   int iResult1 = ReadCDBEntry( NULL, chainId );
365
366   //* read the actual CDB entry if required
367
368   int iResult2 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
369
370   //* read extra parameters from input (if they are)
371
372   int iResult3 = 0;
373
374   if ( commandLine && commandLine[0] != '\0' ) {
375     HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
376     iResult3 = ReadConfigurationString( commandLine );
377   }
378   
379   if( fDebug>1 ) fCFEmulator.SetDebugLevel( fDebug );
380   else fCFEmulator.SetDebugLevel(0);
381
382   return iResult1 ? iResult1 : ( iResult2 ? iResult2 : iResult3 );
383 }
384
385
386 int AliHLTTPCHWCFEmulatorComponent::DoDeinit()
387 {
388   // see header file for class documentation 
389   return 0;
390 }
391
392
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 )
398 {
399   // see header file for class documentation
400
401   int iResult=0;
402   AliHLTUInt32_t maxSize = size;
403   size = 0;
404   
405   if(!IsDataEvent()){
406     return 0;
407   }
408
409   fBenchmark.StartNewEvent();
410   fBenchmark.Start(0);
411
412   AliHLTUInt32_t configWord = AliHLTTPCHWCFEmulator::CreateConfiguration
413     ( fDoDeconvTime, fDoDeconvPad, fDoFlowControl, fDoSinglePadSuppression, fBypassMerger, fClusterLowerLimit, fSingleSeqLimit );
414
415   for ( unsigned long ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
416     {
417       const AliHLTComponentBlockData* iter = blocks+ndx;
418       
419       if (  iter->fDataType != (kAliHLTDataTypeDDLRaw | kAliHLTDataOriginTPC) 
420             &&  iter->fDataType != AliHLTTPCDefinitions::fgkUnpackedRawDataType ) continue;
421
422       int slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
423       int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
424  
425       const char *str=Form("slice %d patch %d:", slice, patch);
426
427       fBenchmark.AddInput(iter->fSize);
428  
429       if (!iter->fPtr) continue;
430  
431       // create input block for the HW cluster finder
432
433       const AliHLTUInt32_t *rawEvent=0;
434       const AliHLTTPCClusterMCLabel *mcLabels = 0;
435       AliHLTUInt32_t rawEventSize32 = 0;
436       AliHLTUInt32_t nMCLabels = 0;
437
438       if( fCFSupport.CreateRawEvent( iter, rawEvent, rawEventSize32, mcLabels, nMCLabels )<0 ) continue; 
439       if( !fDoMC ){
440         mcLabels = 0;
441         nMCLabels = 0;
442       }
443
444       // book memory for the output
445       
446       AliHLTUInt32_t maxNClusters = rawEventSize32 + 1; // N 32-bit words in input
447       AliHLTUInt32_t clustersSize32 = maxNClusters*5;
448       AliHLTUInt32_t nOutputMC = maxNClusters;
449
450       AliHLTUInt32_t headerSize = sizeof(AliRawDataHeader);                   
451       AliHLTUInt8_t *outBlock = new AliHLTUInt8_t[ headerSize+clustersSize32*sizeof(AliHLTUInt32_t) ];
452       
453       AliHLTTPCClusterMCData *outMC = reinterpret_cast<AliHLTTPCClusterMCData *>(new AliHLTTPCClusterMCLabel[nOutputMC+1]);
454       
455       if( !outBlock || !outMC ){
456         HLTWarning("%s Not enouth memory!!!", str);
457         delete[] outBlock;
458         delete[] outMC;
459         continue;       
460       }
461       
462       // fill CDH header here, since the HW clusterfinder does not receive it
463       
464       AliRawDataHeader *cdhHeader = reinterpret_cast<AliRawDataHeader*>(iter->fPtr);
465       AliRawDataHeader *outCDHHeader = reinterpret_cast<AliRawDataHeader*>(outBlock);      
466       *outCDHHeader = *cdhHeader;
467       outCDHHeader->fSize = 0xFFFFFFFF;
468
469       AliHLTUInt32_t *outClusters = reinterpret_cast<AliHLTUInt32_t*> (outBlock + headerSize);
470      
471       fBenchmark.Start(1);
472       fCFEmulator.Init
473         ( fCFSupport.GetMapping(slice,patch), configWord );
474       
475       int err = fCFEmulator.FindClusters( rawEvent, rawEventSize32, 
476                                           outClusters, clustersSize32, 
477                                           mcLabels, nMCLabels,
478                                           outMC );
479       fBenchmark.Stop(1);
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); }
483       if( err<0 ){
484         delete[] outBlock;
485         delete[] outMC;
486         continue;
487       }
488
489       if( fDebug ){
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)));
503
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
509                      );
510             }
511           }
512         }
513       }
514           
515
516       AliHLTUInt32_t outSize = headerSize + clustersSize32*sizeof(AliHLTUInt32_t);
517       
518       if( size + outSize <= maxSize ){
519         
520         memcpy( outputPtr, outBlock, outSize );
521         
522         AliHLTComponentBlockData bd;
523         FillBlockData( bd );
524         bd.fOffset = size;
525         bd.fSize = outSize;
526         bd.fSpecification = iter->fSpecification;
527         bd.fDataType = AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC;
528         outputBlocks.push_back( bd );
529         fBenchmark.AddOutput(bd.fSize);
530         size+= bd.fSize;
531         outputPtr+=bd.fSize;
532       } else {
533         HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+outSize);
534         iResult=-ENOSPC;
535       }
536
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;
544           bdMCInfo.fSize = s;
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; 
551         } else {        
552           HLTWarning( "Output buffer (%db) is too small, required %db", maxSize, size+s);
553           iResult=-ENOSPC;          
554         }
555       }
556       
557       delete[] outBlock;
558       delete[] outMC;      
559     }
560   
561   fBenchmark.Stop(0);  
562   HLTInfo(fBenchmark.GetStatistics());
563   return iResult;
564 }
565
566