]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/AliHLTDataDeflaterHuffman.cxx
- Reshuffling of the particle codes in AliPID. Now the light nuclei are between the
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTDataDeflaterHuffman.cxx
CommitLineData
6a1b3945 1// $Id$
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: Thorsten Kollegger <kollegge@ikf.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/// @file AliHLTDataDeflaterHuffman.cxx
20/// @author Thorsten Kollegger, Matthias Richter
21/// @date 2011-08-10
22/// @brief Deflater implementation using huffman code
23
24#include "AliHLTDataDeflaterHuffman.h"
25#include "AliHLTHuffman.h"
26#include "TObjArray.h"
27#include "TList.h"
28#include "TString.h"
29#include "TFile.h"
30#include <memory>
31#include <algorithm>
32#include <iostream>
33
34/** ROOT macro for the implementation of ROOT specific class methods */
35ClassImp(AliHLTDataDeflaterHuffman)
36
37AliHLTDataDeflaterHuffman::AliHLTDataDeflaterHuffman(bool bTrainingMode)
38 : AliHLTDataDeflater()
a3c3f7e9 39 , fReferenceLength()
6a1b3945 40 , fHuffmanCoders()
41 , fHuffmanCoderList(NULL)
42 , fTrainingMode(bTrainingMode)
43{
44 // see header file for class documentation
45 // or
46 // refer to README to build package
47 // or
48 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
49 if (bTrainingMode) {
50 HLTInfo("using DataDeflaterHuffman in training mode");
51 }
52}
53
54AliHLTDataDeflaterHuffman::~AliHLTDataDeflaterHuffman()
55{
56 // destructor
57 if (fHuffmanCoderList) delete fHuffmanCoderList;
58 fHuffmanCoderList=NULL;
59
60 Clear();
61}
62
a3c3f7e9 63int AliHLTDataDeflaterHuffman::AddParameterDefinition(const char* name, unsigned bitLength, unsigned refLength)
6a1b3945 64{
65 /// search a parameter definition in the decoder configuration, and set the index
66 /// array, return reference id
67 if (IsTrainingMode())
68 return AddTrainingParameter(name, bitLength);
69
70 if (!name) return -EINVAL;
71 if (!fHuffmanCoderList) return -ENODEV;
72 TObject* pObj=fHuffmanCoderList->FindObject(name);
73 if (!pObj) {
74 HLTError("can not find decoder of id '%s'", name);
75 return -ENOENT;
76 }
77 AliHLTHuffman* pHuffman=dynamic_cast<AliHLTHuffman*>(pObj);
78 if (!pHuffman) {
79 HLTError("object %s has wrong type, expected AliHLTHuffman", name);
80 return -EBADF;
81 }
82 if (pHuffman->GetMaxBits()!=bitLength) {
83 HLTError("mismatch in bitlengt: can not use decoder %s of length %d for encoding of %d bits", pHuffman->GetName(), pHuffman->GetMaxBits(), bitLength);
84 return -EPERM;
85 }
86
a3c3f7e9 87 fReferenceLength.push_back(refLength);
6a1b3945 88 fHuffmanCoders.push_back(pHuffman);
a3c3f7e9 89
90 int memberId=fHuffmanCoders.size()-1;
91 if (DoStatistics()) {
92 AddHistogram(memberId, name, bitLength);
93 }
94
95 return memberId;
6a1b3945 96}
97
98int AliHLTDataDeflaterHuffman::InitDecoders(TList* decoderlist)
99{
100 /// init list of decoders
101 /// expects to be an external pointer, valid throughout the livetime of
102 /// the instance
103 if (!decoderlist) return -EINVAL;
104 if (!fHuffmanCoderList) {
105 fHuffmanCoderList=new TList;
106 } else {
107 if (fHuffmanCoderList->GetEntries()>0 && fHuffmanCoderList->IsOwner()) {
108 HLTWarning("list of decoders owns already %d object(s), but disabling ownership now because of new external pointers");
109 }
110 }
111 if (!fHuffmanCoderList) return -ENOMEM;
112 fHuffmanCoderList->SetOwner(kFALSE);
113 TIter next(decoderlist);
114 TObject* pObj=NULL;
115 while ((pObj=next())!=NULL) {
116 if (dynamic_cast<AliHLTHuffman*>(pObj)==NULL) continue;
117 if (fHuffmanCoderList->FindObject(pObj->GetName())) {
118 HLTError("duplicate entry of name '%s'", pObj->GetName());
119 return -EEXIST;
120 }
121 fHuffmanCoderList->Add(pObj);
122 }
123
124 return fHuffmanCoderList->GetEntries();
125}
126
127bool AliHLTDataDeflaterHuffman::OutputParameterBits( int memberId, AliHLTUInt64_t const & value )
128{
129 // write huffman encoded bit pattern of a member to the current byte and position
130 if (IsTrainingMode())
131 return AddTrainingValue(memberId, value);
132
133 if (memberId>=(int)fHuffmanCoders.size()) {
134 return false;
135 }
136
137 AliHLTUInt64_t length = 0;
138 const std::bitset<64>& v=fHuffmanCoders[memberId]->Encode((value>fHuffmanCoders[memberId]->GetMaxValue())?fHuffmanCoders[memberId]->GetMaxValue():value, length);
9409b4b1 139 //cout << fHuffmanCoders[memberId]->GetName() << " value " << value << ": code lenght " << length << " " << v << endl;
a3c3f7e9 140 if (DoStatistics()) {
141 float weight=0.0;
142 unsigned parameterLength=fHuffmanCoders[memberId]->GetMaxBits();
143 if (memberId<(int)fReferenceLength.size() && fReferenceLength[memberId]>0)
144 parameterLength=fReferenceLength[memberId];
145 if (parameterLength>0) {
146 weight=length;
147 weight/=parameterLength;
148 }
149 FillStatistics(memberId, value, length, weight);
150 }
151
6a1b3945 152 if (length>0) {
153 return OutputBits(v, length);
154 }
a3c3f7e9 155
6a1b3945 156 return false;
157}
158
159int AliHLTDataDeflaterHuffman::AddTrainingParameter(const char* name, unsigned bitLength)
160{
161 /// add a parameter definition for huffman training
162
163 /// returns index in the array
164 if (!fHuffmanCoderList) {
165 fHuffmanCoderList=new TList;
166 if (!fHuffmanCoderList) return -ENOMEM;
167 // always set ownership for the new list since it is supposed to
168 // contain only internal pointers
169 fHuffmanCoderList->SetOwner();
170 } else if (!fHuffmanCoderList->IsOwner()) {
171 // not sure about the pointers which are already in the list
172 if (fHuffmanCoderList->GetEntries()>0) {
173 HLTWarning("skip setting ownership because list contains already %d object(s), possible memory leak at cleanup");
174 } else {
175 fHuffmanCoderList->SetOwner();
176 }
177 }
178 AliHLTHuffman* pHuffman=new AliHLTHuffman(name, bitLength);
179 if (!pHuffman) return -ENOMEM;
180 fHuffmanCoderList->Add(pHuffman);
181
182 fHuffmanCoders.push_back(pHuffman);
183 return fHuffmanCoders.size()-1;
184}
185
186bool AliHLTDataDeflaterHuffman::AddTrainingValue( int memberId, AliHLTUInt64_t const & value )
187{
188 /// add a training value for the specified parameter
189 if (memberId>=(int)fHuffmanCoders.size()) {
190 return false;
191 }
192 return fHuffmanCoders[memberId]->AddTrainingValue(value);
193}
194
195const TList* AliHLTDataDeflaterHuffman::GenerateHuffmanTree()
196{
197 /// generate the huffman tree
198 for (unsigned i=0; i<fHuffmanCoders.size(); i++) {
199 if (!fHuffmanCoders[i]->GenerateHuffmanTree()) {
200 HLTError("failed to generate huffman tree for parameter %s", fHuffmanCoders[i]->GetName());
201 }
202 }
203 return fHuffmanCoderList;
204}
205
206void AliHLTDataDeflaterHuffman::Clear(Option_t * option)
207{
208 // internal cleanup
209
210 AliHLTDataDeflater::Clear(option);
211}
212
213void AliHLTDataDeflaterHuffman::Print(Option_t *option) const
214{
215 // print info
216 Print(cout, option);
217}
218
219void AliHLTDataDeflaterHuffman::Print(ostream& out, Option_t * /*option*/) const
220{
221 // print to stream
222 out << "AliHLTDataDeflaterHuffman:" << endl;
223 for (vector<AliHLTHuffman*>::const_iterator it=fHuffmanCoders.begin();
224 it!=fHuffmanCoders.end(); it++) {
225 (*it)->Print("short"); cout << endl;
226 }
227 if (fHuffmanCoders.size()==0 && fHuffmanCoderList && fHuffmanCoderList->GetEntries()>0) {
228 TIter next(fHuffmanCoderList);
229 TObject* pObj=NULL;
230 while ((pObj=next())) {
231 pObj->Print("short"); cout << endl;
232 }
233 }
234}
235
236TObject *AliHLTDataDeflaterHuffman::FindObject(const char *name) const
237{
238 /// find object: 'DeflaterConfiguration'
239 if (strcmp(name, "DeflaterConfiguration")==0) {
240 for (unsigned i=0; i<fHuffmanCoders.size(); i++) {
241 if (!fHuffmanCoders[i]->GenerateHuffmanTree()) {
242 HLTError("generation of huffman tree for parameter '%s' failed", fHuffmanCoders[i]->GetName());
9409b4b1 243 return NULL;
244 }
245 if (!fHuffmanCoders[i]->CheckConsistency()) {
246 HLTError("consistency check of huffman tree for parameter '%s' failed", fHuffmanCoders[i]->GetName());
6a1b3945 247 }
248 }
249
250 return fHuffmanCoderList;
251 }
252
253 return NULL;
254}
255
256void AliHLTDataDeflaterHuffman::SaveAs(const char *filename, Option_t *option) const
257{
258 /// save data according to option
259 TString remainingOptions;
260 bool bWriteHuffmanConf=false; // write the huffman configuration
261 TString strOption(option);
262 std::auto_ptr<TObjArray> tokens(strOption.Tokenize(" "));
263 if (tokens.get()) {
264 for (int i=0; i<tokens->GetEntriesFast(); i++) {
265 if (!tokens->At(i)) continue;
266 const char* key="";
267 TString arg=tokens->At(i)->GetName();
268
269 key="huffmanconf";
270 if (arg.BeginsWith(key)) {
271 bWriteHuffmanConf=true;
272 continue;
273 }
274
275 if (!remainingOptions.IsNull()) remainingOptions+=" ";
276 remainingOptions+=arg;
277 }
278 }
279
280 if (bWriteHuffmanConf) {
281 std::auto_ptr<TFile> output(TFile::Open(filename, "RECREATE"));
282 if (!output.get() || output->IsZombie()) {
283 HLTError("can not open file %s from writing", filename);
284 return;
285 }
286
287 if (!fHuffmanCoderList || fHuffmanCoderList->GetEntries()==0) {
288 HLTError("no huffman instances available for writing");
289 return;
290 }
291
292 for (unsigned i=0; i<fHuffmanCoders.size(); i++) {
293 if (!fHuffmanCoders[i]->GenerateHuffmanTree()) {
294 HLTError("generation of huffman tree for parameter '%s' failed", fHuffmanCoders[i]->GetName());
295 }
296 }
297
298 output->cd();
299 fHuffmanCoderList->Write("DeflaterConfiguration", TObject::kSingleKey);
300 output->Close();
a3c3f7e9 301 return;
6a1b3945 302 }
303
a3c3f7e9 304 return AliHLTDataDeflater::SaveAs(filename, remainingOptions);
6a1b3945 305}
306
307ostream& operator<<(ostream &out, const AliHLTDataDeflaterHuffman& me)
308{
309 me.Print(out);
310 return out;
311}
312