707106bb8cd1c38e49a0946d3cae8a7e9942e9b5
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCHWCFData.h
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-0: Qmax, fixed point number with 6 bits after the point
46  *   word 1: total charge 32bit  big endian, fixed point number with 12 bits after the point
47  *   word 2: pad (float)
48  *   word 3: time (float)
49  *   word 4: pad variance (float)
50  *   word 5: time variance (float)
51  * </pre>
52  */
53 class AliHLTTPCHWCFData : public AliHLTLogging {
54  public:
55   AliHLTTPCHWCFData(int forceVersion=-1);
56   virtual ~AliHLTTPCHWCFData();
57
58   int Init(const AliHLTUInt8_t* pBuffer, int bufferSize);
59   int Reset();
60
61   Int_t    GetNumberOfClusters() const;
62
63   Int_t    GetPadRow(int i)  const;
64   Float_t  GetPad(int i)     const;
65   Float_t  GetTime(int i)    const;
66   Float_t  GetSigmaY2(int i) const;
67   Float_t  GetSigmaZ2(int i) const;
68   Int_t    GetCharge(int i)  const;
69   Int_t    GetQMax(int i)    const;
70
71   int CheckVersion();
72   bool CheckAssumption(int format, const AliHLTUInt8_t* pData, int size) const;
73
74   // check if index is within bounds
75   bool CheckBounds(int i) const {
76     if (fVersion<0) {
77       ALIHLTERRORGUARD(1, "");
78       return false;
79     }
80     int elementsize=GetElementSize(fVersion);
81     if (elementsize<0) return false;
82     return ((i+1)*elementsize+fRCUTrailerSize<=fBufferSize);
83   }
84
85   // get the size of one element
86   int GetElementSize(int version) const {
87     switch (version) {
88     case 0: return sizeof(AliHLTTPCHWClusterV0);
89     case 1: return sizeof(AliHLTTPCHWClusterV1);
90     default:
91       ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
92     }
93     return -1;
94   }
95
96   // pointer to RCU trailer
97   const AliHLTUInt8_t*  GetRCUTrailer() const
98   {
99     if (fRCUTrailerSize<=0 || fpBuffer==NULL || fBufferSize<fRCUTrailerSize) return NULL;
100     return fpBuffer+(fBufferSize-fRCUTrailerSize);
101   }
102
103   // size of RCU trailer
104   int GetRCUTrailerSize() const { return fRCUTrailerSize; }
105
106   // print info
107   void Print(const char* option);
108
109   // open a file and init
110   int Open(const char* filename);
111
112   enum {
113     kHWCFDataV0 = 0,
114     kHWCFDataV1 = 1,
115   };
116
117   struct AliHLTTPCHWClusterV0 {
118     AliHLTUInt32_t fHeader;
119     Float_t        fPad;
120     Float_t        fTime;
121     Float_t        fSigmaY2;
122     Float_t        fSigmaZ2;
123
124     Int_t    GetPadRow()  const;
125     Float_t  GetPad()     const {return fPad+0.5;}
126     Float_t  GetTime()    const {return fTime;}
127     Float_t  GetSigmaY2() const {
128       Float_t sy2 = fSigmaY2 - fPad*fPad;
129       return (sy2>0) ?sy2 :0.;
130     }
131     Float_t  GetSigmaZ2() const {
132       Float_t sz2 = fSigmaZ2 - fTime*fTime;
133       return (sz2>0) ?sz2 :0.;
134     }
135     Int_t    GetCharge()  const;
136     Int_t    GetQMax()    const {return -1;}
137   };
138
139   struct AliHLTTPCHWClusterV1 {
140     AliHLTUInt32_t fHeader;
141     AliHLTUInt32_t fCharge;
142     Float_t        fPad;
143     Float_t        fTime;
144     Float_t        fSigmaY2;
145     Float_t        fSigmaZ2;
146
147     Int_t    GetPadRow()  const;
148     Float_t  GetPad()     const {return fPad+0.5;}
149     Float_t  GetTime()    const {return fTime;}
150     Float_t  GetSigmaY2() const {
151       Float_t sy2 = fSigmaY2 - fPad*fPad;
152       return (sy2>0) ?sy2 :0.;
153     }
154     Float_t  GetSigmaZ2() const {
155       Float_t sz2 = fSigmaZ2 - fTime*fTime;
156       return (sz2>0) ?sz2 :0.;
157     }
158     Int_t    GetCharge()  const;
159     Int_t    GetQMax()    const;
160   };
161
162   template<typename T>
163   class AliHLTTPCHWClusterDecoder {
164   public:
165     AliHLTTPCHWClusterDecoder(const T* pClusterArray, int entries);
166     ~AliHLTTPCHWClusterDecoder();
167
168     // i'th element, no bounds check for performance reasons
169     const T& operator[](unsigned i) {
170       return fpClusterArray[i];
171     }
172
173     Int_t    GetPadRow(int i)  const {return fpClusterArray[i]->GetPadRow();}
174     Float_t  GetPad(int i)     const {return fpClusterArray[i]->GetPad();}
175     Float_t  GetTime(int i)    const {return fpClusterArray[i]->GetTime();}
176     Float_t  GetSigmaY2(int i) const {return fpClusterArray[i]->GetSigmaY2();}
177     Float_t  GetSigmaZ2(int i) const {return fpClusterArray[i]->GetSigmaZ2();}
178     Int_t    GetCharge(int i)  const {return fpClusterArray[i]->GetCharge();}
179     Int_t    GetQMax(int i)    const {return fpClusterArray[i]->GetQMax();}
180
181   private:
182     const T* fpClusterArray; //! array of clusters
183     int fEntries;            //! number of entries
184   };
185
186   class iterator {
187   public:
188     iterator()
189       : fData(NULL), fVersion(-1), fElementSize(0) {}
190     iterator(const AliHLTUInt8_t* pData, int version, int elementSize)
191       : fData(pData), fVersion(version), fElementSize(elementSize) {}
192     iterator(const iterator& i)
193       : fData(i.fData), fVersion(i.fVersion), fElementSize(i.fElementSize) {}
194     iterator& operator=(const iterator& i) {
195       if (this==&i) return *this;
196       fData=i.fData; fVersion=i.fVersion; fElementSize=i.fElementSize; return *this;
197     }
198     ~iterator() {fData=NULL;}
199
200     bool operator==(const iterator& i) const  {return (fData!=NULL) && (fData==i.fData);}
201     bool operator!=(const iterator& i) const  {return (fData!=NULL) && (fData!=i.fData);}
202     // prefix operators
203     iterator& operator++() {fData+=fElementSize; return *this;}
204     iterator& operator--() {fData-=fElementSize; return *this;}
205     // postfix operators
206     iterator operator++(int) {iterator i(*this); fData+=fElementSize; return i;}
207     iterator operator--(int) {iterator i(*this); fData-=fElementSize; return i;}
208
209     iterator& operator+=(int step) {fData+=step*fElementSize; return *this;}
210
211     Int_t    GetPadRow()  const {
212       switch (fVersion) {
213       case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetPadRow();
214       case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetPadRow();
215       } return -1;
216     }
217     Float_t  GetPad()     const {
218       switch (fVersion) {
219       case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetPad();
220       case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetPad();
221       } return -10000.;
222     }
223     Float_t  GetTime()    const {
224       switch (fVersion) {
225       case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetTime();
226       case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetTime();
227       } return -10000.;
228     }
229     Float_t  GetSigmaY2() const {
230       switch (fVersion) {
231       case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetSigmaY2();
232       case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetSigmaY2();
233       } return -10000.;
234     }
235     Float_t  GetSigmaZ2() const {
236       switch (fVersion) {
237       case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetSigmaZ2();
238       case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetSigmaZ2();
239       } return -10000.;
240     }
241     Int_t    GetCharge()  const {
242       switch (fVersion) {
243       case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetCharge();
244       case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetCharge();
245       } return -1;
246     }
247     Int_t    GetQMax()    const {
248       switch (fVersion) {
249       case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(fData)->GetQMax();
250       case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(fData)->GetQMax();
251       } return -1;
252     }
253
254   protected:
255   private:
256     const AliHLTUInt8_t* fData; //! data
257     int fVersion; //! format version
258     int fElementSize; //! element size
259   };
260
261   // prepare iterator and end marker
262   iterator& begin() {
263     fIterator.~iterator();
264     new (&fIterator) iterator(fpBuffer, fVersion, GetElementSize(fVersion));
265     fIteratorEnd=fIterator;
266     fIteratorEnd+=GetNumberOfClusters();
267     return fIterator;
268   }
269
270   // get loop end marker
271   iterator& end() {
272     return fIteratorEnd;
273   }
274
275   // find one single element
276   iterator& find(int i) {
277     fIterator.~iterator();
278     fIteratorEnd.~iterator();
279     if (i>=GetNumberOfClusters()) return fIterator;
280     new (&fIterator) iterator(fpBuffer, fVersion, GetElementSize(fVersion));
281     fIterator+=i;
282     fIteratorEnd=fIterator;
283     fIteratorEnd+=1;
284     return fIterator;
285   }
286
287   static const unsigned  fgkAliHLTTPCHWClusterSize;
288  protected:
289
290  private:
291   AliHLTTPCHWCFData(const AliHLTTPCHWCFData&);
292   AliHLTTPCHWCFData& operator=(const AliHLTTPCHWCFData&);
293
294   // get pointer to i'th element
295   const AliHLTUInt8_t* Get(int i) const
296   {
297     if (!fpBuffer) return NULL;
298     int elementsize=GetElementSize(fVersion);
299     if (elementsize<0) return NULL;
300     return fpBuffer+(i*elementsize);
301   }
302
303
304   const AliHLTUInt8_t* fpBuffer; //! pointer to data buffer
305   int fBufferSize; //! size of data buffer
306
307   int fVersion; //! format version
308   int fForcedVersion; //! forced format version
309   int fRCUTrailerSize; //! size of the RCU trailer in Byte
310
311   TArrayC* fpFileBuffer; //! internal buffer for file content
312
313   iterator fIterator; //! iterator
314   iterator fIteratorEnd; //! end iterator
315
316   ClassDef(AliHLTTPCHWCFData, 0)
317 };
318 #endif