Line data Source code
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: Matthias Richter <Matthias.Richter@ift.uib.no> *
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 AliHLTTPCHWCFData.cxx
20 : /// @author Matthias Richter
21 : /// @date 2011-08-04
22 : /// @brief Decoder methods for the HWCF format
23 : ///
24 : #include "AliHLTTPCHWCFData.h"
25 : #include "AliHLTErrorGuard.h"
26 : #include "AliHLTTPCHWCFEmulator.h"
27 : #include "AliHLTTPCGeometry.h"
28 : #include "AliHLTCDHWrapper.h"
29 : #include "TFile.h"
30 : #include <memory>
31 : #include <ostream>
32 :
33 6 : ClassImp(AliHLTTPCHWCFData) //ROOT macro for the implementation of ROOT specific class methods
34 :
35 0 : AliHLTTPCHWCFData::AliHLTTPCHWCFData(int forceVersion)
36 0 : : fpBuffer(NULL)
37 0 : , fBufferSize(0)
38 0 : , fVersion(-1)
39 0 : , fForcedVersion(forceVersion)
40 0 : , fRCUTrailerSize(0)
41 0 : , fpFileBuffer(NULL)
42 0 : , fIterator()
43 0 : , fIteratorEnd()
44 0 : {
45 : // constructor
46 0 : }
47 :
48 : const unsigned AliHLTTPCHWCFData::fgkAliHLTTPCHWClusterSize=sizeof(AliHLTTPCHWCFData::AliHLTTPCHWClusterV1)/sizeof(AliHLTUInt32_t);
49 :
50 : AliHLTTPCHWCFData::~AliHLTTPCHWCFData()
51 0 : {
52 : // destructor
53 0 : if (fpFileBuffer) delete fpFileBuffer;
54 0 : }
55 :
56 : int AliHLTTPCHWCFData::Init(const AliHLTUInt8_t* pBuffer, int bufferSize)
57 : {
58 : // init the internal pointer
59 0 : Reset();
60 0 : if (!pBuffer || (unsigned)bufferSize<sizeof(AliHLTUInt32_t)) return -EINVAL;
61 0 : if (bufferSize%sizeof(AliHLTUInt32_t)) {
62 0 : HLTError("invalid buffer size %d, expecting multiple of 4", bufferSize);
63 0 : return -EINVAL;
64 : }
65 0 : const AliHLTUInt32_t* rcuTrailer=reinterpret_cast<const AliHLTUInt32_t*>(pBuffer);
66 0 : rcuTrailer+=bufferSize/sizeof(AliHLTUInt32_t)-1;
67 :
68 0 : if ((*rcuTrailer >> 30) != 3) {
69 : // The HWCFEmulator does not write the RCU trailer at the moment
70 : // skip this error
71 : // HLTError("can not read last rcu trailer word");
72 : // return -ENODATA;
73 : } else {
74 : // number of 32 bit RCU trailer words can be found in the last word
75 0 : int nofRCUTrailerWords = (*rcuTrailer & 0x7F);
76 0 : if (nofRCUTrailerWords < 2) {
77 0 : HLTError("Invalid trailer size found (%d bytes)", nofRCUTrailerWords*4);
78 0 : return -ENODATA;
79 : }
80 :
81 0 : if (nofRCUTrailerWords*4>bufferSize) {
82 0 : HLTError("inconsistent RCU trailer size, exceeds buffer size");
83 0 : return -ENODATA;
84 : }
85 :
86 : // check if the first RCU trailer word starts with pattern '10'
87 0 : rcuTrailer-=nofRCUTrailerWords-1;
88 0 : if ((*rcuTrailer >> 30) != 2) {
89 0 : HLTError("inconsistent first RCU trailer word: can not find indicator pattern '10' in bit 31 and 30 (0x%08x): trailer size %d word(s), buffer size %d byte", *rcuTrailer, nofRCUTrailerWords, bufferSize);
90 0 : return -ENODATA;
91 : }
92 :
93 0 : fRCUTrailerSize = nofRCUTrailerWords*4;
94 0 : }
95 :
96 0 : fpBuffer=pBuffer;
97 0 : fBufferSize=bufferSize;
98 :
99 0 : return 0;
100 0 : }
101 :
102 : int AliHLTTPCHWCFData::Reset()
103 : {
104 : // reset
105 0 : fpBuffer=NULL;
106 0 : fBufferSize=0;
107 0 : fRCUTrailerSize=0;
108 0 : return 0;
109 : }
110 :
111 : int AliHLTTPCHWCFData::CheckVersion()
112 : {
113 : // check the data buffer for format version
114 0 : if (fVersion>=0) return fVersion;
115 0 : if (CheckAssumption(kHWCFDataV1, fpBuffer, fBufferSize-fRCUTrailerSize)) {
116 0 : fVersion=kHWCFDataV1;
117 0 : } else if (CheckAssumption(kHWCFDataV0, fpBuffer, fBufferSize-fRCUTrailerSize)) {
118 0 : fVersion=kHWCFDataV0;
119 0 : }
120 0 : return fVersion;
121 0 : }
122 :
123 : bool AliHLTTPCHWCFData::CheckAssumption(int format, const AliHLTUInt8_t* pData, int size) const
124 : {
125 : // check the format assumption for data buffer
126 0 : int elementsize=GetElementSize(format);
127 : // size has to be known
128 0 : if (elementsize<0) return false;
129 : // buffer must be multiple of element size
130 0 : if (size<elementsize || (size%elementsize)!=0) return false;
131 0 : for (int trial=0; trial<10 && (trial+1)*elementsize<=size; trial++) {
132 0 : AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(*reinterpret_cast<const AliHLTUInt32_t*>(pData+trial*elementsize));
133 : // cluster header starts with 11 in bit 30 and 31
134 0 : if ((header&0xc0000000)!=0xc0000000) return false;
135 : // check that the padrow is within bounds
136 0 : if (((header >> 24) & 0x3f)>(unsigned)AliHLTTPCGeometry::GetNRows(-1)) return false;
137 0 : }
138 0 : return true;
139 0 : }
140 :
141 : Int_t AliHLTTPCHWCFData::GetNumberOfClusters() const
142 : {
143 : // get number of clusters
144 0 : if (fVersion<0) return 0;
145 0 : int elementsize=GetElementSize(fVersion);
146 0 : if (elementsize<0) return 0;
147 0 : if (!fpBuffer || fBufferSize==0 || fBufferSize<fRCUTrailerSize) return 0;
148 0 : return (fBufferSize-fRCUTrailerSize)/elementsize;
149 0 : }
150 :
151 : Int_t AliHLTTPCHWCFData::GetPadRow(int i) const
152 : {
153 : // get raw coordinate
154 0 : if (fVersion>=0 && CheckBounds(i)) {
155 0 : switch (fVersion) {
156 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetPadRow();
157 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetPadRow();
158 : default:
159 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
160 : }
161 0 : }
162 0 : return -1;
163 0 : }
164 :
165 : Float_t AliHLTTPCHWCFData::GetPad(int i) const
166 : {
167 : // get pad coordinate
168 0 : if (fVersion>=0 && CheckBounds(i)) {
169 0 : switch (fVersion) {
170 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetPad();
171 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetPad();
172 : default:
173 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
174 : }
175 0 : }
176 0 : return -10000.;
177 0 : }
178 :
179 : Float_t AliHLTTPCHWCFData::GetTime(int i) const
180 : {
181 : // get time coordinate
182 0 : if (fVersion>=0 && CheckBounds(i)) {
183 0 : switch (fVersion) {
184 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetTime();
185 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetTime();
186 : default:
187 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
188 : }
189 0 : }
190 0 : return -10000.;
191 0 : }
192 :
193 : Float_t AliHLTTPCHWCFData::GetSigmaY2(int i) const
194 : {
195 : // get sigmaY2 coordinate
196 0 : if (fVersion>=0 && CheckBounds(i)) {
197 0 : switch (fVersion) {
198 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetSigmaY2();
199 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetSigmaY2();
200 : default:
201 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
202 : }
203 0 : }
204 0 : return -10000.;
205 0 : }
206 :
207 : Float_t AliHLTTPCHWCFData::GetSigmaZ2(int i) const
208 : {
209 : // get sigmaZ2 coordinate
210 0 : if (fVersion>=0 && CheckBounds(i)) {
211 0 : switch (fVersion) {
212 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetSigmaZ2();
213 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetSigmaZ2();
214 : default:
215 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
216 : }
217 0 : }
218 0 : return -10000.;
219 0 : }
220 :
221 : Int_t AliHLTTPCHWCFData::GetCharge(int i) const
222 : {
223 : // get charge coordinate
224 0 : if (fVersion>=0 && CheckBounds(i)) {
225 0 : switch (fVersion) {
226 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetCharge();
227 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetCharge();
228 : default:
229 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
230 : }
231 0 : }
232 0 : return -1;
233 0 : }
234 :
235 : Int_t AliHLTTPCHWCFData::GetQMax(int i) const
236 : {
237 : // get qmax coordinate
238 0 : if (fVersion>=0 && CheckBounds(i)) {
239 0 : switch (fVersion) {
240 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->GetQMax();
241 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->GetQMax();
242 : default:
243 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
244 : }
245 0 : }
246 0 : return -1;
247 0 : }
248 :
249 : Bool_t AliHLTTPCHWCFData::IsDeconvolutedPad(int i) const
250 : {
251 : // get IsDeconvolutedPad flag
252 0 : if (fVersion>=0 && CheckBounds(i)) {
253 0 : switch (fVersion) {
254 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->IsDeconvolutedPad();
255 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->IsDeconvolutedPad();
256 : default:
257 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
258 : }
259 0 : }
260 0 : return -1;
261 0 : }
262 :
263 : Bool_t AliHLTTPCHWCFData::IsDeconvolutedTime(int i) const
264 : {
265 : // get IsDeconvolutedTime flag
266 0 : if (fVersion>=0 && CheckBounds(i)) {
267 0 : switch (fVersion) {
268 0 : case 0: return reinterpret_cast<const AliHLTTPCHWClusterV0*>(Get(i))->IsDeconvolutedTime();
269 0 : case 1: return reinterpret_cast<const AliHLTTPCHWClusterV1*>(Get(i))->IsDeconvolutedTime();
270 : default:
271 0 : ALIHLTERRORGUARD(1, "invalid format version %d", fVersion);
272 : }
273 0 : }
274 0 : return -1;
275 0 : }
276 :
277 :
278 : void AliHLTTPCHWCFData::Print(const char* option)
279 : {
280 : // print info
281 0 : cout << "HWCF format version " << fVersion << endl;
282 0 : if (fVersion<0) return;
283 :
284 0 : cout << " " << GetNumberOfClusters() << " cluster(s)" << endl;
285 0 : if (GetRCUTrailerSize()>0) {
286 0 : cout << " RCU trailer: " << GetRCUTrailerSize() << " word(s)" << endl;
287 0 : }
288 :
289 0 : if (strcmp(option, "all")==0) {
290 0 : for (unsigned i=0; (int)i<GetNumberOfClusters(); i++) {
291 0 : cout << /* setw(5) <<*/ i << ":";
292 0 : cout << /* setw(8) <<*/ " " << GetPadRow(i);
293 0 : cout << /* setw(8) <<*/ " " << GetPad(i);
294 0 : cout << /* setw(8) <<*/ " " << GetTime(i);
295 0 : cout << /* setw(8) <<*/ " " << GetSigmaY2(i);
296 0 : cout << /* setw(8) <<*/ " " << GetSigmaZ2(i);
297 0 : cout << /* setw(8) <<*/ " " << GetCharge(i);
298 0 : cout << /* setw(8) <<*/ " " << GetQMax(i);
299 0 : cout << /* setw(2) <<*/ " " << IsDeconvolutedPad(i);
300 0 : cout << /* setw(2) <<*/ " " << IsDeconvolutedTime(i);
301 0 : cout << endl;
302 : }
303 0 : }
304 0 : }
305 :
306 : void AliHLTTPCHWCFData::ErrorMsg( const char *str ) const
307 : {
308 0 : ALIHLTERRORGUARD(1, str);
309 0 : }
310 :
311 : int AliHLTTPCHWCFData::Open(const char* filename)
312 : {
313 : // open block from file and add to collection
314 0 : if (!filename) return -EINVAL;
315 :
316 0 : TString input=filename;
317 0 : input+="?filetype=raw";
318 0 : std::auto_ptr<TFile> pFile(new TFile(input));
319 0 : if (!pFile.get()) return -ENOMEM;
320 0 : if (pFile->IsZombie()) return -ENOENT;
321 :
322 : int iResult=0;
323 0 : if (pFile->GetSize()<(int)sizeof(AliRawDataHeader)) {
324 0 : HLTError("file %s to small", filename);
325 0 : return -ENODATA;
326 : }
327 :
328 0 : pFile->Seek(0);
329 0 : std::auto_ptr<TArrayC> buffer(new TArrayC);
330 0 : if (!buffer.get()) return -ENOMEM;
331 :
332 0 : buffer->Set(pFile->GetSize());
333 0 : if (pFile->ReadBuffer(buffer->GetArray(), buffer->GetSize())==0) {
334 : } else {
335 0 : HLTError("failed reading %d byte(s) from file %s", pFile->GetSize(), filename);
336 : iResult=-ENODATA;
337 : }
338 :
339 0 : AliHLTCDHWrapper header(buffer->GetArray());
340 0 : AliHLTUInt8_t* pBuffer=reinterpret_cast<AliHLTUInt8_t*>(buffer->GetArray()+header.GetHeaderSize());
341 0 : unsigned bufferSize=buffer->GetSize()-header.GetHeaderSize();
342 0 : if ((iResult=Init(pBuffer, bufferSize))<0 ||
343 0 : (iResult=CheckVersion())<0) {
344 0 : Reset();
345 0 : return iResult;
346 : }
347 :
348 0 : fpFileBuffer=buffer.release();
349 0 : return GetNumberOfClusters();
350 0 : }
351 :
352 : Int_t AliHLTTPCHWCFData::AliHLTTPCHWClusterV0::GetPadRow() const
353 : {
354 : // bit 24 to 29
355 0 : AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
356 0 : if ((header>>30) != 3) return -EBADMSG;
357 0 : return (header >> 24) & 0x3f;
358 0 : }
359 :
360 : Int_t AliHLTTPCHWCFData::AliHLTTPCHWClusterV0::GetCharge() const
361 : {
362 : // 24 bit fixed point number with 6 bits after the point
363 0 : AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
364 0 : return (header & 0xFFFFFF )>>6;
365 : }
366 :
367 : Int_t AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetPadRow() const
368 : {
369 : // bit 24 to 29
370 0 : AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
371 0 : if ((header>>30) != 3) return -EBADMSG;
372 0 : return (header >> 24) & 0x3f;
373 0 : }
374 :
375 : Int_t AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetCharge() const
376 : {
377 : // 30 bit fixed point number with 12 bits after the point
378 0 : AliHLTUInt32_t word1=AliHLTTPCHWCFEmulator::ReadBigEndian(fWord1);
379 0 : return (word1 & 0x3FFFFFFF)>>12;
380 : }
381 :
382 : Int_t AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::GetQMax() const
383 : {
384 : // 23 bit fixed point number with 12 bits after the point
385 0 : AliHLTUInt32_t header=AliHLTTPCHWCFEmulator::ReadBigEndian(fHeader);
386 0 : return (header & 0x7FFFFF )>>12;
387 : }
388 :
389 : Bool_t AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::IsDeconvolutedPad() const
390 : {
391 : // bit 31 of word 1
392 0 : AliHLTUInt32_t word1=AliHLTTPCHWCFEmulator::ReadBigEndian(fWord1);
393 0 : return (word1 >> 31) & 0x1;
394 : }
395 :
396 : Bool_t AliHLTTPCHWCFData::AliHLTTPCHWClusterV1::IsDeconvolutedTime() const
397 : {
398 : // bit 30 of word 1
399 0 : AliHLTUInt32_t word1=AliHLTTPCHWCFEmulator::ReadBigEndian(fWord1);
400 0 : return (word1 >> 30) & 0x1;
401 : }
|