4ffc7c5072c7a5f29f8e8fde61574fdc36d01c2c
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCHWClusterDecoderComponent.cxx
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 "AliHLTTPCTransform.h"
29 #include "AliHLTTPCDefinitions.h"
30 #include "AliHLTTPCSpacePointData.h"
31 #include "AliHLTTPCClusterDataFormat.h"
32 #include "AliRawDataHeader.h"
33 #include "AliHLTTPCRawCluster.h"
34 #include "AliHLTTPCHWCFEmulator.h"
35 #include "AliHLTTPCHWCFData.h"
36 #include "AliHLTErrorGuard.h"
37 #include "AliHLTTPCRawClustersDescriptor.h"
38
39 #include "AliCDBManager.h"
40 #include "AliCDBEntry.h"
41
42 #include "TMath.h"
43 #include "TObjString.h" 
44 #include <cstdlib>
45 #include <cerrno>
46 #include <sys/time.h>
47
48 using namespace std;
49
50 ClassImp(AliHLTTPCHWClusterDecoderComponent) //ROOT macro for the implementation of ROOT specific class methods
51
52 const char* AliHLTTPCHWClusterDecoderComponent::fgkOCDBEntry="HLT/ConfigTPC/TPCHWClusterDecoder";
53
54
55 AliHLTTPCHWClusterDecoderComponent::AliHLTTPCHWClusterDecoderComponent()
56 :
57 fpDecoder(NULL),
58 fpClusterMerger(NULL),
59 fDoMerge(1),
60 fBenchmark("HWClusterDecoder")
61 {
62   // see header file for class documentation
63   // or
64   // refer to README to build package
65   // or
66   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt  
67
68   fBenchmark.Reset();
69   fBenchmark.SetTimer(0,"total");
70 }
71
72 AliHLTTPCHWClusterDecoderComponent::~AliHLTTPCHWClusterDecoderComponent()
73
74   // destructor
75   delete fpDecoder;
76   delete fpClusterMerger;
77 }
78
79 const char* AliHLTTPCHWClusterDecoderComponent::GetComponentID() 
80
81   // see header file for class documentation
82   return "TPCHWClusterDecoder";
83 }
84
85
86
87 void AliHLTTPCHWClusterDecoderComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) { 
88   // see header file for class documentation
89
90   list.clear(); 
91   list.push_back( AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC  );
92   list.push_back( AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
93 }
94
95 AliHLTComponentDataType AliHLTTPCHWClusterDecoderComponent::GetOutputDataType() { 
96   // see header file for class documentation
97
98   return kAliHLTMultipleDataType;
99 }
100
101 int AliHLTTPCHWClusterDecoderComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) { 
102   // see header file for class documentation
103
104   tgtList.clear();
105   tgtList.push_back( AliHLTTPCDefinitions::fgkRawClustersDataType  | kAliHLTDataOriginTPC );
106   tgtList.push_back( AliHLTTPCDefinitions::RawClustersDescriptorDataType() );
107   tgtList.push_back( AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC );
108   return tgtList.size();
109 }
110
111 void AliHLTTPCHWClusterDecoderComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) { 
112   // see header file for class documentation
113   constBase = 0;
114   inputMultiplier = 2.0;
115 }
116
117 AliHLTComponent* AliHLTTPCHWClusterDecoderComponent::Spawn() { 
118   // see header file for class documentation
119
120   return new AliHLTTPCHWClusterDecoderComponent();
121 }
122         
123 int AliHLTTPCHWClusterDecoderComponent::DoInit( int argc, const char** argv ) 
124
125   // see header file for class documentation
126   
127   int iResult=0;
128
129   fpDecoder=new AliHLTTPCHWCFData;
130   if (!fpDecoder) iResult=-ENOMEM;
131   
132   fDoMerge = 1;
133
134   //!! if (iResult>=0) iResult = ConfigureFromCDBTObjString(fgkOCDBEntry);
135
136   if (iResult>=0 && argc>0) iResult = ConfigureFromArgumentString(argc, argv);
137
138   if ( iResult>=0 ) iResult = InitClusterMerger();  
139   
140   return iResult;
141 } // end DoInit()
142
143 int AliHLTTPCHWClusterDecoderComponent::DoDeinit() { 
144   // see header file for class documentation   
145   if (!fpDecoder) delete fpDecoder;
146   fpDecoder=NULL;
147   delete fpClusterMerger;
148   fpClusterMerger = NULL;
149   return 0;
150 }
151
152 int AliHLTTPCHWClusterDecoderComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/) { 
153   // see header file for class documentation
154
155   fDoMerge = 1;
156   int iResult = 0;
157   //!! iResult = ConfigureFromCDBTObjString(fgkOCDBEntry);
158   if ( iResult>=0 ) iResult = InitClusterMerger();  
159   return iResult;
160 }
161
162 int AliHLTTPCHWClusterDecoderComponent::ScanConfigurationArgument(int argc, const char** argv){
163
164   // see header file for class documentation
165
166   if (argc<=0) return 0;
167   int i=0;
168   TString argument=argv[i];
169
170   if (argument.CompareTo("-do-merge")==0){
171     fDoMerge = 1;
172     return 1;
173   }
174
175   if (argument.CompareTo("-do-not-merge")==0){
176     fDoMerge = 0;
177     return 1;
178   }
179
180   // unknown argument
181   return -EINVAL;
182 }
183
184 int AliHLTTPCHWClusterDecoderComponent::InitClusterMerger()
185 {
186   //
187   // init merger
188   //
189   int iResult = 0;
190   if ( fDoMerge && !fpClusterMerger) {
191     fpClusterMerger = new AliHLTTPCHWClusterMergerV1;
192     if( !fpClusterMerger ) iResult=-ENOMEM;
193     else iResult = fpClusterMerger->Init();
194     if( iResult<0 ){
195       HLTError("Can not initialise cluster merger");
196       delete fpClusterMerger;
197       fpClusterMerger = 0;
198     }
199   }
200   return iResult;
201 }
202
203 void AliHLTTPCHWClusterDecoderComponent::GetOCDBObjectDescription( TMap* const targetMap)
204 {
205   // Get a list of OCDB object description needed for the particular component
206   if (!targetMap) return;
207   
208   // OCDB entries for component arguments
209
210   //!! targetMap->Add(new TObjString(fgkOCDBEntry), new TObjString("component argument for HW cluster decoder"));  
211 }
212
213
214 int AliHLTTPCHWClusterDecoderComponent::DoEvent(const AliHLTComponentEventData& evtData, 
215                                                   const AliHLTComponentBlockData* blocks, 
216                                                   AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
217                                                   AliHLTUInt32_t& size, 
218                                                   vector<AliHLTComponentBlockData>& outputBlocks ){
219   // see header file for class documentation
220  
221   UInt_t maxOutSize = size;
222   size = 0;
223   int iResult = 0;
224   if(!IsDataEvent()) return 0;
225
226   if (!fpDecoder) return -ENODEV;
227
228   fBenchmark.StartNewEvent();
229   fBenchmark.Start(0);
230   
231   AliHLTUInt8_t* origOutputPtr = outputPtr;
232   UInt_t origOutputBlocksSize = outputBlocks.size();
233
234   bool isInputPresent = kFALSE;
235
236   for( unsigned long ndx=0; ndx<evtData.fBlockCnt; ndx++ ){
237      
238     const AliHLTComponentBlockData *iter   = blocks+ndx;
239     
240     fBenchmark.AddInput(iter->fSize);
241     
242     HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",
243              evtData.fEventID, evtData.fEventID, 
244              DataType2Text( iter->fDataType).c_str(), 
245              DataType2Text(AliHLTTPCDefinitions::fgkHWClustersDataType).c_str());                       
246  
247     if(iter->fDataType == (AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC) ){
248       // simply forward MC labels
249       
250       if( size+iter->fSize > maxOutSize ){
251         HLTWarning( "Output buffer (%db) is too small, required %db", maxOutSize, size+iter->fSize);
252         iResult  = -ENOSPC;
253         break;
254       }
255
256       memcpy( outputPtr, iter->fPtr, iter->fSize );
257       
258       AliHLTComponentBlockData bd;
259       FillBlockData( bd );
260       bd.fOffset = size;
261       bd.fSize = iter->fSize;      
262       bd.fSpecification = iter->fSpecification;     
263       bd.fDataType = iter->fDataType;
264       outputBlocks.push_back( bd );           
265       size   += bd.fSize;
266       outputPtr += bd.fSize;
267       fBenchmark.AddOutput(bd.fSize);    
268       continue;
269     }
270
271     if( iter->fDataType == (AliHLTTPCDefinitions::fgkHWClustersDataType | kAliHLTDataOriginTPC) ){
272
273       isInputPresent = 1;
274
275       HLTDebug("minSlice: %d, minPartition: %d", AliHLTTPCDefinitions::GetMinSliceNr(*iter), AliHLTTPCDefinitions::GetMinPatchNr(*iter));     
276       
277       long maxRawClusters = ((long)maxOutSize-size-sizeof(AliHLTTPCRawClusterData))/sizeof(AliHLTTPCRawCluster);
278        
279       if( maxRawClusters<=0 ) {
280         HLTWarning("No more space to add raw clusters, exiting!");
281         iResult  = -ENOSPC;
282         continue;
283       }       
284
285       // copy raw cluster data from input
286          
287       AliHLTTPCRawClusterData* outputRaw= (AliHLTTPCRawClusterData*)(outputPtr);
288        
289       outputRaw->fVersion = 0;
290       outputRaw->fCount = 0;
291       
292       AliHLTUInt32_t *buffer = (AliHLTUInt32_t*)iter->fPtr;  
293      
294       // skip the first 8 32-bit CDH words
295       buffer += 8;
296       UInt_t bufferSize32 = ((Int_t)iter->fSize - sizeof(AliRawDataHeader) )/sizeof(AliHLTUInt32_t);
297       
298       if (fpDecoder->Init(reinterpret_cast<AliHLTUInt8_t*>(buffer), bufferSize32*sizeof(AliHLTUInt32_t))>=0 && fpDecoder->CheckVersion()>=0) {
299         
300         for (AliHLTTPCHWCFData::iterator cl=fpDecoder->begin(); cl!=fpDecoder->end(); ++cl) {
301              
302           if(outputRaw->fCount>=maxRawClusters){
303             HLTWarning("No more space to add clusters, exiting!");
304             iResult  = -ENOSPC;
305             break;
306           }
307           AliHLTTPCRawCluster &c = outputRaw->fClusters[outputRaw->fCount];       
308           c.SetPadRow(cl.GetPadRow());
309           c.SetCharge(cl.GetCharge());
310           c.SetPad(cl.GetPad());  
311           c.SetTime(cl.GetTime());
312           c.SetSigmaY2(cl.GetSigmaY2());
313           c.SetSigmaZ2(cl.GetSigmaZ2());
314           c.SetQMax(cl.GetQMax());        
315           outputRaw->fCount++;
316         }       
317         
318         // fill into HLT output data
319         AliHLTComponentBlockData bdRawClusters;
320         FillBlockData( bdRawClusters );
321         bdRawClusters.fOffset = size;   
322         bdRawClusters.fSize = sizeof(AliHLTTPCRawClusterData)+outputRaw->fCount*sizeof(AliHLTTPCRawCluster);
323         bdRawClusters.fSpecification = iter->fSpecification;
324         bdRawClusters.fDataType = AliHLTTPCDefinitions::fgkRawClustersDataType | kAliHLTDataOriginTPC;
325         outputBlocks.push_back( bdRawClusters );
326         fBenchmark.AddOutput(bdRawClusters.fSize);
327         size   += bdRawClusters.fSize;
328         outputPtr += bdRawClusters.fSize;
329       }    
330       continue; // HW clusters data block
331     }
332
333   } // end of loop over data blocks  
334
335   AliHLTTPCRawClustersDescriptor desc; 
336   desc.SetMergedClustersFlag(0);
337
338   if( fDoMerge && fpClusterMerger ){
339     fpClusterMerger->Clear();
340     fpClusterMerger->SetDataPointer(origOutputPtr);
341     for( UInt_t i=origOutputBlocksSize; i<outputBlocks.size(); i++){
342       fpClusterMerger->SetDataBlock(&(outputBlocks[i]));
343     }
344     int nMerged = fpClusterMerger->Merge();
345     fpClusterMerger->Clear();
346     desc.SetMergedClustersFlag(1);
347     HLTInfo("Merged %d clusters",nMerged);   
348   }
349
350   // Write header block 
351   if( isInputPresent ){
352     AliHLTComponent_BlockData bd;
353     FillBlockData(bd);
354     bd.fOffset        = size;
355     bd.fSize          = sizeof(AliHLTTPCRawClustersDescriptor);
356     bd.fDataType      = AliHLTTPCDefinitions::RawClustersDescriptorDataType();
357     if( maxOutSize < size + bd.fSize ){
358         HLTWarning( "Output buffer (%db) is too small, required %db", maxOutSize, size+bd.fSize);
359         iResult  = -ENOSPC;
360         return iResult;
361     }    
362     *(AliHLTTPCRawClustersDescriptor*)(outputPtr ) = desc;
363     outputBlocks.push_back(bd);
364     size += bd.fSize;
365     outputPtr += bd.fSize;
366     fBenchmark.AddOutput(bd.fSize);    
367     HLTBenchmark("header data block of size %d", bd.fSize);
368   }
369   fBenchmark.Stop(0);
370   HLTInfo(fBenchmark.GetStatistics());
371   
372   return iResult;
373 } // end DoEvent()
374
375
376
377 void AliHLTTPCHWClusterDecoderComponent::PrintDebug(AliHLTUInt32_t *buffer, Int_t size){
378 // see header file for class documentation 
379
380   HLTInfo("The size is: %d", size);
381   for(Int_t n32bit=0; n32bit<size; n32bit++){
382     
383     AliHLTUInt8_t *wordPtr = reinterpret_cast<AliHLTUInt8_t*>(&buffer[n32bit]);
384     //    cout << "word ptr initialized"<<endl;
385     for(Int_t w=3;w>=0;w--){
386       //     cout <<"accessing word"<<endl;
387       AliHLTUInt8_t word = wordPtr[w];
388       //     cout<< "word was accessed"<<endl; 
389       for(int n=7; n>=0; n--){
390         //print the byte values
391         if((((word>>n)<<7)&0x80) != 0){
392           printf("1");
393         }
394         else{
395           printf("0");
396         }
397       }
398       printf("  ");
399     }
400     printf("\n");
401   }
402 } // end of PrintDebug
403