]>
Commit | Line | Data |
---|---|---|
db16520a | 1 | // $Id$ |
2 | ||
3 | /************************************************************************** | |
9be2600f | 4 | * This file is property of and copyright by the ALICE HLT Project * |
5 | * ALICE Experiment at CERN, All rights reserved. * | |
db16520a | 6 | * * |
9be2600f | 7 | * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * |
8 | * Timm Steinbeck <timm@kip.uni-heidelberg.de> * | |
9 | * Jochen Thaeder <thaeder@kip.uni-heidelberg.de> * | |
10 | * for The ALICE HLT Project. * | |
db16520a | 11 | * * |
12 | * Permission to use, copy, modify and distribute this software and its * | |
13 | * documentation strictly for non-commercial purposes is hereby granted * | |
14 | * without fee, provided that the above copyright notice appears in all * | |
15 | * copies and that both the copyright notice and this permission notice * | |
16 | * appear in the supporting documentation. The authors make no claims * | |
17 | * about the suitability of this software for any purpose. It is * | |
18 | * provided "as is" without express or implied warranty. * | |
19 | **************************************************************************/ | |
20 | ||
84645eb0 | 21 | /** @file AliHLTTPCDigitReaderRaw.cxx |
22 | @author Timm Steinbeck | |
23 | @date | |
24 | @brief A digit reader implementation for the RAW data coming from the RCU. | |
25 | */ | |
db16520a | 26 | |
27 | #if __GNUC__>= 3 | |
28 | using namespace std; | |
29 | #endif | |
30 | ||
db16520a | 31 | #include "AliHLTTPCDigitReaderRaw.h" |
32 | #include "AliHLTTPCTransform.h" | |
33 | #include "AliHLTTPCRootTypes.h" | |
78b557c2 | 34 | #include "AliHLTStdIncludes.h" |
db16520a | 35 | #include "AliHLTTPCLogging.h" |
36 | ||
37 | ClassImp(AliHLTTPCDigitReaderRaw) | |
38 | ||
84645eb0 | 39 | AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw( unsigned formatVersion ) |
40 | : | |
41 | fBuffer(NULL), | |
42 | fBufferSize(0), | |
43 | fPatch(-1), | |
44 | fSlice(-1), | |
6235cd38 | 45 | fRow(-1), |
46 | fPad(-1), | |
84645eb0 | 47 | fDataFormatVersion(formatVersion), |
2a083ac4 | 48 | fVerify(false), |
49 | ||
84645eb0 | 50 | fCurrentRow(0), |
51 | fCurrentPad(0), | |
52 | fCurrentBin(-1), | |
84645eb0 | 53 | fRowOffset(0), |
2a083ac4 | 54 | fNRows(0), |
84645eb0 | 55 | fNMaxRows(0), |
56 | fNMaxPads(0), | |
57 | fNTimeBins(0), | |
8e984e21 | 58 | fData(NULL), |
59 | fMapErrThrown(0) | |
db16520a | 60 | { |
6235cd38 | 61 | // see header file for class documentation |
62 | // or | |
63 | // refer to README to build package | |
64 | // or | |
65 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
8e984e21 | 66 | #ifndef HAVE_TPC_MAPPING |
6235cd38 | 67 | memset(fgMapping0, 0, fgkMapping0Size*fgkMappingDimension*sizeof(Int_t)); |
68 | memset(fgMapping1, 0, fgkMapping1Size*fgkMappingDimension*sizeof(Int_t)); | |
69 | memset(fgMapping2, 0, fgkMapping2Size*fgkMappingDimension*sizeof(Int_t)); | |
70 | memset(fgMapping3, 0, fgkMapping3Size*fgkMappingDimension*sizeof(Int_t)); | |
71 | memset(fgMapping4, 0, fgkMapping4Size*fgkMappingDimension*sizeof(Int_t)); | |
72 | memset(fgMapping5, 0, fgkMapping5Size*fgkMappingDimension*sizeof(Int_t)); | |
8e984e21 | 73 | #endif //#ifndef HAVE_TPC_MAPPING |
74 | ||
5235c3e9 | 75 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 76 | { |
77 | ||
78 | // get max number of rows | |
79 | for (Int_t ii=0; ii < 6; ii++) | |
80 | if (AliHLTTPCTransform::GetNRows(ii) > fNMaxRows) | |
81 | fNMaxRows = AliHLTTPCTransform::GetNRows(ii); | |
82 | ||
83 | // get max number of pads | |
84 | for (Int_t ii=0; ii < AliHLTTPCTransform::GetNRows();ii++ ) | |
85 | if (AliHLTTPCTransform::GetNPads(ii) > fNMaxPads) | |
86 | fNMaxPads = AliHLTTPCTransform::GetNPads(ii); | |
87 | ||
88 | // get max number of bins | |
89 | fNTimeBins = AliHLTTPCTransform::GetNTimeBins(); | |
90 | ||
5235c3e9 | 91 | // HLTDebug("Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d", |
92 | // fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads); | |
db16520a | 93 | |
94 | // init Data array | |
95 | fData = new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ]; | |
96 | } | |
97 | } | |
98 | ||
84645eb0 | 99 | AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw(const AliHLTTPCDigitReaderRaw& src) |
100 | : | |
101 | fBuffer(NULL), | |
102 | fBufferSize(0), | |
103 | fPatch(-1), | |
104 | fSlice(-1), | |
6235cd38 | 105 | fRow(-1), |
106 | fPad(-1), | |
84645eb0 | 107 | fDataFormatVersion(src.fDataFormatVersion), |
2a083ac4 | 108 | fVerify(false), |
109 | ||
84645eb0 | 110 | fCurrentRow(0), |
111 | fCurrentPad(0), | |
112 | fCurrentBin(-1), | |
84645eb0 | 113 | fRowOffset(0), |
2a083ac4 | 114 | fNRows(0), |
84645eb0 | 115 | fNMaxRows(0), |
116 | fNMaxPads(0), | |
117 | fNTimeBins(0), | |
8e984e21 | 118 | fData(NULL), |
119 | fMapErrThrown(0) | |
84645eb0 | 120 | { |
6235cd38 | 121 | // see header file for class documentation |
8e984e21 | 122 | #ifndef HAVE_TPC_MAPPING |
6235cd38 | 123 | memset(fgMapping0, 0, fgkMapping0Size*fgkMappingDimension*sizeof(Int_t)); |
124 | memset(fgMapping1, 0, fgkMapping1Size*fgkMappingDimension*sizeof(Int_t)); | |
125 | memset(fgMapping2, 0, fgkMapping2Size*fgkMappingDimension*sizeof(Int_t)); | |
126 | memset(fgMapping3, 0, fgkMapping3Size*fgkMappingDimension*sizeof(Int_t)); | |
127 | memset(fgMapping4, 0, fgkMapping4Size*fgkMappingDimension*sizeof(Int_t)); | |
128 | memset(fgMapping5, 0, fgkMapping5Size*fgkMappingDimension*sizeof(Int_t)); | |
8e984e21 | 129 | #endif //#ifndef HAVE_TPC_MAPPING |
84645eb0 | 130 | HLTFatal("copy constructor not for use"); |
131 | } | |
132 | ||
133 | AliHLTTPCDigitReaderRaw& AliHLTTPCDigitReaderRaw::operator=(const AliHLTTPCDigitReaderRaw& src) | |
134 | { | |
6235cd38 | 135 | // see header file for class documentation |
8e984e21 | 136 | #ifndef HAVE_TPC_MAPPING |
6235cd38 | 137 | memset(fgMapping0, 0, fgkMapping0Size*fgkMappingDimension*sizeof(Int_t)); |
138 | memset(fgMapping1, 0, fgkMapping1Size*fgkMappingDimension*sizeof(Int_t)); | |
139 | memset(fgMapping2, 0, fgkMapping2Size*fgkMappingDimension*sizeof(Int_t)); | |
140 | memset(fgMapping3, 0, fgkMapping3Size*fgkMappingDimension*sizeof(Int_t)); | |
141 | memset(fgMapping4, 0, fgkMapping4Size*fgkMappingDimension*sizeof(Int_t)); | |
142 | memset(fgMapping5, 0, fgkMapping5Size*fgkMappingDimension*sizeof(Int_t)); | |
8e984e21 | 143 | #endif //#ifndef HAVE_TPC_MAPPING |
84645eb0 | 144 | fBuffer=NULL; |
145 | fBufferSize=0; | |
146 | fPatch=-1; | |
147 | fSlice=-1; | |
6235cd38 | 148 | fRow=-1; |
149 | fPad=-1; | |
84645eb0 | 150 | fDataFormatVersion=src.fDataFormatVersion; |
151 | fCurrentRow=0; | |
152 | fCurrentPad=0; | |
153 | fCurrentBin=-1; | |
154 | fVerify=false; | |
155 | ||
156 | // For sorting | |
157 | fNRows=0; | |
158 | fRowOffset=0; | |
159 | fNMaxRows=0; | |
160 | fNMaxPads=0; | |
161 | fNTimeBins=0; | |
162 | fData=NULL; | |
8e984e21 | 163 | fMapErrThrown=0; |
84645eb0 | 164 | HLTFatal("assignment operator not for use"); |
165 | return (*this); | |
166 | } | |
167 | ||
6235cd38 | 168 | AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw() |
169 | { | |
170 | // see header file for class documentation | |
5235c3e9 | 171 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 172 | { |
173 | if ( fData ) | |
174 | delete [] fData; | |
175 | fData = NULL; | |
176 | } | |
177 | } | |
178 | ||
6235cd38 | 179 | int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size,Int_t firstrow,Int_t lastrow, Int_t patch, Int_t slice) |
180 | { | |
181 | // see header file for class documentation | |
78b557c2 | 182 | return AliHLTTPCDigitReader::InitBlock(ptr, size, firstrow, lastrow, patch, slice); |
183 | } | |
184 | ||
6235cd38 | 185 | int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice) |
186 | { | |
187 | // see header file for class documentation | |
db16520a | 188 | |
189 | fBuffer = (AliHLTUInt8_t*) ptr; | |
84645eb0 | 190 | if (fBuffer==NULL) { |
191 | HLTError("invalid data buffer"); | |
192 | return -EINVAL; | |
193 | } | |
db16520a | 194 | fBufferSize = size; |
84645eb0 | 195 | if (fBufferSize<=0) HLTWarning("no data available: zero length buffer"); |
db16520a | 196 | fPatch = patch; |
197 | fSlice = slice; | |
198 | fPad = -1; | |
199 | fRow = -1; | |
200 | ||
201 | fAltroBlockPositionBytes = 0; | |
202 | fAltroBlockLengthBytes = 0; | |
203 | fAltroBlock10BitWordCnt = 0xFFFFU; | |
204 | fAltroBlockHWAddress = 0xFFFFU; | |
205 | fBunchPosition = 0xFFFFU; | |
206 | fBunchTimebinStart = ~0U; | |
207 | fBunchLength = 0; | |
208 | fWordInBunch = (unsigned)-1; | |
209 | ||
84645eb0 | 210 | Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch); |
211 | Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch); | |
db16520a | 212 | |
5235c3e9 | 213 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 214 | { |
215 | fCurrentRow = 0; | |
216 | fCurrentPad = 0; | |
217 | fCurrentBin = -1; | |
218 | ||
219 | fNRows = lastrow - firstrow + 1; | |
220 | ||
221 | Int_t offset=0; | |
222 | if (patch > 1) offset = AliHLTTPCTransform::GetFirstRow( 2 ); | |
223 | ||
224 | fRowOffset = firstrow - offset; | |
225 | firstrow -= offset; | |
226 | lastrow -= offset; | |
227 | ||
228 | // Init array with -1 | |
229 | memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) ); | |
84645eb0 | 230 | |
6235cd38 | 231 | const Int_t kMaxErrorPrintout=20; |
84645eb0 | 232 | Int_t errorCount=0; |
233 | Int_t entryCount=0; | |
db16520a | 234 | // read data and fill in array |
84645eb0 | 235 | |
db16520a | 236 | while( RealNext()){ |
84645eb0 | 237 | |
238 | entryCount++; | |
db16520a | 239 | Int_t row = GetRealRow(); |
240 | Int_t pad = GetRealPad(); | |
241 | Int_t bin = GetRealTime(); | |
242 | ||
84645eb0 | 243 | // HLTFatal("Index out of array range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset); |
db16520a | 244 | |
245 | if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins || pad<0 || bin<0){ | |
246 | // if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins){ | |
6235cd38 | 247 | if (errorCount++<kMaxErrorPrintout) { |
84645eb0 | 248 | HLTFatal("Index out of range. Probably wrong patch! slice %d - patch %d", slice, patch); |
249 | HLTFatal("PAD=%d out of %d ||| ROW=%d (%d to %d) ||| BIN=%d out of %d ||| OFFSET=%d ||| ROWOFFSET=%d", | |
250 | pad, AliHLTTPCTransform::GetNPads(row + offset), row, firstrow, lastrow, bin, fNTimeBins, | |
251 | offset, fRowOffset); | |
252 | ||
253 | if ( row < firstrow || row > lastrow ) | |
254 | HLTFatal("Row out of range: %d ( %d to %d)", row, firstrow, lastrow); | |
255 | if ( pad > AliHLTTPCTransform::GetNPads(row + offset) ) | |
256 | HLTFatal("Pad out of range: %d (pad count %d)", pad, AliHLTTPCTransform::GetNPads(row + offset)); | |
257 | if ( bin > fNTimeBins ) | |
258 | HLTFatal("Time bin out of range: %d (bin count %d)", bin, fNTimeBins); | |
db16520a | 259 | } |
4a6b4894 | 260 | // stop at the fist error message in order to avoid endless messages and |
261 | // to handle corrupted events | |
262 | //continue; | |
263 | break; | |
84645eb0 | 264 | } else if ((row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin >= fNMaxRows*fNMaxPads*fNTimeBins ) { |
6235cd38 | 265 | if (errorCount++<kMaxErrorPrintout) { |
84645eb0 | 266 | HLTFatal("index out of range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset); |
db16520a | 267 | } |
4a6b4894 | 268 | // stop at the fist error message in order to avoid endless messages and |
269 | // to handle corrupted events | |
270 | //continue; | |
271 | break; | |
84645eb0 | 272 | } else { |
273 | fData[ (row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin ] = GetRealSignal() ; | |
db16520a | 274 | } |
275 | } | |
84645eb0 | 276 | if (errorCount>0) { |
277 | HLTFatal("%d of %d entries out of range", errorCount, entryCount); | |
278 | } | |
db16520a | 279 | } |
280 | ||
281 | return 0; | |
282 | } | |
283 | ||
6235cd38 | 284 | bool AliHLTTPCDigitReaderRaw::Next() |
285 | { | |
286 | // see header file for class documentation | |
287 | ||
5235c3e9 | 288 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 289 | { |
290 | Bool_t readvalue = kTRUE; | |
291 | while (1) { | |
292 | fCurrentBin++; | |
293 | if (fCurrentBin >= fNTimeBins){ | |
294 | fCurrentBin = 0; | |
295 | fCurrentPad++; | |
296 | ||
297 | if (fCurrentPad >=fNMaxPads){ | |
298 | fCurrentPad = 0; | |
299 | fCurrentRow++; | |
300 | ||
301 | if (fCurrentRow >= fNMaxRows){ | |
302 | readvalue = kFALSE; | |
303 | break; | |
304 | } | |
305 | } | |
306 | } | |
307 | ||
308 | if (fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin >= fNMaxRows*fNMaxPads*fNTimeBins ) { | |
84645eb0 | 309 | HLTFatal("Overflow: fCurrentRow=%d fCurrentPad=%d fCurrentBin=%d", fCurrentRow, fCurrentPad, fCurrentBin); |
db16520a | 310 | readvalue = kFALSE; |
311 | break; | |
312 | } | |
313 | ||
314 | if (fData[ fCurrentRow*fNMaxPads*fNTimeBins + fCurrentPad*fNTimeBins + fCurrentBin ] != -1) break; | |
315 | } | |
316 | return readvalue; | |
317 | } | |
318 | else | |
319 | return RealNext(); | |
320 | } | |
321 | ||
6235cd38 | 322 | int AliHLTTPCDigitReaderRaw::GetRow() |
323 | { | |
324 | // see header file for class documentation | |
325 | ||
5235c3e9 | 326 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 327 | { |
328 | return (fCurrentRow + fRowOffset); | |
329 | } | |
330 | else | |
331 | return GetRealRow(); | |
332 | } | |
6235cd38 | 333 | |
334 | int AliHLTTPCDigitReaderRaw::GetPad() | |
335 | { | |
336 | // see header file for class documentation | |
337 | ||
5235c3e9 | 338 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 339 | { |
340 | return fCurrentPad; | |
341 | } | |
342 | else | |
343 | return GetRealPad(); | |
344 | } | |
6235cd38 | 345 | |
346 | int AliHLTTPCDigitReaderRaw::GetSignal() | |
347 | { | |
348 | // see header file for class documentation | |
349 | ||
5235c3e9 | 350 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 351 | { |
352 | return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ]; | |
353 | } | |
354 | else | |
355 | return GetRealSignal(); | |
356 | } | |
6235cd38 | 357 | |
358 | int AliHLTTPCDigitReaderRaw::GetTime() | |
359 | { | |
360 | // see header file for class documentation | |
361 | ||
5235c3e9 | 362 | if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 ) |
db16520a | 363 | { |
364 | return fCurrentBin; | |
365 | } | |
366 | else | |
367 | return GetRealTime(); | |
368 | } | |
369 | ||
6235cd38 | 370 | bool AliHLTTPCDigitReaderRaw::RealNext() |
371 | { | |
372 | // see header file for class documentation | |
db16520a | 373 | |
db16520a | 374 | // printf( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt ); |
375 | fWordInBunch++; // use next word in bunch | |
376 | if ( fWordInBunch==fBunchLength ) { // we have a bunch at all but have reached its end (or do not have an altro block yet) | |
377 | if ( fBunchPosition+fBunchLength==fAltroBlock10BitWordCnt ) { // We were at the last bunch of this altro block (or do not have an altro block yet) | |
378 | if ( !NextAltroBlock() ) | |
379 | return false; | |
380 | fBunchPosition = 0; | |
381 | } | |
382 | else { | |
383 | fBunchPosition += fBunchLength; | |
384 | } | |
385 | fBunchLength = GetAltroBlock10BitWord( fBunchPosition ); | |
386 | fBunchTimebinStart = GetAltroBlock10BitWord( fBunchPosition+1 ); | |
387 | fWordInBunch = 2; | |
388 | } | |
84645eb0 | 389 | //HLTDebug( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt ); |
db16520a | 390 | return true; |
391 | } | |
6235cd38 | 392 | |
393 | int AliHLTTPCDigitReaderRaw::GetRealRow() const | |
394 | { | |
395 | // see header file for class documentation | |
db16520a | 396 | return fRow; |
397 | } | |
6235cd38 | 398 | |
399 | int AliHLTTPCDigitReaderRaw::GetRealPad() const | |
400 | { | |
401 | // see header file for class documentation | |
db16520a | 402 | return fPad; |
403 | } | |
6235cd38 | 404 | |
405 | int AliHLTTPCDigitReaderRaw::GetRealSignal() | |
406 | { | |
407 | // see header file for class documentation | |
db16520a | 408 | return GetAltroBlock10BitWord( fBunchPosition+fWordInBunch ); |
409 | } | |
6235cd38 | 410 | |
411 | int AliHLTTPCDigitReaderRaw::GetRealTime() const | |
412 | { | |
413 | // see header file for class documentation | |
84645eb0 | 414 | //HLTDebug( "GetRealTime: %u - %u\n", fBunchTimebinStart, fWordInBunch ); |
db16520a | 415 | return fBunchTimebinStart-(fWordInBunch-2); |
416 | } | |
417 | ||
6235cd38 | 418 | AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetRCUTrailer( unsigned offset ) const |
419 | { | |
420 | // see header file for class documentation | |
84645eb0 | 421 | if (fBufferSize<=0) return 0; |
422 | unsigned rcuDataBlockLen = GetRCUDataBlockLength(); | |
5235c3e9 | 423 | if ( offset >= rcuDataBlockLen ) return 0; |
424 | return ((AliHLTUInt32_t*)(fBuffer+fBufferSize-rcuDataBlockLen))[offset]; | |
db16520a | 425 | } |
426 | ||
427 | bool AliHLTTPCDigitReaderRaw::NextAltroBlock() | |
6235cd38 | 428 | { |
429 | // see header file for class documentation | |
84645eb0 | 430 | if (fBufferSize<=0) return 0; |
5235c3e9 | 431 | bool first = false; |
db16520a | 432 | if ( !fAltroBlockLengthBytes ) |
433 | { | |
434 | // First block in back linked list (last block in memory) | |
435 | fAltroBlockPositionBytes = fBufferSize-GetRCUDataBlockLength(); | |
5235c3e9 | 436 | first = true; |
db16520a | 437 | } |
438 | else | |
439 | { | |
440 | if ( fAltroBlockPositionBytes<fAltroBlockLengthBytes+GetCommonDataHeaderSize() ) | |
441 | { | |
84645eb0 | 442 | HLTFatal("Inconsistent Data: fAltroBlockPositionBytes=%d fAltroBlockLengthBytes=%d", fAltroBlockPositionBytes, fAltroBlockLengthBytes); |
db16520a | 443 | } |
444 | if ( fAltroBlockPositionBytes<=fAltroBlockLengthBytes+GetCommonDataHeaderSize() ) | |
445 | return false; // We have reached the end of the back linked list | |
446 | fAltroBlockPositionBytes -= fAltroBlockLengthBytes; | |
447 | } | |
448 | ||
449 | AliHLTUInt64_t altroTrailerWord = GetAltroBlock40BitWord( 0 ); | |
5235c3e9 | 450 | // Undefined hack from experience to match fill words appearing in simulated data |
451 | // Seem to be between 0 and 3 fill words, most likely to bring the number of 40bit words | |
452 | // to a multiple of four / to bring the total number of bytes to a common multiple of 4 and 5. | |
453 | // (RCU sends 40 bit (5 byte) words, DDL uses 32 bit (4 bytes) words. | |
454 | unsigned short tmpCnt=0; | |
455 | //HLTDebug( "Altro trailer word 0: 0x%016LX\n", altroTrailerWord ); | |
456 | while ( first && altroTrailerWord==0x000000AAAAAAAAAAULL && tmpCnt++<4 ) // Allow up to 4 fill values | |
457 | { | |
458 | altroTrailerWord = GetAltroBlock40BitWord( tmpCnt ); | |
459 | //HLTDebug( "Altro trailer word %hu: 0x%016LX\n", tmpCnt, altroTrailerWord ); | |
460 | } | |
db16520a | 461 | |
5235c3e9 | 462 | fAltroBlockPositionBytes -= 5*tmpCnt; |
db16520a | 463 | if ( fVerify && ((altroTrailerWord & 0xFFFC000000ULL)!=0xAAA8000000ULL) ) |
464 | { | |
84645eb0 | 465 | HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0x2AAA in high 14 bits of altro trailer word; Found %#llx (%#llx)", |
466 | fAltroBlockPositionBytes, fAltroBlockPositionBytes, | |
467 | ((altroTrailerWord & 0xFFFC000000ULL) >> 26), altroTrailerWord); | |
db16520a | 468 | |
469 | ||
470 | return false; | |
471 | } | |
472 | ||
473 | if ( fVerify && ((altroTrailerWord & 0x000000F000ULL)!=0x000000A000ULL) ) | |
474 | { | |
84645eb0 | 475 | HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0xA in bits 12-15 of altro trailer word; Found %#llx .", |
476 | fAltroBlockPositionBytes, fAltroBlockPositionBytes, ((altroTrailerWord & 0x000000F000ULL) >> 12)); | |
db16520a | 477 | |
478 | return false; | |
479 | } | |
480 | ||
481 | fAltroBlock10BitWordCnt = (altroTrailerWord >> 16) & 0x3FF; | |
482 | fAltroBlockHWAddress = altroTrailerWord & 0xFFF; | |
483 | ||
484 | // ApplyMapping | |
485 | if (!ApplyMapping()) | |
486 | { | |
84645eb0 | 487 | HLTFatal("Mapping failed Patch %d HWA %#x (%d) - maxHWA %#x (%d)", |
6235cd38 | 488 | fPatch, fAltroBlockHWAddress, fAltroBlockHWAddress, fgMaxHWA[fPatch], fgMaxHWA[fPatch]); |
db16520a | 489 | |
490 | } | |
491 | ||
492 | unsigned words40Bit = fAltroBlock10BitWordCnt/4; | |
493 | if ( fAltroBlock10BitWordCnt % 4 ) | |
494 | words40Bit++; | |
495 | words40Bit++; | |
496 | fAltroBlockLengthBytes = words40Bit*5; | |
497 | if ( fAltroBlock10BitWordCnt % 4 ) | |
498 | fAltroBlock10BitFillWordCnt = 4-(fAltroBlock10BitWordCnt % 4); | |
499 | else | |
500 | fAltroBlock10BitFillWordCnt=0; | |
501 | if ( fVerify ) | |
502 | { | |
503 | for ( unsigned b = 0; b < fAltroBlock10BitFillWordCnt; b++ ) | |
504 | { | |
505 | if ( GetAltroBlockReal10BitWord(b)!=0x2AA ) | |
506 | { | |
84645eb0 | 507 | HLTFatal("Data inconsistency in trailing 10 bit fill word of Altro Block at byte position %#x (%d): Expected 0x2AA; Found %#x", |
508 | fAltroBlockPositionBytes, fAltroBlockPositionBytes, GetAltroBlockReal10BitWord(b)); | |
db16520a | 509 | |
510 | return false; | |
511 | } | |
512 | } | |
513 | } | |
514 | return true; | |
6235cd38 | 515 | } |
db16520a | 516 | |
6235cd38 | 517 | AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetAltroBlockHWaddr() const |
518 | { | |
519 | // see header file for class documentation | |
520 | return fAltroBlockHWAddress; | |
db16520a | 521 | } |
6235cd38 | 522 | |
523 | unsigned AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWordCnt() const | |
524 | { | |
525 | // see header file for class documentation | |
526 | return fAltroBlock10BitWordCnt; | |
db16520a | 527 | } |
6235cd38 | 528 | |
529 | AliHLTUInt64_t AliHLTTPCDigitReaderRaw::GetAltroBlock40BitWord( unsigned long ndx ) const | |
530 | { | |
531 | // see header file for class documentation | |
db16520a | 532 | AliHLTUInt64_t val=0; |
533 | unsigned wordOffset32Bit = (ndx / 4)*5; | |
534 | switch ( ndx % 4 ) // 40 bit word index in a 4*40 bit=5*32 bit group | |
535 | { | |
536 | case 0: | |
537 | val = (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+1)*sizeof(AliHLTUInt32_t))); | |
538 | val <<= 8; | |
539 | val |= (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) >> 24; | |
540 | break; | |
541 | case 1: | |
542 | val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) & 0x00FFFFFF); | |
543 | val <<= 16; | |
544 | val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) >> 16) & 0xFFFF; | |
545 | break; | |
546 | case 2: | |
547 | val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) & 0xFFFF); | |
548 | val <<= 24; | |
549 | val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) >> 8); | |
550 | break; | |
551 | case 3: | |
552 | val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) & 0xFF); | |
553 | val <<= 32; | |
554 | val |= *(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+5)*sizeof(AliHLTUInt32_t)); | |
555 | break; | |
556 | } | |
557 | return val; | |
558 | } | |
6235cd38 | 559 | |
560 | AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWord( unsigned long ndx ) | |
561 | { | |
562 | // see header file for class documentation | |
db16520a | 563 | unsigned long realNdx = ndx+fAltroBlock10BitFillWordCnt; |
564 | unsigned long word40BitNdx = (realNdx / 4)+1; | |
565 | AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx ); | |
566 | switch ( realNdx % 4 ) | |
567 | { | |
568 | case 3: | |
569 | return word40Bit & 0x3FF; | |
570 | case 2: | |
571 | return (word40Bit>>10) & 0x3FF; | |
572 | case 1: | |
573 | return (word40Bit>>20) & 0x3FF; | |
574 | case 0: | |
575 | return (word40Bit>>30) & 0x3FF; | |
576 | } | |
577 | ||
578 | return 0xFFFF; | |
579 | } | |
580 | ||
6235cd38 | 581 | AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlockReal10BitWord( unsigned long ndx ) |
582 | { | |
583 | // see header file for class documentation | |
db16520a | 584 | unsigned long word40BitNdx = (ndx / 4)+1; |
585 | AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx ); | |
586 | switch ( ndx % 4 ) | |
587 | { | |
588 | case 3: | |
589 | return word40Bit & 0x3FF; | |
590 | case 2: | |
591 | return (word40Bit>>10) & 0x3FF; | |
592 | case 1: | |
593 | return (word40Bit>>20) & 0x3FF; | |
594 | case 0: | |
595 | return (word40Bit>>30) & 0x3FF; | |
596 | } | |
597 | ||
598 | return 0xFFFF; | |
599 | } | |
600 | ||
db16520a | 601 | unsigned AliHLTTPCDigitReaderRaw::GetRCUDataBlockLength() const |
6235cd38 | 602 | { |
603 | // see header file for class documentation | |
604 | // Return length of trailing RCU data block in bytes | |
db16520a | 605 | switch ( fDataFormatVersion ) |
606 | { | |
607 | case 0: | |
608 | case 1: | |
609 | return 4; | |
610 | break; | |
611 | case 2: | |
612 | case 3: | |
613 | return 12; | |
614 | break; | |
5235c3e9 | 615 | case 4: |
616 | case 5: | |
617 | return 8; | |
618 | break; | |
db16520a | 619 | default: |
620 | return fBufferSize; | |
621 | } | |
6235cd38 | 622 | } |
db16520a | 623 | |
624 | unsigned AliHLTTPCDigitReaderRaw::GetCommonDataHeaderSize() const | |
6235cd38 | 625 | { |
626 | // see header file for class documentation | |
627 | return 32; | |
628 | } | |
db16520a | 629 | |
630 | ||
6235cd38 | 631 | Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping() |
632 | { | |
633 | // see header file for class documentation | |
db16520a | 634 | |
8e984e21 | 635 | #ifndef HAVE_TPC_MAPPING |
636 | if (fMapErrThrown++==0) { | |
637 | HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING"); | |
638 | } | |
639 | return -1; | |
640 | #endif //#ifndef HAVE_TPC_MAPPING | |
6235cd38 | 641 | if ( (unsigned)fAltroBlockHWAddress > fgMaxHWA[fPatch]){ |
db16520a | 642 | fPad = -1; |
643 | fRow = -1; | |
644 | return kFALSE; | |
645 | } | |
646 | ||
647 | switch(fPatch){ | |
648 | case 0: | |
6235cd38 | 649 | fRow = fgMapping0[(unsigned)fAltroBlockHWAddress][0]; |
650 | fPad = fgMapping0[(unsigned)fAltroBlockHWAddress][1]; | |
db16520a | 651 | break; |
652 | case 1: | |
6235cd38 | 653 | fRow = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][0]; |
654 | fPad = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][1]; | |
db16520a | 655 | #if 0 |
6235cd38 | 656 | printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress][0],fgMapping1[(unsigned)fAltroBlockHWAddress][1], (unsigned)fAltroBlockHWAddress, (unsigned)fAltroBlockHWAddress); |
657 | printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress-1][0],fgMapping1[(unsigned)fAltroBlockHWAddress-1][1], (unsigned)fAltroBlockHWAddress-1, (unsigned)fAltroBlockHWAddress-1); | |
658 | printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress+1][0],fgMapping1[(unsigned)fAltroBlockHWAddress+1][1], (unsigned)fAltroBlockHWAddress+1, (unsigned)fAltroBlockHWAddress+1); | |
db16520a | 659 | #endif |
660 | break; | |
661 | case 2: | |
6235cd38 | 662 | fRow = fgMapping2[(unsigned)fAltroBlockHWAddress][0]; |
663 | fPad = fgMapping2[(unsigned)fAltroBlockHWAddress][1]; | |
db16520a | 664 | break; |
665 | case 3: | |
6235cd38 | 666 | fRow = fgMapping3[(unsigned)fAltroBlockHWAddress][0]; |
667 | fPad = fgMapping3[(unsigned)fAltroBlockHWAddress][1]; | |
db16520a | 668 | break; |
669 | case 4: | |
6235cd38 | 670 | fRow = fgMapping4[(unsigned)fAltroBlockHWAddress][0]; |
671 | fPad = fgMapping4[(unsigned)fAltroBlockHWAddress][1]; | |
db16520a | 672 | break; |
673 | case 5: | |
6235cd38 | 674 | fRow = fgMapping5[(unsigned)fAltroBlockHWAddress][0]; |
675 | fPad = fgMapping5[(unsigned)fAltroBlockHWAddress][1]; | |
db16520a | 676 | break; |
677 | default: | |
678 | fRow = -1; | |
679 | fPad = -1; | |
680 | return kFALSE; | |
681 | } | |
682 | return kTRUE; | |
683 | } | |
684 | ||
685 | ||
8e984e21 | 686 | Int_t AliHLTTPCDigitReaderRaw::GetRow( unsigned patch, unsigned hwAddr ) |
db16520a | 687 | { |
6235cd38 | 688 | // see header file for class documentation |
689 | ||
8e984e21 | 690 | #ifndef HAVE_TPC_MAPPING |
691 | if (fMapErrThrown++==0) { | |
692 | HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING"); | |
693 | } | |
694 | return -1; | |
695 | #endif //#ifndef HAVE_TPC_MAPPING | |
6235cd38 | 696 | if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){ |
db16520a | 697 | return -1; |
698 | } | |
699 | ||
700 | switch(fPatch){ | |
701 | case 0: | |
6235cd38 | 702 | return fgMapping0[hwAddr][0]; |
db16520a | 703 | case 1: |
6235cd38 | 704 | return fgMapping1[hwAddr][0]; |
db16520a | 705 | case 2: |
6235cd38 | 706 | return fgMapping2[hwAddr][0]; |
db16520a | 707 | case 3: |
6235cd38 | 708 | return fgMapping3[hwAddr][0]; |
db16520a | 709 | case 4: |
6235cd38 | 710 | return fgMapping4[hwAddr][0]; |
db16520a | 711 | case 5: |
6235cd38 | 712 | return fgMapping5[hwAddr][0]; |
db16520a | 713 | default: |
714 | return -1; | |
715 | } | |
716 | } | |
6235cd38 | 717 | |
8e984e21 | 718 | Int_t AliHLTTPCDigitReaderRaw::GetPad( unsigned patch, unsigned hwAddr ) |
db16520a | 719 | { |
6235cd38 | 720 | // see header file for class documentation |
721 | ||
8e984e21 | 722 | #ifndef HAVE_TPC_MAPPING |
723 | if (fMapErrThrown++==0) { | |
724 | HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING"); | |
725 | } | |
726 | return -1; | |
727 | #endif //#ifndef HAVE_TPC_MAPPING | |
6235cd38 | 728 | if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){ |
db16520a | 729 | return -1; |
730 | } | |
731 | ||
732 | switch(fPatch){ | |
733 | case 0: | |
6235cd38 | 734 | return fgMapping0[hwAddr][1]; |
db16520a | 735 | case 1: |
6235cd38 | 736 | return fgMapping1[hwAddr][1]; |
db16520a | 737 | case 2: |
6235cd38 | 738 | return fgMapping2[hwAddr][1]; |
db16520a | 739 | case 3: |
6235cd38 | 740 | return fgMapping3[hwAddr][1]; |
db16520a | 741 | case 4: |
6235cd38 | 742 | return fgMapping4[hwAddr][1]; |
db16520a | 743 | case 5: |
6235cd38 | 744 | return fgMapping5[hwAddr][1]; |
db16520a | 745 | default: |
746 | return -1; | |
747 | } | |
748 | } | |
749 | ||
6235cd38 | 750 | unsigned AliHLTTPCDigitReaderRaw::GetMaxHWA( unsigned patch ) const |
db16520a | 751 | { |
6235cd38 | 752 | // see header file for class documentation |
753 | ||
754 | if ( (int)patch>=fgkNofPatches ) | |
db16520a | 755 | return 0; |
6235cd38 | 756 | return fgMaxHWA[patch]; |
db16520a | 757 | } |
758 | ||
6235cd38 | 759 | Int_t AliHLTTPCDigitReaderRaw::DecodeMode(Int_t mode) |
760 | { | |
761 | // see header file for class documentation | |
762 | ||
f3f599e0 | 763 | Int_t decodedMode; |
764 | ||
765 | if ( mode >= kNofRawReaderModes ) | |
766 | decodedMode = -1; | |
767 | else | |
768 | decodedMode = mode; | |
769 | ||
770 | return decodedMode; | |
771 | } | |
772 | ||
6235cd38 | 773 | Int_t AliHLTTPCDigitReaderRaw::DecodeMode(const Char_t *mode) |
774 | { | |
775 | // see header file for class documentation | |
776 | ||
f3f599e0 | 777 | Int_t decodedMode; |
778 | Char_t *cpErr; | |
779 | ||
780 | // Check if String is convertible to Int_t | |
781 | // if not decode the string, otherwise, check if Int_t is valid | |
782 | Int_t intMode = strtoul( mode, &cpErr ,0); | |
783 | ||
784 | if ( *cpErr ) { | |
785 | if ( !strcmp( mode, "sorted_3_trailerword" ) ) | |
786 | decodedMode = kSorted3Trailerword; | |
787 | ||
788 | else if ( !strcmp( mode, "sorted_2_trailerword" ) ) | |
789 | decodedMode = kSorted2Trailerword; | |
790 | ||
791 | else if ( !strcmp( mode, "sorted_1_trailerword" ) ) | |
792 | decodedMode = kSorted1Trailerword; | |
793 | ||
794 | else if ( !strcmp( mode, "unsorted_3_trailerword" ) ) | |
795 | decodedMode = kUnsorted3Trailerword; | |
796 | ||
797 | else if ( !strcmp( mode, "unsorted_2_trailerword" ) ) | |
798 | decodedMode = kUnsorted2Trailerword; | |
799 | ||
800 | else if ( !strcmp( mode, "unsorted_1_trailerword" ) ) | |
801 | decodedMode = kUnsorted1Trailerword; | |
802 | ||
803 | else if ( ! strcmp( mode, "offline" ) ) | |
804 | decodedMode = -2; | |
805 | ||
806 | else | |
807 | decodedMode = -1; | |
808 | } // END if ( *cpErr ) { | |
809 | else { | |
810 | if ( intMode >= kNofRawReaderModes ) | |
811 | decodedMode = -1; | |
812 | else | |
813 | decodedMode = intMode; | |
814 | } | |
815 | ||
816 | return decodedMode; | |
817 | } | |
818 | ||
db16520a | 819 | |
820 | // ----- MAPPING ARRAYS | |
8e984e21 | 821 | #if defined(HAVE_TPC_MAPPING) |
db16520a | 822 | #include "mapping_array_out.inc" |
8e984e21 | 823 | #else |
824 | // dummy definitions in case of missing mapping | |
6235cd38 | 825 | unsigned AliHLTTPCDigitReaderRaw::fgMaxHWA[fgkNofPatches]; |
826 | Int_t AliHLTTPCDigitReaderRaw::fgMapping0[fgkMapping0Size][fgkMappingDimension]; | |
827 | Int_t AliHLTTPCDigitReaderRaw::fgMapping1[fgkMapping1Size][fgkMappingDimension]; | |
828 | Int_t AliHLTTPCDigitReaderRaw::fgMapping2[fgkMapping2Size][fgkMappingDimension]; | |
829 | Int_t AliHLTTPCDigitReaderRaw::fgMapping3[fgkMapping3Size][fgkMappingDimension]; | |
830 | Int_t AliHLTTPCDigitReaderRaw::fgMapping4[fgkMapping4Size][fgkMappingDimension]; | |
831 | Int_t AliHLTTPCDigitReaderRaw::fgMapping5[fgkMapping5Size][fgkMappingDimension]; | |
db16520a | 832 | #endif //#if defined(HAVE_TPC_MAPPING) |