Line data Source code
1 : //-*- Mode: C++ -*-
2 : #ifndef ALIHLTTPCDATACOMPRESSIONUNPACKERCOMPONENT_H
3 : #define ALIHLTTPCDATACOMPRESSIONUNPACKERCOMPONENT_H
4 : //* This file is property of and copyright by the ALICE HLT Project *
5 : //* ALICE Experiment at CERN, All rights reserved. *
6 : //* See cxx source for full Copyright notice *
7 :
8 : /// @file AliHLTTPCDataCompressionUnpackerComponent.h
9 : /// @author Matthias Richter
10 : /// @date 2016-03-08
11 : /// @brief Unpacker component for compressed TPC cluster data
12 : ///
13 :
14 : #include "AliHLTProcessor.h"
15 : #include "AliHLTTPCRawCluster.h"
16 : #include "AliHLTTPCSpacePointData.h"
17 : #include "TString.h"
18 : #include <stdexcept>
19 : #include <map>
20 : #include <cassert>
21 :
22 : class AliHLTTPCClusterMCLabel;
23 : class AliHLTTPCDataCompressionDecoder;
24 :
25 : /**
26 : * @class AliHLTTPCDataCompressionUnpackerComponent
27 : *
28 : * <h2>General properties:</h2>
29 : *
30 : * Component ID: \b TPCDataCompressorUnpacker <br>
31 : * Library: \b libAliHLTTPC.so <br>
32 : * Input Data Types: <br>
33 : * Output Data Types: <br>
34 : *
35 : * <h2>Mandatory arguments:</h2>
36 : * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
37 : *
38 : * <h2>Optional arguments:</h2>
39 : * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
40 :
41 : * <h2>Configuration:</h2>
42 : * <!-- NOTE: ignore the \li. <i> and </i>: it's just doxygen formatting -->
43 : *
44 : * <h2>Default CDB entries:</h2>
45 : *
46 : * <h2>Performance:</h2>
47 : *
48 : * <h2>Memory consumption:</h2>
49 : *
50 : * <h2>Output size:</h2>
51 : *
52 : *
53 : * @ingroup alihlt_tpc
54 : */
55 : class AliHLTTPCDataCompressionUnpackerComponent : public AliHLTProcessor {
56 : public:
57 : /// standard constructor
58 : AliHLTTPCDataCompressionUnpackerComponent();
59 : /// destructor
60 : ~AliHLTTPCDataCompressionUnpackerComponent();
61 : /// inherited from AliHLTComponent: id of the component
62 : virtual const char* GetComponentID();
63 :
64 : /// inherited from AliHLTComponent: list of data types in the vector reference
65 : void GetInputDataTypes( AliHLTComponentDataTypeList& );
66 :
67 : /// inherited from AliHLTComponent: output data type of the component.
68 : AliHLTComponentDataType GetOutputDataType();
69 :
70 : /// inherited from AliHLTComponent: multiple output data types of the component.
71 : int GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList);
72 :
73 : /// inherited from AliHLTComponent: output data size estimator
74 : void GetOutputDataSize( unsigned long& constBase, double& inputMultiplier );
75 :
76 : /// inherited from AliHLTComponent: spawn function.
77 : virtual AliHLTComponent* Spawn();
78 :
79 : /**
80 : * @class AliHLTTPCRawClusterRef
81 : * Abstract interface to references of AliHLTTPCRawCluster objects.
82 : * The polymorphic solution has been chosen over templates to make the container
83 : * iterator template free. The interface consists of the access operator which
84 : * returns a reference to the raw cluster in memory. A clone function provides
85 : * a factory for copy constructor and assignment operator.
86 : */
87 : class AliHLTTPCRawClusterRef {
88 : public:
89 0 : AliHLTTPCRawClusterRef() {}
90 0 : virtual ~AliHLTTPCRawClusterRef() {}
91 : virtual AliHLTTPCRawCluster& operator[](unsigned) = 0;
92 : virtual AliHLTTPCRawClusterRef* Clone() const = 0;
93 : };
94 :
95 : /**
96 : * @class AliHLTTPCRawClusterArrayRef
97 : * Reference to an array of AliHLTTPCRawCluster
98 : */
99 : class AliHLTTPCRawClusterArrayRef : public AliHLTTPCRawClusterRef {
100 : public:
101 0 : AliHLTTPCRawClusterArrayRef(AliHLTTPCRawCluster* array=NULL, unsigned size=0)
102 0 : : fExternalArray(array), fArraySize(size) {}
103 0 : AliHLTTPCRawClusterArrayRef(const AliHLTTPCRawClusterArrayRef& other)
104 0 : : fExternalArray(other.fExternalArray), fArraySize(other.fArraySize) {}
105 : AliHLTTPCRawClusterArrayRef& operator=(const AliHLTTPCRawClusterArrayRef& other)
106 : { if (&other!=this) {fExternalArray=other.fExternalArray, fArraySize=other.fArraySize;} return *this;}
107 0 : ~AliHLTTPCRawClusterArrayRef() {}
108 :
109 : AliHLTTPCRawCluster& operator[](unsigned id) {
110 0 : unsigned n=AliHLTTPCSpacePointData::GetNumber(id);
111 0 : if (n>=fArraySize) {
112 0 : throw std::runtime_error("index out of bounds");
113 : }
114 0 : return *(fExternalArray+n);
115 0 : }
116 :
117 0 : AliHLTTPCRawClusterRef* Clone() const {return new AliHLTTPCRawClusterArrayRef(*this);}
118 : private:
119 : AliHLTTPCRawCluster* fExternalArray;
120 : unsigned fArraySize;
121 : };
122 :
123 : /**
124 : * @class AliHLTTPCRawClusterMapRef
125 : * Reference to a std map of AliHLTTPCRawCluster
126 : */
127 : class AliHLTTPCRawClusterMapRef : public AliHLTTPCRawClusterRef {
128 : public:
129 0 : AliHLTTPCRawClusterMapRef(std::map<AliHLTUInt32_t, AliHLTTPCRawCluster>& map)
130 0 : : fMap(map) {}
131 0 : AliHLTTPCRawClusterMapRef(const AliHLTTPCRawClusterMapRef& other)
132 0 : : fMap(other.fMap) {}
133 : AliHLTTPCRawClusterMapRef& operator=(const AliHLTTPCRawClusterMapRef& other)
134 : { if (&other!=this) {fMap=other.fMap;} return *this;}
135 0 : ~AliHLTTPCRawClusterMapRef() {}
136 :
137 : AliHLTTPCRawCluster& operator[](unsigned id) {
138 0 : return fMap[id];
139 : }
140 0 : AliHLTTPCRawClusterRef* Clone() const {return new AliHLTTPCRawClusterMapRef(*this);}
141 : private:
142 : std::map<AliHLTUInt32_t, AliHLTTPCRawCluster>& fMap;
143 : };
144 :
145 : /**
146 : * @class AliClusterWriter
147 : * Container for cluster decoder.
148 : * The class implements the interface to be used in the decoding
149 : * of compressed TPC data, and writes it to the output buffer.
150 : */
151 : class AliClusterWriter : public AliHLTLogging {
152 : public:
153 : AliClusterWriter();
154 : AliClusterWriter(AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size);
155 : virtual ~AliClusterWriter();
156 :
157 : struct AliClusterIdBlock {
158 0 : AliClusterIdBlock() : fIds(NULL), fSize(0) {}
159 : AliHLTUInt32_t* fIds; //!
160 : AliHLTUInt32_t fSize; //!
161 : };
162 :
163 : /**
164 : * @class iterator
165 : * iterator to be used within the cluster decoder class.
166 : * The iterator has access to the target for writing through the AliHLTTPCRawClusterRef
167 : * interface.
168 : */
169 : class iterator {
170 : public:
171 : iterator()
172 : : fClusterNo(-1)
173 : , fRef(NULL)
174 : , fSlice(-1)
175 : , fPartition(-1)
176 : , fClusterIdBlock(NULL)
177 : , fClusterId(kAliHLTVoidDataSpec)
178 : {}
179 : iterator(AliHLTTPCRawClusterRef& ref, int slice=-1, int partition=-1, AliClusterIdBlock* clusterIdBlock=NULL)
180 0 : : fClusterNo(-1)
181 0 : , fRef(ref.Clone())
182 0 : , fSlice(slice)
183 0 : , fPartition(partition)
184 0 : , fClusterIdBlock(clusterIdBlock)
185 0 : , fClusterId(GetClusterId())
186 0 : {}
187 :
188 : iterator(const iterator& other)
189 : : fClusterNo(other.fClusterNo)
190 : , fRef(other.fRef->Clone())
191 : , fSlice(other.fSlice)
192 : , fPartition(other.fPartition)
193 : , fClusterIdBlock(other.fClusterIdBlock)
194 : , fClusterId(other.fClusterId)
195 : {}
196 : iterator& operator=(const iterator& other) {
197 : if (this==&other) return *this;
198 : fClusterNo=other.fClusterNo;
199 : fRef=other.fRef->Clone();
200 : fSlice=other.fSlice;
201 : fPartition=other.fPartition;
202 : fClusterIdBlock=other.fClusterIdBlock;
203 : fClusterId=other.fClusterId;
204 : return *this;
205 : }
206 0 : ~iterator() {delete fRef;}
207 :
208 0 : void SetPadRow(int row) {(*fRef)[fClusterId].SetPadRow(row);}
209 0 : void SetPad(float pad) {(*fRef)[fClusterId].SetPad(pad);}
210 0 : void SetTime(float time) {(*fRef)[fClusterId].SetTime(time);}
211 0 : void SetSigmaY2(float sigmaY2) {(*fRef)[fClusterId].SetSigmaPad2(sigmaY2);}
212 0 : void SetSigmaZ2(float sigmaZ2) {(*fRef)[fClusterId].SetSigmaTime2(sigmaZ2);}
213 0 : void SetCharge(unsigned charge) {(*fRef)[fClusterId].SetCharge(charge);}
214 0 : void SetQMax(unsigned qmax) {(*fRef)[fClusterId].SetQMax(qmax);}
215 0 : void SetFlags(unsigned short flags) {(*fRef)[fClusterId].SetFlags(flags);}
216 : void Set(const AliHLTTPCRawCluster& cl) {*this=cl;}
217 : iterator& operator=(const AliHLTTPCRawCluster& cluster) {
218 : (*fRef)[fClusterId]=cluster;
219 : return *this;
220 : }
221 0 : void SetMC(const AliHLTTPCClusterMCLabel* /*pMC*/) {assert(0);/* to be implemented*/}
222 :
223 : // switch to next cluster
224 : iterator& Next(int slice, int partition) {
225 0 : fSlice=slice; fPartition=partition; return operator++();
226 : }
227 : // prefix operators
228 0 : iterator& operator++() {fClusterNo++; fClusterId=GetClusterId();return *this;}
229 : iterator& operator--() {fClusterNo--; fClusterId=GetClusterId();return *this;}
230 : // postfix operators
231 : iterator operator++(int) {iterator i(*this); operator++(); return i;}
232 : iterator operator--(int) {iterator i(*this); operator--(); return i;}
233 :
234 : // TODO: not yet used, proper implementation needed
235 : //bool operator==(const iterator other) const {return ...;}
236 : //bool operator!=(const iterator other) const {return ...;}
237 :
238 : private:
239 : // retrieve cluster id from the optional cluster ID block, or calculate
240 : // from slice, partition and cluster number
241 : AliHLTUInt32_t GetClusterId() const {
242 : AliHLTUInt32_t id=kAliHLTVoidDataSpec;
243 0 : if (fClusterNo<0) return id;
244 0 : if (fClusterIdBlock) {
245 0 : if (fClusterIdBlock->fSize<=(unsigned)fClusterNo) {
246 0 : throw std::runtime_error("index out of bounds");
247 : }
248 0 : id=fClusterIdBlock->fIds[fClusterNo];
249 0 : }
250 0 : if (id==kAliHLTVoidDataSpec) id=AliHLTTPCSpacePointData::GetID(fSlice, fPartition, fClusterNo);
251 0 : return id;
252 0 : };
253 :
254 : int fClusterNo; //! cluster no in the current block
255 : AliHLTTPCRawClusterRef* fRef; //! reference instance for writing of unpacked clusters
256 : int fSlice; //! current slice
257 : int fPartition; //! current partition
258 : AliClusterIdBlock* fClusterIdBlock; //! pointer to optional cluster Ids
259 : AliHLTUInt32_t fClusterId; //! id of the cluster, from optional cluster id blocks or calculated from slice-partition-number
260 : };
261 :
262 : /// iterator of partition clusters block of specification
263 : iterator BeginPartitionClusterBlock(int count, AliHLTUInt32_t specification);
264 : /// iterator of track model clusters
265 : iterator BeginTrackModelClusterBlock(int count);
266 :
267 : /// add cluster id block for partition or track model clusters
268 : int AddClusterIds(const AliHLTComponentBlockData* pDesc);
269 : /// get the cluster id from the current cluster id block (optional)
270 : AliHLTUInt32_t GetClusterId(int clusterNo) const;
271 :
272 : /// set output buffer and init for writing
273 : void Init(AliHLTUInt8_t* pBuffer, AliHLTUInt32_t size);
274 :
275 : int Finish(AliHLTComponentBlockDataList& outputBlocks);
276 :
277 : /// internal cleanup
278 : virtual void Clear(Option_t * option="");
279 :
280 0 : unsigned GetRequiredSpace() const {return fRequiredSpace;}
281 : int ProcessTrackModelClusterCount();
282 :
283 : protected:
284 : AliHLTComponentBlockData ReservePartitionClusterBlock(int count, AliHLTUInt32_t specification);
285 :
286 : private:
287 : AliClusterWriter(const AliClusterWriter&);
288 : AliClusterWriter& operator=(const AliClusterWriter&);
289 :
290 : AliHLTUInt8_t* fOutputBuffer; //! output buffer for unpacked clusters
291 : AliHLTUInt32_t fBufferSize; //! size of output buffer
292 : AliHLTUInt32_t fBufferFilled; //! buffer fill count
293 : AliHLTUInt32_t fRequiredSpace; //! required space
294 : std::map<AliHLTUInt32_t, AliHLTTPCRawCluster> fTrackModelClusters; //! unpacked track model clusters
295 : std::map<AliHLTUInt32_t, unsigned> fTrackModelClusterCounts; //! cluster count per partition
296 : std::map<AliHLTUInt32_t, AliHLTComponentBlockData> fPartitionBlockDescriptors; //! block descriptors of partition clusters
297 : std::map<AliHLTUInt32_t, AliHLTTPCRawCluster*> fPartitionClusterTargets; //! positions of partition cluster blocks
298 : std::map<AliHLTUInt32_t, AliClusterIdBlock> fPartitionClusterIds; //! clusters ids for partition cluster ids
299 : AliClusterIdBlock fTrackModelClusterIds; //! cluster ids for track model clusters
300 : };
301 :
302 : protected:
303 : /// inherited from AliHLTProcessor: data processing
304 : int DoEvent( const AliHLTComponentEventData& evtData,
305 : const AliHLTComponentBlockData* blocks,
306 : AliHLTComponentTriggerData& trigData,
307 : AliHLTUInt8_t* outputPtr,
308 : AliHLTUInt32_t& size,
309 : AliHLTComponentBlockDataList& outputBlocks );
310 : using AliHLTProcessor::DoEvent;
311 : int DoInit(int argc, const char** argv );
312 :
313 : /// inherited from AliHLTComponent: component cleanup
314 : int DoDeinit();
315 :
316 : /// inherited from AliHLTComponent: argument scan
317 : int ScanConfigurationArgument(int argc, const char** argv);
318 :
319 : private:
320 : AliHLTTPCDataCompressionUnpackerComponent(const AliHLTTPCDataCompressionUnpackerComponent&);
321 : AliHLTTPCDataCompressionUnpackerComponent& operator=(const AliHLTTPCDataCompressionUnpackerComponent&);
322 :
323 : /// cluster decoder instance
324 : AliHLTTPCDataCompressionDecoder* fpDecoder; //! cluster decoder instance
325 :
326 : AliClusterWriter* fClusterWriter; //! writer instance to the output buffer
327 :
328 : unsigned fRequiredSpace; //! required space in the output buffer
329 : float fInputMultiplier; //! input multiplier for estimation of output size
330 :
331 6 : ClassDef(AliHLTTPCDataCompressionUnpackerComponent, 0)
332 : };
333 :
334 : #endif //ALIHLTTPCDATACOMPRESSIONUNPACKERCOMPONENT_H
|