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