correcting printf format specifiers
[u/mrichter/AliRoot.git] / HLT / comp / AliHLTCOMPHuffmanAltroComponent.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * All rights reserved.                                                   *
6  *                                                                        *
7  * Primary Author: Jenny Wagner  (jwagner@cern.ch)                        *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          * 
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 /** @file   AliHLTCOMPHuffmanAltroComponent.cxx
19     @author Jenny Wagner
20     @date   29-08-2007
21     @brief  The Huffman compressor component.
22 */
23
24 #if __GNUC__>= 3
25 using namespace std;
26 #endif
27
28 #include "AliHLTCOMPHuffmanAltroComponent.h"
29 #include "AliHLTCOMPHuffmanAltro.h"
30 #include "AliHLTCOMPHuffmanData.h"
31 #include "AliHLTCompDefinitions.h"
32 #include "AliHLTStdIncludes.h"
33 #include "TFile.h"
34
35 ClassImp(AliHLTCOMPHuffmanAltroComponent)
36
37 /* constructur with arguments */
38 AliHLTCOMPHuffmanAltroComponent::AliHLTCOMPHuffmanAltroComponent(bool compression)
39   :
40   fHuffmanCompressor(NULL),
41   fCompressionSwitch(compression),
42   fTrainingMode(kFALSE),
43   fOrigin(kAliHLTVoidDataOrigin),
44   fRunNumber(0),
45   fDataSpec(0),
46   fTablePath(),
47   fNrcuTrailerwords(0),
48   fHuffmanData(NULL) 
49 {
50    // see header file for class documentation
51   // or
52   // refer to README to build package
53   // or
54   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
55 }
56
57 AliHLTCOMPHuffmanAltroComponent::~AliHLTCOMPHuffmanAltroComponent()
58 {
59   // see header file for class documentation
60 }
61
62 // Public functions to implement AliHLTComponent's interface.
63 // These functions are required for the registration process
64
65 const char* AliHLTCOMPHuffmanAltroComponent::GetComponentID()
66 {
67   // see header file for class documentation
68   if(fCompressionSwitch)
69     {
70       return "COMPHuffmanCompressor";
71     }
72   else
73     {
74       return "COMPHuffmanDecompressor";
75     }
76 }
77
78 void AliHLTCOMPHuffmanAltroComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list)
79 {
80   // see header file for class documentation
81   // initialise list
82   list.clear(); 
83
84   // if compression is to be done, input data is packed raw data
85   // else (decompression): input data is special entropy encoded raw data
86   if (fCompressionSwitch) list.push_back( kAliHLTDataTypeDDLRaw );
87   else list.push_back( AliHLTCompDefinitions::fgkDDLEncodedHuffmanAltroDataType);
88   
89 }
90
91 AliHLTComponentDataType AliHLTCOMPHuffmanAltroComponent::GetOutputDataType()
92 {
93   // see header file for class documentation
94   // if compression is to be one, output data is special entropy encoded raw data
95   // else (decompression): output data is packed raw data
96   AliHLTComponentDataType dt=kAliHLTDataTypeDDLRaw;
97   if(fCompressionSwitch)
98     dt=AliHLTCompDefinitions::fgkDDLEncodedHuffmanAltroDataType;
99   if (!fOrigin.IsNull()) SetDataType(dt, NULL, fOrigin.Data());
100   return dt;
101 }
102
103 void AliHLTCOMPHuffmanAltroComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier )
104 {
105   // see header file for class documentation
106   // reserved outputsize = inputside * inputMultiplier
107   constBase = 0;
108   if (fCompressionSwitch == kFALSE)
109     {
110       // for decompression: compressed * 4 = (enough space for) decompressed
111       inputMultiplier = 4.0 ;
112     }
113   else
114     {
115       // for compression: original * 1 = (enough space for) compressed
116       inputMultiplier = 1.0;
117     }
118 }
119
120 AliHLTComponent* AliHLTCOMPHuffmanAltroComponent::Spawn()
121 {
122   // see header file for class documentation
123   return new AliHLTCOMPHuffmanAltroComponent(fCompressionSwitch);
124 }
125
126
127 int AliHLTCOMPHuffmanAltroComponent::DoInit( int argc, const char** argv )
128 {
129   
130   // see header file for class documentation
131   
132   if ( fHuffmanCompressor )
133     return EINPROGRESS;
134   
135   
136   Int_t i = 0;
137   //Char_t* cpErr;
138   
139   while ( i < argc ) 
140     {     
141       // -- training mode wrongly called here
142       if ( !strcmp( argv[i], "-training" ) ) 
143         {
144           fTrainingMode = kTRUE;
145           
146           HLTInfo("HuffmanCompressor called in training mode, please call HuffmanCalibration instead.");
147
148           return EINVAL;
149         }
150       
151       // mode option: compress or decompress
152       //  if ( !strcmp( argv[i], "-compress" ) ) 
153       //        {
154       //          fCompressionSwitch = kTRUE;
155
156       //  ++i;
157       //  continue;
158           //}
159     
160       //if(!strcmp( argv[i], "-decompress" ) ) 
161       //        {
162       //          fCompressionSwitch = kFALSE;
163           
164       //          ++i;
165       //  continue;
166       //        }
167    
168       // -- argument to load correct code table for respective data specifications (origin, runnumber, specification)
169       if ( !strcmp( argv[i], "-origin" ) ) 
170         {
171          
172           if ( argc <= i+1 ) 
173             {
174               HLTError("Missing data origin specification");
175               return ENOTSUP;
176             }
177
178           // get data origin (TPC, PHOS, ...)
179           fOrigin=argv[i+1];
180
181           while(fOrigin.Length() <  kAliHLTComponentDataTypefOriginSize)
182             {
183               fOrigin.Append(" ");
184             }
185      
186           HLTDebug("Origin is set to %s.", fOrigin.Data());
187          
188           i += 2;
189           continue;
190         }
191
192       // -- get run number specification
193       if ( !strcmp( argv[i], "-runnumber" ) ) 
194         {
195           if ( argc <= i+1 ) 
196             {
197               HLTError("Missing run number specification");
198               return ENOTSUP;
199             }
200
201           // get run number
202           const char* runnumber = argv[i+1];
203           
204           fRunNumber =  atoi(runnumber);
205
206           HLTDebug("Run number set to %d (Dec) = %X (Hex).", fRunNumber, fRunNumber);
207           
208           // validation check of run number?!
209
210           i += 2;
211           continue;
212         }
213
214
215       // -- get data specification (e.g. TPC: slice and patch information contained in "dataspec")
216       if ( !strcmp( argv[i], "-dataspec" ) ) 
217         {
218           if ( argc <= i+1 ) 
219             {
220               HLTError("Missing data specification");
221               return ENOTSUP;
222             }
223
224           // get data spec
225           fDataSpec = strtoul(argv[i+1], NULL, 16);
226
227           HLTDebug("Dataspecification set to %d (Dec) = %08X (Hex).", fDataSpec, fDataSpec);
228           
229           // validation check of specification?!
230
231           i += 2;
232           continue;
233         }
234
235       // -- get tablepathname (e.g. ../HLT-data/)
236       if ( !strcmp( argv[i], "-tablepath" ) ) 
237         {
238           if ( argc <= i+1 ) 
239             {
240               HLTDebug("Missing table path argument.");
241             }
242
243           // get data spec
244           fTablePath=argv[i+1];
245
246           HLTDebug("Table path set to %s.", fTablePath.Data());
247           
248           // validation check of specification?!
249
250           i += 2;
251           continue;
252         }
253
254       // -- number of trailerwords: from 1 to 3
255       if ( !strcmp( argv[i], "-trailerwords" ) ) 
256         {
257           if ( argc <= i+1 ) 
258             {
259               HLTError("Missing trailerword specification");
260               return ENOTSUP;
261             }
262           
263           if ( !strcmp( argv[i+1], "1" ) ) 
264               fNrcuTrailerwords = 1;
265           else if ( !strcmp( argv[i+1], "2" ) ) 
266             fNrcuTrailerwords = 2; 
267           else if ( !strcmp( argv[i+1], "3" ) ) 
268             fNrcuTrailerwords = 3; 
269           else
270             {
271               HLTError("Missing number of trailerwords, cannot accept argument '%s'.", argv[i+1] );
272               
273               return EINVAL;
274             }   
275           
276           i += 2;
277           continue;
278         }
279             
280       HLTError("Unknown Option '%s'", argv[i] );
281       return EINVAL;
282     } // end while-loop
283   
284   // load HuffmanData from root-file to acquire translation table
285   fHuffmanData = new AliHLTCOMPHuffmanData();
286
287   TString rootfilename;
288   if(fTablePath.IsNull())
289     {
290       // if no table path is explicity set, take current path as table path
291       rootfilename.Form("huffmanData_%s_%08X_%08X.root", fOrigin.Data(), (unsigned)fRunNumber, (unsigned)fDataSpec);   
292     }
293   else
294     {
295       rootfilename.Form("%shuffmanData_%s_%08X_%08X.root", fTablePath.Data(), fOrigin.Data(), (unsigned)fRunNumber, (unsigned)fDataSpec);
296     }
297
298   TFile* huffmancodefile = new TFile(rootfilename, "READ");
299   
300   if(huffmancodefile->IsZombie())
301   { 
302     HLTFatal("No Huffman code table available for %s.", rootfilename.Data());
303       return EINVAL;
304     }    
305   fHuffmanData = (AliHLTCOMPHuffmanData*) huffmancodefile->Get("HuffmanData");
306
307   // create a new Huffman compressor 
308   fHuffmanCompressor = new AliHLTCOMPHuffmanAltro(fCompressionSwitch, kFALSE, NULL, fNrcuTrailerwords);
309   
310   // get translation table for pure encoding and decoding from HuffmanData
311   fHuffmanCompressor->GetTranslationTable(fHuffmanData);
312     
313   return 0;
314 }
315
316 int AliHLTCOMPHuffmanAltroComponent::DoDeinit()
317 {
318
319   // see header file for class documentation
320   if (fHuffmanCompressor) 
321     delete fHuffmanCompressor;
322   fHuffmanCompressor = NULL;
323
324   if ( fHuffmanData )
325     delete fHuffmanData; 
326   fHuffmanData = NULL;
327   
328   return 0;
329 }
330
331 int AliHLTCOMPHuffmanAltroComponent::DoEvent( const AliHLTComponentEventData& evtData, 
332                                               const AliHLTComponentBlockData* blocks, 
333                                               AliHLTComponentTriggerData& /*trigData*/, AliHLTUInt8_t* outputPtr, 
334                                               AliHLTUInt32_t& size, 
335                                               vector<AliHLTComponentBlockData>& outputBlocks )
336 {
337   // see header file for class documentation
338   
339   //  == init iter (pointer to datablock)
340   const AliHLTComponentBlockData* iter = NULL;
341   unsigned long ndx;
342   
343   //  == OUTdatatype pointer
344   //    AliHLTTPCClusterData* outPtr;
345   
346   AliHLTUInt8_t* outBPtr;
347   UInt_t offset, mysize, tSize = 0;
348   
349   outBPtr = outputPtr;
350   //    outPtr = (AliHLTTPCClusterData*)outBPtr;
351   
352   
353   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ )
354     {
355       iter = blocks+ndx;
356       mysize = 0;
357       offset = tSize;
358       
359       if(fCompressionSwitch) // show selected mode
360         {
361           HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",evtData.fEventID, evtData.fEventID, 
362                    DataType2Text(iter->fDataType).c_str(), DataType2Text(kAliHLTDataTypeDDLRaw|fOrigin.Data()).c_str());
363
364           // check if current block has correct data format
365           // if not, take next block
366           if ( iter->fDataType != (kAliHLTDataTypeDDLRaw|fOrigin.Data()) ) continue;
367         }
368       else
369         {
370           HLTDebug("Event 0x%08LX (%Lu) received datatype: %s - required datatype: %s",evtData.fEventID, evtData.fEventID,
371                    DataType2Text(iter->fDataType).c_str(), DataType2Text(AliHLTCompDefinitions::fgkDDLEncodedHuffmanAltroDataType|fOrigin.Data()).c_str());
372
373           // check if current block has correct data format
374           // if not, take next block
375           if ( iter->fDataType != (AliHLTCompDefinitions::fgkDDLEncodedHuffmanAltroDataType|fOrigin.Data()) ) continue;
376         }
377
378       // HLTDebug("HLT::HuffmanCompressor::DoEvent", "Event received", "Starting to process data");
379
380       fHuffmanCompressor->SetInputData(iter->fPtr, iter->fSize);
381
382       // validation test
383       // HLTDebug("input data pointer (HEX) = %x ", iter->fPtr);
384       // HLTDebug("input data size (bytes) = %i ", iter->fSize);
385       
386       fHuffmanCompressor->SetOutputData(outBPtr, size);
387       
388       // validation test
389       // HLTDebug("output data pointer (HEX) = %x ", outBPtr);
390       // HLTDebug("reserved output data size (bytes) = %i ", size);
391       
392       fHuffmanCompressor->ProcessData();
393       
394       //        outPtr = (AliHLTTPCClusterData*)outBPtr;
395       
396       mysize = fHuffmanCompressor->GetOutputDataSize();
397       
398       if(mysize != 0)
399         {
400           AliHLTComponentBlockData bd;
401           FillBlockData( bd );
402           bd.fOffset = offset;
403           bd.fSize = mysize;
404           bd.fSpecification = iter->fSpecification;
405           //AliHLTSubEventDescriptor::FillBlockAttributes( bd.fAttributes );
406           outputBlocks.push_back( bd );
407             
408           tSize += mysize;
409             outBPtr += mysize;
410             //outPtr = (AliHLTTPCClusterData*)outBPtr;
411             
412             if ( tSize > size )
413               {
414                 HLTFatal("HLT::TPCHuffmanCompressor::DoEvent: Too much data, data written over allowed buffer. Amount written: %lu, allowed amount: %lu.",tSize, size );
415                 return EMSGSIZE;
416               }
417             
418         } // end of output-block-generation
419       
420     }
421   
422   size = tSize;
423
424   return 0;   
425 }
426