2 //**************************************************************************
3 //* This file is property of and copyright by the *
4 //* ALICE Experiment at CERN, All rights reserved. *
6 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* Permission to use, copy, modify and distribute this software and its *
9 //* documentation strictly for non-commercial purposes is hereby granted *
10 //* without fee, provided that the above copyright notice appears in all *
11 //* copies and that both the copyright notice and this permission notice *
12 //* appear in the supporting documentation. The authors make no claims *
13 //* about the suitability of this software for any purpose. It is *
14 //* provided "as is" without express or implied warranty. *
15 //**************************************************************************
17 /// @file AliHLTTPCDataCompressionDecoder.cxx
18 /// @author Matthias Richter
20 /// @brief Generic decoder class for compressed TPC data, works on a container
21 /// class implementation which fills the actual target data struct
23 #include "AliHLTTPCDataCompressionDecoder.h"
24 #include "AliHLTTPCDataCompressionDescriptor.h"
25 #include "AliHLTTPCRawClustersDescriptor.h"
26 #include "AliHLTDataInflaterSimple.h"
27 #include "AliHLTDataInflaterHuffman.h"
31 ClassImp(AliHLTTPCDataCompressionDecoder)
33 AliHLTTPCDataCompressionDecoder::AliHLTTPCDataCompressionDecoder()
36 , fUseClusterMerger(kTRUE)
37 , fpDataInflaterPartition(NULL)
38 , fpDataInflaterTrack(NULL)
39 , fpClusterMerger(NULL)
40 , fPartitionClusterIds()
41 , fTrackModelClusterIds()
42 , fCurrentClusterIds(NULL)
48 AliHLTTPCDataCompressionDecoder::~AliHLTTPCDataCompressionDecoder()
51 if (fpDataInflaterPartition) delete fpDataInflaterPartition;
52 fpDataInflaterPartition=NULL;
53 if (fpDataInflaterTrack) delete fpDataInflaterTrack;
54 fpDataInflaterTrack=NULL;
55 if (fpClusterMerger) delete fpClusterMerger;
59 AliHLTDataInflater* AliHLTTPCDataCompressionDecoder::CreateInflater(int deflater, int mode) const
61 // create the inflater for the specified mode
62 vector<AliHLTTPCDefinitions::AliClusterParameterId_t> parameterids;
65 parameterids.push_back(AliHLTTPCDefinitions::kPadRow );
66 parameterids.push_back(AliHLTTPCDefinitions::kPad );
67 parameterids.push_back(AliHLTTPCDefinitions::kTime );
68 parameterids.push_back(AliHLTTPCDefinitions::kSigmaY2);
69 parameterids.push_back(AliHLTTPCDefinitions::kSigmaZ2);
70 parameterids.push_back(AliHLTTPCDefinitions::kCharge );
71 parameterids.push_back(AliHLTTPCDefinitions::kQMax );
74 parameterids.push_back(AliHLTTPCDefinitions::kResidualPad );
75 parameterids.push_back(AliHLTTPCDefinitions::kResidualTime);
76 parameterids.push_back(AliHLTTPCDefinitions::kSigmaY2);
77 parameterids.push_back(AliHLTTPCDefinitions::kSigmaZ2);
78 parameterids.push_back(AliHLTTPCDefinitions::kCharge );
79 parameterids.push_back(AliHLTTPCDefinitions::kQMax );
82 HLTError("invalid mode %d for inflater initialization", mode);
88 std::auto_ptr<AliHLTDataInflaterSimple> inflatersimple(new AliHLTDataInflaterSimple);
89 if (!inflatersimple.get()) return NULL;
90 for (vector<AliHLTTPCDefinitions::AliClusterParameterId_t>::const_iterator id=parameterids.begin();
91 id!=parameterids.end(); id++) {
92 const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[*id];
93 if (inflatersimple->AddParameterDefinition(parameter.fName,
95 parameter.fOptional)<0) {
96 HLTError("error adding parameter definition %s to inflater", parameter.fName);
100 return inflatersimple.release();
105 std::auto_ptr<AliHLTDataInflaterHuffman> inflaterhuffman(new AliHLTDataInflaterHuffman);
106 if (!inflaterhuffman.get()) return NULL;
107 TString cdbPath("HLT/ConfigTPC/TPCDataCompressorHuffmanTables");
108 TObject* pConf=AliHLTMisc::Instance().ExtractObject(AliHLTMisc::Instance().LoadOCDBEntry(cdbPath));
110 HLTError("can not load configuration object %s", cdbPath.Data());
113 if (dynamic_cast<TList*>(pConf)==NULL) {
114 HLTError("huffman table configuration object of inconsistent type");
117 inflaterhuffman->InitDecoders(dynamic_cast<TList*>(pConf));
118 for (vector<AliHLTTPCDefinitions::AliClusterParameterId_t>::const_iterator id=parameterids.begin();
119 id!=parameterids.end(); id++) {
120 const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[*id];
121 if (inflaterhuffman->AddParameterDefinition(parameter.fName,
122 parameter.fBitLength)<0) {
123 HLTError("error adding parameter definition %s to inflater", parameter.fName);
127 return inflaterhuffman.release();
131 HLTError("unknown inflater requested %d", deflater);
136 int AliHLTTPCDataCompressionDecoder::InitPartitionClusterDecoding(AliHLTUInt32_t specification)
138 /// init the decoding of partition cluster block
139 AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(specification);
140 AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(specification);
141 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
142 if (index<fPartitionClusterIds.size())
143 fCurrentClusterIds=&fPartitionClusterIds[index];
145 fCurrentClusterIds=NULL;
149 int AliHLTTPCDataCompressionDecoder::InitTrackModelClusterClusterDecoding()
151 /// init the decoding of track model cluster block
152 if (fTrackModelClusterIds.fIds && fTrackModelClusterIds.fSize>0)
153 fCurrentClusterIds=&fTrackModelClusterIds;
155 fCurrentClusterIds=NULL;
159 int AliHLTTPCDataCompressionDecoder::AddCompressionDescriptor(const AliHLTComponentBlockData* pDesc)
162 if (!pDesc) return -EINVAL;
163 if (pDesc->fDataType!=AliHLTTPCDefinitions::DataCompressionDescriptorDataType()) return -ENODATA;
164 const AliHLTTPCDataCompressionDescriptor* pHeader=reinterpret_cast<const AliHLTTPCDataCompressionDescriptor*>(pDesc->fPtr);
165 if (! pHeader->CheckSize( pDesc->fSize ) ) return -EINVAL;
166 if( pHeader->GetMergedClustersFlag() == 0 ){
167 fUseClusterMerger = kTRUE;
168 } else if( pHeader->GetMergedClustersFlag() == 1 ){
169 fUseClusterMerger = kFALSE;
170 } else return -EINVAL;
174 int AliHLTTPCDataCompressionDecoder::AddRawClustersDescriptor(const AliHLTComponentBlockData* pDesc)
177 if (!pDesc) return -EINVAL;
178 if (pDesc->fDataType!=AliHLTTPCDefinitions::RawClustersDescriptorDataType()) return -ENODATA;
179 const AliHLTTPCRawClustersDescriptor* pHeader=reinterpret_cast<const AliHLTTPCRawClustersDescriptor*>(pDesc->fPtr);
180 if (! pHeader->CheckSize( pDesc->fSize ) ) return -EINVAL;
181 if( pHeader->GetMergedClustersFlag() == 0 ){
182 fUseClusterMerger = kTRUE;
183 } else if( pHeader->GetMergedClustersFlag() == 1 ){
184 fUseClusterMerger = kFALSE;
185 } else return -EINVAL;
189 int AliHLTTPCDataCompressionDecoder::AddClusterMCData(const AliHLTComponentBlockData* pDesc)
191 /// add cluster mc data block
192 if (!pDesc) return -EINVAL;
193 if (pDesc->fDataType==AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo()) {
194 AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(pDesc->fSpecification);
195 AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(pDesc->fSpecification);
196 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
197 if (fClusterMCData.size()<=index) {
198 if ((int)fClusterMCData.size()<AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()) {
199 fClusterMCData.resize(AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches(), NULL);
201 fClusterMCData.resize(index+1, NULL);
204 if (pDesc->fSize<sizeof(AliHLTTPCClusterMCData)) return -EINVAL;
205 const AliHLTTPCClusterMCData* pData=reinterpret_cast<const AliHLTTPCClusterMCData*>(pDesc->fPtr);
206 unsigned nLabels = pData->fCount;
207 if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != pDesc->fSize) {
210 fClusterMCData[index]=pData;
216 int AliHLTTPCDataCompressionDecoder::AddClusterIds(const AliHLTComponentBlockData* pDesc)
218 /// add cluster id block for partition or track model clusters
219 if (!pDesc) return -EINVAL;
220 if (pDesc->fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
221 fTrackModelClusterIds.fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
222 fTrackModelClusterIds.fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
225 if (pDesc->fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) {
226 AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(pDesc->fSpecification);
227 AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(pDesc->fSpecification);
228 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
229 if (fPartitionClusterIds.size()<=index) {
230 if ((int)fPartitionClusterIds.size()<AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()) {
231 fPartitionClusterIds.resize(AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches());
233 fPartitionClusterIds.resize(index+1);
236 fPartitionClusterIds[index].fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
237 fPartitionClusterIds[index].fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
243 AliHLTUInt32_t AliHLTTPCDataCompressionDecoder::GetClusterId(int clusterNo) const
245 /// get the cluster id from the current cluster id block
246 /// clusters ids correctly link the MC label from the separate MC data block
247 /// to the cluster. The option is enabled by default in the simulation.
248 if (!fCurrentClusterIds ||
249 (int)fCurrentClusterIds->fSize<=clusterNo ||
251 return kAliHLTVoidDataSpec;
252 return fCurrentClusterIds->fIds[clusterNo];
255 const AliHLTTPCClusterMCLabel* AliHLTTPCDataCompressionDecoder::GetMCLabel(AliHLTUInt32_t clusterId) const
257 /// get MC data for a cluster Id
258 /// MC data is sent in a separate data block to keep the raw compressed
259 /// format free from any overhead
260 if (clusterId==kAliHLTVoidDataSpec) return NULL;
262 unsigned slice=AliHLTTPCSpacePointData::GetSlice(clusterId);
263 unsigned partition=AliHLTTPCSpacePointData::GetPatch(clusterId);
264 unsigned number=AliHLTTPCSpacePointData::GetNumber(clusterId);
265 if ((int)slice>=AliHLTTPCTransform::GetNSlice() ||
266 (int)partition>=AliHLTTPCTransform::GetNumberOfPatches()) return NULL;
267 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
268 if (fClusterMCData.size()<=index ||
269 fClusterMCData[index]==NULL ||
270 fClusterMCData[index]->fCount<=number) return NULL;
272 return &(fClusterMCData[index]->fLabels[number]);
275 void AliHLTTPCDataCompressionDecoder::Clear(const char* option)
277 /// cleanup, tabula rase for next event
278 if (fpDataInflaterPartition) fpDataInflaterPartition->Clear(option);
279 if (fpDataInflaterTrack) fpDataInflaterTrack->Clear(option);
280 if (fpClusterMerger) fpClusterMerger->Clear();
281 fCurrentClusterIds=NULL;
282 fPartitionClusterIds.clear();
283 fTrackModelClusterIds.Clear();
284 fClusterMCData.clear();
285 fUseClusterMerger = kTRUE;