Line data Source code
1 : //-*- Mode: C++ -*-
2 : // $Id$
3 : #ifndef ALIHLTTPCHWCFDATA_H
4 : #define ALIHLTTPCHWCFDATA_H
5 : //* This file is property of and copyright by the ALICE HLT Project *
6 : //* ALICE Experiment at CERN, All rights reserved. *
7 : //* See cxx source for full Copyright notice *
8 :
9 : /// @file AliHLTTPCHWCFData.h
10 : /// @author Matthias Richter
11 : /// @date 2011-08-04
12 : /// @brief Decoder methods for the HWCF format
13 : ///
14 :
15 : #include "Rtypes.h"
16 : #include "AliHLTDataTypes.h"
17 : #include "AliHLTLogging.h"
18 : #include "AliHLTErrorGuard.h"
19 :
20 : class TArrayC;
21 :
22 : /**
23 : * @class AliHLTTPCHWCFData
24 : * The class provides decoding functionality for the output format of the
25 : * TPC HW ClusterFinder
26 : *
27 : * Two formats have been defined in the past and can be detected:
28 : * version 0: 5 32bit words 20 Byte
29 : * <pre>
30 : * word 0: header (big endian 32bit unsigned)
31 : * bit 31-30: 0x11 indicates cluster
32 : * bit 29-24: row number in partition
33 : * bit 23-0: Qtot, fixed point number with 6 bits after the point
34 : * word 1: pad (float)
35 : * word 2: time (float)
36 : * word 3: pad variance (float)
37 : * word 4: time variance (float)
38 : * </pre>
39 : *
40 : * version 1: 6 32bit words 24 Byte
41 : * <pre>
42 : * word 0: header (big endian 32bit unsigned)
43 : * bit 31-30: 0x11 indicates cluster
44 : * bit 29-24: row number in partition
45 : * bit 23: empty
46 : * bit 22-0: Qmax, fixed point number with 6 bits after the point
47 : * word 1: bit 31: is set when cluster is deconvoluted in pad direction
48 : * bit 30: is set when cluster is deconvoluted in time direction
49 : * bits 0-29: total charge 30 bit big endian, fixed point number with 12 bits after the point
50 : * word 2: pad (float)
51 : * word 3: time (float)
52 : * word 4: pad variance (float)
53 : * word 5: time variance (float)
54 : * </pre>
55 : */
56 : class AliHLTTPCHWCFData : public AliHLTLogging {
57 : public:
58 : AliHLTTPCHWCFData(int forceVersion=-1);
59 : virtual ~AliHLTTPCHWCFData();
60 :
61 : int Init(const AliHLTUInt8_t* pBuffer, int bufferSize);
62 : int Reset();
63 :
64 : Int_t GetNumberOfClusters() const;
65 :
66 : Int_t GetPadRow(int i) const;
67 : Float_t GetPad(int i) const;
68 : Float_t GetTime(int i) const;
69 : Float_t GetSigmaY2(int i) const;
70 : Float_t GetSigmaZ2(int i) const;
71 : Int_t GetCharge(int i) const;
72 : Int_t GetQMax(int i) const;
73 : Bool_t IsDeconvolutedPad(int i) const;
74 : Bool_t IsDeconvolutedTime(int i) const;
75 :
76 : int CheckVersion();
77 : bool CheckAssumption(int format, const AliHLTUInt8_t* pData, int size) const;
78 :
79 : // check if index is within bounds
80 :
81 : bool CheckBounds(int i) const {
82 0 : if (fVersion<0) {
83 0 : ErrorMsg("");
84 0 : return false;
85 : }
86 0 : int elementsize=GetElementSize(fVersion);
87 0 : if (elementsize<0) return false;
88 0 : return ((i+1)*elementsize+fRCUTrailerSize<=fBufferSize);
89 0 : }
90 :
91 : // get the size of one element
92 : int GetElementSize(int version) const {
93 0 : switch (version) {
94 0 : case 0: return sizeof(AliHLTTPCHWClusterV0);
95 0 : case 1: return sizeof(AliHLTTPCHWClusterV1);
96 : default:
97 0 : ErrorMsg(Form("invalid format version %d", fVersion));
98 : }
99 0 : return -1;
100 0 : }
101 :
102 : // pointer to RCU trailer
103 : const AliHLTUInt8_t* GetRCUTrailer() const
104 : {
105 0 : if (fRCUTrailerSize<=0 || fpBuffer==NULL || fBufferSize<fRCUTrailerSize) return NULL;
106 0 : return fpBuffer+(fBufferSize-fRCUTrailerSize);
107 0 : }
108 :
109 : // size of RCU trailer
110 0 : int GetRCUTrailerSize() const { return fRCUTrailerSize; }
111 :
112 : // print info
113 : void Print(const char* option);
114 :
115 : // print error message
116 : void ErrorMsg( const char *str ) const;
117 :
118 : // open a file and init
119 : int Open(const char* filename);
120 :
121 : enum {
122 : kHWCFDataV0 = 0,
123 : kHWCFDataV1 = 1,
124 : };
125 :
126 : struct AliHLTTPCHWClusterV0 {
127 : AliHLTUInt32_t fHeader;
128 : Float_t fPad;
129 : Float_t fTime;
130 : Float_t fSigmaY2;
131 : Float_t fSigmaZ2;
132 :
133 : Int_t GetPadRow() const;
134 0 : Float_t GetPad() const {return fPad+0.5;}
135 0 : Float_t GetTime() const {return fTime;}
136 : Float_t GetSigmaY2() const {
137 0 : Float_t sy2 = fSigmaY2 - fPad*fPad;
138 0 : return (sy2>0) ?sy2 :0.;
139 : }
140 : Float_t GetSigmaZ2() const {
141 0 : Float_t sz2 = fSigmaZ2 - fTime*fTime;
142 0 : return (sz2>0) ?sz2 :0.;
143 : }
144 : Int_t GetCharge() const;
145 0 : Int_t GetQMax() const {return -1;}
146 0 : Bool_t IsDeconvolutedPad() const {return 0;}
147 0 : Bool_t IsDeconvolutedTime() const {return 0;}
148 : };
149 :
150 : struct AliHLTTPCHWClusterV1 {
151 : AliHLTUInt32_t fHeader;
152 : AliHLTUInt32_t fWord1;
153 : Float_t fPad;
154 : Float_t fTime;
155 : Float_t fSigmaY2;
156 : Float_t fSigmaZ2;
157 :
158 : Int_t GetPadRow() const;
159 0 : Float_t GetPad() const {return fPad+0.5;}
160 0 : Float_t GetTime() const {return fTime;}
161 : Float_t GetSigmaY2() const {
162 0 : Float_t sy2 = fSigmaY2 - fPad*fPad;
163 0 : return (sy2>0) ?sy2 :0.;
164 : }
165 : Float_t GetSigmaZ2() const {
166 0 : Float_t sz2 = fSigmaZ2 - fTime*fTime;
167 0 : return (sz2>0) ?sz2 :0.;
168 : }
169 : Int_t GetCharge() const;
170 : Int_t GetQMax() const;
171 : Bool_t IsDeconvolutedPad() const;
172 : Bool_t IsDeconvolutedTime() const;
173 : };
174 :
175 : template<typename T>
176 : class AliHLTTPCHWClusterDecoder {
177 : public:
178 : AliHLTTPCHWClusterDecoder(const T* pClusterArray, int entries);
179 : ~AliHLTTPCHWClusterDecoder();
180 :
181 : // i'th element, no bounds check for performance reasons
182 : const T& operator[](unsigned i) {
183 : return fpClusterArray[i];
184 : }
185 :
186 : Int_t GetPadRow(int i) const {return fpClusterArray[i]->GetPadRow();}
187 : Float_t GetPad(int i) const {return fpClusterArray[i]->GetPad();}
188 : Float_t GetTime(int i) const {return fpClusterArray[i]->GetTime();}
189 : Float_t GetSigmaY2(int i) const {return fpClusterArray[i]->GetSigmaY2();}
190 : Float_t GetSigmaZ2(int i) const {return fpClusterArray[i]->GetSigmaZ2();}
191 : Int_t GetCharge(int i) const {return fpClusterArray[i]->GetCharge();}
192 : Int_t GetQMax(int i) const {return fpClusterArray[i]->GetQMax();}
193 : Bool_t IsDeconvolutedPad(int i) const {return fpClusterArray[i]->IsDeconvolutedPad();}
194 : Bool_t IsDeconvolutedTime(int i) const {return fpClusterArray[i]->IsDeconvolutedTime();}
195 :
196 : private:
197 : const T* fpClusterArray; //! array of clusters
198 : int fEntries; //! number of entries
199 : };
200 :
201 : class iterator {
202 : public:
203 : iterator()
204 0 : : fData(NULL), fVersion(-1), fElementSize(0) {}
205 : iterator(const AliHLTUInt8_t* pData, int version, int elementSize)
206 0 : : fData(pData), fVersion(version), fElementSize(elementSize) {}
207 : iterator(const iterator& i)
208 0 : : fData(i.fData), fVersion(i.fVersion), fElementSize(i.fElementSize) {}
209 : iterator& operator=(const iterator& i) {
210 0 : if (this==&i) return *this;
211 0 : fData=i.fData; fVersion=i.fVersion; fElementSize=i.fElementSize; return *this;
212 0 : }
213 0 : ~iterator() {fData=NULL;}
214 :
215 : bool operator==(const iterator& i) const {return (fData!=NULL) && (fData==i.fData);}
216 0 : bool operator!=(const iterator& i) const {return (fData!=NULL) && (fData!=i.fData);}
217 : // prefix operators
218 0 : iterator& operator++() {fData+=fElementSize; return *this;}
219 : iterator& operator--() {fData-=fElementSize; return *this;}
220 : // postfix operators
221 : iterator operator++(int) {iterator i(*this); fData+=fElementSize; return i;}
222 : iterator operator--(int) {iterator i(*this); fData-=fElementSize; return i;}
223 :
224 0 : iterator& operator+=(int step) {fData+=step*fElementSize; return *this;}
225 :
226 : Int_t GetPadRow() const {
227 0 : switch (fVersion) {
228 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetPadRow();
229 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetPadRow();
230 0 : } return -1;
231 0 : }
232 : Float_t GetPad() const {
233 0 : switch (fVersion) {
234 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetPad();
235 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetPad();
236 0 : } return -10000.;
237 0 : }
238 : Float_t GetTime() const {
239 0 : switch (fVersion) {
240 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetTime();
241 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetTime();
242 0 : } return -10000.;
243 0 : }
244 : Float_t GetSigmaY2() const {
245 0 : switch (fVersion) {
246 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetSigmaY2();
247 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetSigmaY2();
248 0 : } return -10000.;
249 0 : }
250 : Float_t GetSigmaZ2() const {
251 0 : switch (fVersion) {
252 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetSigmaZ2();
253 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetSigmaZ2();
254 0 : } return -10000.;
255 0 : }
256 : Int_t GetCharge() const {
257 0 : switch (fVersion) {
258 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetCharge();
259 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetCharge();
260 0 : } return -1;
261 0 : }
262 : Int_t GetQMax() const {
263 0 : switch (fVersion) {
264 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetQMax();
265 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetQMax();
266 0 : } return -1;
267 0 : }
268 :
269 : Bool_t IsDeconvolutedPad() const {
270 0 : switch (fVersion) {
271 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->IsDeconvolutedPad();
272 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->IsDeconvolutedPad();
273 0 : } return -1;
274 0 : }
275 :
276 : Bool_t IsDeconvolutedTime() const {
277 0 : switch (fVersion) {
278 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->IsDeconvolutedTime();
279 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->IsDeconvolutedTime();
280 0 : } return -1;
281 0 : }
282 :
283 : protected:
284 : private:
285 : const AliHLTUInt8_t* fData; //! data
286 : int fVersion; //! format version
287 : int fElementSize; //! element size
288 : };
289 :
290 : // prepare iterator and end marker
291 : iterator& begin() {
292 0 : fIterator.~iterator();
293 0 : new (&fIterator) iterator(fpBuffer, fVersion, GetElementSize(fVersion));
294 0 : fIteratorEnd=fIterator;
295 0 : fIteratorEnd+=GetNumberOfClusters();
296 0 : return fIterator;
297 : }
298 :
299 : // get loop end marker
300 : iterator& end() {
301 0 : return fIteratorEnd;
302 : }
303 :
304 : // find one single element
305 : iterator& find(int i) {
306 0 : fIterator.~iterator();
307 0 : fIteratorEnd.~iterator();
308 0 : if (i>=GetNumberOfClusters()) return fIterator;
309 0 : new (&fIterator) iterator(fpBuffer, fVersion, GetElementSize(fVersion));
310 0 : fIterator+=i;
311 0 : fIteratorEnd=fIterator;
312 0 : fIteratorEnd+=1;
313 0 : return fIterator;
314 0 : }
315 :
316 : static const unsigned fgkAliHLTTPCHWClusterSize;
317 : protected:
318 :
319 : private:
320 : AliHLTTPCHWCFData(const AliHLTTPCHWCFData&);
321 : AliHLTTPCHWCFData& operator=(const AliHLTTPCHWCFData&);
322 :
323 : // get pointer to i'th element
324 : const AliHLTUInt8_t* Get(int i) const
325 : {
326 0 : if (!fpBuffer) return NULL;
327 0 : int elementsize=GetElementSize(fVersion);
328 0 : if (elementsize<0) return NULL;
329 0 : return fpBuffer+(i*elementsize);
330 0 : }
331 :
332 :
333 : const AliHLTUInt8_t* fpBuffer; //! pointer to data buffer
334 : int fBufferSize; //! size of data buffer
335 :
336 : int fVersion; //! format version
337 : int fForcedVersion; //! forced format version
338 : int fRCUTrailerSize; //! size of the RCU trailer in Byte
339 :
340 : TArrayC* fpFileBuffer; //! internal buffer for file content
341 :
342 : iterator fIterator; //! iterator
343 : iterator fIteratorEnd; //! end iterator
344 :
345 6 : ClassDef(AliHLTTPCHWCFData, 0)
346 : };
347 : #endif
|