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