]>
Commit | Line | Data |
---|---|---|
3ea47630 | 1 | /************************************************************************** |
2 | * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
7 | * Permission to use, copy, modify and distribute this software and its * | |
8 | * documentation strictly for non-commercial purposes is hereby granted * | |
9 | * without fee, provided that the above copyright notice appears in all * | |
10 | * copies and that both the copyright notice and this permission notice * | |
11 | * appear in the supporting documentation. The authors make no claims * | |
12 | * about the suitability of this software for any purpose. It is * | |
13 | * provided "as is" without express or implied warranty. * | |
14 | **************************************************************************/ | |
15 | ||
16 | /* $Id$ */ | |
17 | ||
18 | /////////////////////////////////////////////////////////////////////////////// | |
19 | /// | |
20 | /// This class provides access to Altro digits in raw data. | |
21 | /// | |
22 | /// It loops over all Altro digits in the raw data given by the AliRawReader. | |
23 | /// The Next method goes to the next digit. If there are no digits left | |
24 | /// it returns kFALSE. | |
25 | /// Several getters provide information about the current digit. | |
26 | /// | |
27 | /////////////////////////////////////////////////////////////////////////////// | |
28 | ||
29 | #include "AliAltroRawStream.h" | |
30 | #include "AliRawReader.h" | |
3a291af4 | 31 | #include "AliLog.h" |
3ea47630 | 32 | |
33 | ClassImp(AliAltroRawStream) | |
34 | ||
35 | ||
36 | //_____________________________________________________________________________ | |
37 | AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) : | |
e7fd2555 | 38 | fNoAltroMapping(kTRUE), |
7e18047e | 39 | fIsOldRCUFormat(kFALSE), |
1e984421 | 40 | fIsShortDataHeader(kFALSE), |
e7fd2555 | 41 | fDDLNumber(-1), |
42 | fPrevDDLNumber(-1), | |
5e6235b5 | 43 | fRCUId(-1), |
44 | fPrevRCUId(-1), | |
3a291af4 | 45 | fHWAddress(-1), |
46 | fPrevHWAddress(-1), | |
3ea47630 | 47 | fTime(-1), |
e7fd2555 | 48 | fPrevTime(-1), |
3ea47630 | 49 | fSignal(-1), |
e7fd2555 | 50 | fTimeBunch(-1), |
3ea47630 | 51 | fRawReader(rawReader), |
52 | fData(NULL), | |
53 | fPosition(0), | |
54 | fCount(0), | |
5e6235b5 | 55 | fBunchLength(0), |
56 | fRCUTrailerData(NULL), | |
57 | fRCUTrailerSize(0) | |
3ea47630 | 58 | { |
59 | // create an object to read Altro raw digits | |
e7fd2555 | 60 | fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1; |
3ea47630 | 61 | } |
62 | ||
63 | //_____________________________________________________________________________ | |
64 | AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) : | |
65 | TObject(stream), | |
e7fd2555 | 66 | fNoAltroMapping(kTRUE), |
7e18047e | 67 | fIsOldRCUFormat(kFALSE), |
1e984421 | 68 | fIsShortDataHeader(kFALSE), |
e7fd2555 | 69 | fDDLNumber(-1), |
70 | fPrevDDLNumber(-1), | |
5e6235b5 | 71 | fRCUId(-1), |
72 | fPrevRCUId(-1), | |
3a291af4 | 73 | fHWAddress(-1), |
74 | fPrevHWAddress(-1), | |
3ea47630 | 75 | fTime(-1), |
e7fd2555 | 76 | fPrevTime(-1), |
3ea47630 | 77 | fSignal(-1), |
e7fd2555 | 78 | fTimeBunch(-1), |
3ea47630 | 79 | fRawReader(NULL), |
80 | fData(NULL), | |
81 | fPosition(0), | |
82 | fCount(0), | |
5e6235b5 | 83 | fBunchLength(0), |
84 | fRCUTrailerData(NULL), | |
85 | fRCUTrailerSize(0) | |
3ea47630 | 86 | { |
87 | Fatal("AliAltroRawStream", "copy constructor not implemented"); | |
88 | } | |
89 | ||
90 | //_____________________________________________________________________________ | |
91 | AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream& | |
92 | /* stream */) | |
93 | { | |
94 | Fatal("operator =", "assignment operator not implemented"); | |
95 | return *this; | |
96 | } | |
97 | ||
98 | //_____________________________________________________________________________ | |
99 | AliAltroRawStream::~AliAltroRawStream() | |
100 | { | |
101 | // clean up | |
102 | ||
103 | } | |
104 | ||
3a291af4 | 105 | //_____________________________________________________________________________ |
106 | void AliAltroRawStream::Reset() | |
107 | { | |
108 | // reset altro raw stream params | |
109 | ||
110 | fPosition = fCount = fBunchLength = 0; | |
111 | ||
5e6235b5 | 112 | fRCUTrailerData = NULL; |
113 | fRCUTrailerSize = 0; | |
114 | ||
115 | fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1; | |
3a291af4 | 116 | |
117 | if (fRawReader) fRawReader->Reset(); | |
e7fd2555 | 118 | |
119 | fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1; | |
3a291af4 | 120 | } |
3ea47630 | 121 | |
122 | //_____________________________________________________________________________ | |
123 | Bool_t AliAltroRawStream::Next() | |
124 | { | |
125 | // read the next raw digit | |
126 | // returns kFALSE if there is no digit left | |
127 | ||
e7fd2555 | 128 | fPrevDDLNumber = fDDLNumber; |
5e6235b5 | 129 | fPrevRCUId = fRCUId; |
3a291af4 | 130 | fPrevHWAddress = fHWAddress; |
e7fd2555 | 131 | fPrevTime = fTime; |
3ea47630 | 132 | |
133 | while (fCount == 0) { // next trailer | |
134 | if (fPosition <= 0) { // next payload | |
135 | do { | |
136 | if (!fRawReader->ReadNextData(fData)) return kFALSE; | |
137 | } while (fRawReader->GetDataSize() == 0); | |
138 | ||
e7fd2555 | 139 | fDDLNumber = fRawReader->GetDDLID(); |
140 | ||
3a291af4 | 141 | fPosition = GetPosition(); |
3ea47630 | 142 | } |
3ea47630 | 143 | |
3a291af4 | 144 | if (!ReadTrailer()) |
145 | AliFatal("Incorrect trailer information !"); | |
3ea47630 | 146 | |
3a291af4 | 147 | fBunchLength = 0; |
3ea47630 | 148 | } |
149 | ||
3a291af4 | 150 | if (fBunchLength == 0) ReadBunch(); |
151 | else fTime--; | |
152 | ||
153 | ReadAmplitude(); | |
3ea47630 | 154 | |
155 | return kTRUE; | |
156 | } | |
157 | ||
e7fd2555 | 158 | //_____________________________________________________________________________ |
159 | void AliAltroRawStream::SelectRawData(Int_t detId) | |
160 | { | |
161 | // Select the raw data for specific | |
162 | // detector id | |
163 | AliDebug(1,Form("Selecting raw data for detector %d",detId)); | |
164 | fRawReader->Select(detId); | |
165 | } | |
166 | ||
362c9d61 | 167 | //_____________________________________________________________________________ |
168 | void AliAltroRawStream::SelectRawData(const char *detName) | |
169 | { | |
170 | // Select the raw data for specific | |
171 | // detector name | |
172 | AliDebug(1,Form("Selecting raw data for detector %s",detName)); | |
173 | fRawReader->Select(detName); | |
174 | } | |
175 | ||
3ea47630 | 176 | //_____________________________________________________________________________ |
3a291af4 | 177 | UShort_t AliAltroRawStream::GetNextWord() |
3ea47630 | 178 | { |
3a291af4 | 179 | // Read the next 10 bit word in backward direction |
180 | // The input stream access is given by fData and fPosition | |
3ea47630 | 181 | |
3a291af4 | 182 | fPosition--; |
183 | ||
184 | Int_t iBit = fPosition * 10; | |
3ea47630 | 185 | Int_t iByte = iBit / 8; |
186 | Int_t shift = iBit % 8; | |
3ea47630 | 187 | |
5e6235b5 | 188 | // the raw data is written as integers where the low bits are filled first |
3ea47630 | 189 | // -> little endian is assumed here ! |
5e6235b5 | 190 | Int_t iByteLow = iByte; |
3ea47630 | 191 | iByte++; |
5e6235b5 | 192 | Int_t iByteHigh = iByte; |
3a291af4 | 193 | return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF; |
194 | } | |
195 | ||
196 | //_____________________________________________________________________________ | |
197 | Bool_t AliAltroRawStream::ReadTrailer() | |
198 | { | |
199 | //Read a trailer of 40 bits in the backward reading mode | |
200 | //In case of no mapping is provided, read a dummy trailer | |
201 | if (fNoAltroMapping) { | |
202 | AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!"); | |
203 | return ReadDummyTrailer(); | |
204 | } | |
205 | ||
206 | //First reading filling words | |
207 | UShort_t temp; | |
208 | Int_t nFillWords = 0; | |
209 | while ((temp = GetNextWord()) == 0x2AA) nFillWords++; | |
776c3b9c | 210 | if (nFillWords == 0) { |
211 | PrintDebug(); | |
3a291af4 | 212 | AliFatal("Incorrect trailer found ! Expected 0x2AA not found !"); |
776c3b9c | 213 | } |
3a291af4 | 214 | |
215 | //Then read the trailer | |
776c3b9c | 216 | if (fPosition <= 4) { |
217 | PrintDebug(); | |
3a291af4 | 218 | AliFatal(Form("Incorrect raw data size ! Expected at lest 4 words but found %d !",fPosition)); |
776c3b9c | 219 | } |
3a291af4 | 220 | |
221 | fCount = (temp << 4) & 0x3FF; | |
776c3b9c | 222 | if ((temp >> 6) != 0xA) { |
223 | PrintDebug(); | |
3a291af4 | 224 | AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6)); |
776c3b9c | 225 | } |
3a291af4 | 226 | |
227 | temp = GetNextWord(); | |
228 | fHWAddress = (temp & 0x3) << 10; | |
776c3b9c | 229 | if (((temp >> 2) & 0xF) != 0xA) { |
230 | PrintDebug(); | |
3a291af4 | 231 | AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",(temp >> 2) & 0xF)); |
776c3b9c | 232 | } |
3a291af4 | 233 | fCount |= ((temp & 0x3FF) >> 6); |
234 | if (fCount == 0) return kFALSE; | |
235 | ||
236 | temp = GetNextWord(); | |
237 | fHWAddress |= temp; | |
238 | ||
239 | fPosition -= (4 - (fCount % 4)) % 4; // skip fill words | |
240 | ||
3a291af4 | 241 | return kTRUE; |
242 | } | |
243 | ||
244 | //_____________________________________________________________________________ | |
245 | Bool_t AliAltroRawStream::ReadDummyTrailer() | |
246 | { | |
247 | //Read a trailer of 40 bits in the backward reading mode | |
248 | //In case of no mapping is provided, read a dummy trailer | |
249 | UShort_t temp; | |
250 | while ((temp = GetNextWord()) == 0x2AA); | |
251 | ||
e7fd2555 | 252 | fSegmentation[0] = temp; |
253 | fSegmentation[1] = GetNextWord(); | |
254 | fSegmentation[2] = GetNextWord(); | |
3a291af4 | 255 | fCount = GetNextWord(); |
256 | if (fCount == 0) return kFALSE; | |
257 | fHWAddress = -1; | |
258 | ||
e7fd2555 | 259 | fPosition -= (4 - (fCount % 4)) % 4; // skip fill words |
260 | ||
3a291af4 | 261 | return kTRUE; |
262 | } | |
263 | ||
264 | //_____________________________________________________________________________ | |
265 | void AliAltroRawStream::ReadBunch() | |
266 | { | |
267 | // Read altro payload in | |
268 | // backward direction | |
776c3b9c | 269 | if (fPosition <= 0) { |
270 | PrintDebug(); | |
3a291af4 | 271 | AliFatal("Could not read bunch length !"); |
776c3b9c | 272 | } |
3a291af4 | 273 | |
274 | fBunchLength = GetNextWord() - 2; | |
275 | fTimeBunch = fBunchLength; | |
276 | fCount--; | |
277 | ||
776c3b9c | 278 | if (fPosition <= 0) { |
279 | PrintDebug(); | |
3a291af4 | 280 | AliFatal("Could not read time bin !"); |
776c3b9c | 281 | } |
3a291af4 | 282 | |
283 | fTime = GetNextWord(); | |
284 | fCount--; | |
285 | ||
286 | return; | |
287 | } | |
288 | ||
289 | //_____________________________________________________________________________ | |
290 | void AliAltroRawStream::ReadAmplitude() | |
291 | { | |
292 | // Read next time bin amplitude | |
776c3b9c | 293 | if (fPosition <= 0) { |
294 | PrintDebug(); | |
3a291af4 | 295 | AliFatal("Could not read sample amplitude !"); |
776c3b9c | 296 | } |
3a291af4 | 297 | |
298 | fSignal = GetNextWord(); | |
299 | fCount--; | |
300 | fBunchLength--; | |
301 | ||
302 | return; | |
303 | } | |
304 | ||
305 | //_____________________________________________________________________________ | |
306 | Int_t AliAltroRawStream::GetPosition() | |
307 | { | |
308 | // Sets the position in the | |
309 | // input stream | |
5e6235b5 | 310 | // Read the RCU trailer |
311 | // This includes the trailer size, | |
312 | // RCU identifier and raw data payload. | |
313 | // The RCU trailer format is described | |
314 | // in details in the RCU manual. | |
315 | ||
7e18047e | 316 | if (!fIsOldRCUFormat) { |
317 | // First read 32-bit word with the | |
318 | // trailer size (22 bits) and RCU ID (the rest) | |
319 | Int_t index = fRawReader->GetDataSize(); | |
320 | UInt_t word = Get32bitWord(index); | |
321 | fRCUId = (Int_t)(word >> 22); | |
322 | Int_t trailerSize = (word & 0x3FFFFF); | |
323 | ||
324 | // Now read the beginning of the trailer | |
325 | // where the payload size is written | |
776c3b9c | 326 | if (trailerSize < 2) { |
327 | PrintDebug(); | |
7e18047e | 328 | AliFatal(Form("Invalid trailer size found (%d bytes) !",trailerSize*4)); |
776c3b9c | 329 | } |
7e18047e | 330 | fRCUTrailerSize = (trailerSize-2)*4; |
331 | index -= fRCUTrailerSize; | |
776c3b9c | 332 | if (index < 4) { |
333 | PrintDebug(); | |
7e18047e | 334 | AliFatal(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!", |
335 | trailerSize*4, | |
336 | fRawReader->GetDataSize())); | |
776c3b9c | 337 | } |
7e18047e | 338 | fRCUTrailerData = fData + index; |
339 | Int_t position = Get32bitWord(index); | |
340 | // The size is specified in a number of 40bits | |
341 | // Therefore we need to transform it to number of bytes | |
342 | position *= 5; | |
343 | ||
344 | // Check the consistency of the header and trailer | |
776c3b9c | 345 | if ((fRawReader->GetDataSize() - trailerSize*4) != position) { |
346 | PrintDebug(); | |
7e18047e | 347 | AliFatal(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !", |
348 | fRawReader->GetDataSize(), | |
349 | trailerSize*4, | |
350 | position)); | |
776c3b9c | 351 | } |
7e18047e | 352 | |
353 | return position * 8 / 10; | |
354 | } | |
355 | else { | |
356 | // In case of the Old RCU trailer format | |
357 | // we have to read just the size of altro payload | |
358 | // in units of 40-bit words | |
359 | Int_t index = fRawReader->GetDataSize(); | |
360 | Int_t position = Get32bitWord(index); | |
361 | ||
362 | fRCUId = -1; | |
363 | fRCUTrailerSize = 0; | |
364 | fRCUTrailerData = NULL; | |
365 | ||
366 | // The size is specified in a number of 40bits | |
367 | // Therefore we need to transform it to number of bytes | |
368 | position *= 5; | |
369 | ||
1e984421 | 370 | if (!fIsShortDataHeader) { |
7e18047e | 371 | |
1e984421 | 372 | // Check the consistency of the header and trailer |
776c3b9c | 373 | if ((fRawReader->GetDataSize() - 4) != position) { |
374 | PrintDebug(); | |
1e984421 | 375 | AliFatal(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!", |
376 | fRawReader->GetDataSize()-4, | |
377 | position)); | |
776c3b9c | 378 | } |
1e984421 | 379 | } |
380 | else { | |
381 | // Check the consistency of the header and trailer | |
382 | // In this case the header is shorter by 4 bytes | |
776c3b9c | 383 | if (fRawReader->GetDataSize() != position) { |
384 | PrintDebug(); | |
1e984421 | 385 | AliFatal(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!", |
386 | fRawReader->GetDataSize(), | |
387 | position)); | |
776c3b9c | 388 | } |
1e984421 | 389 | |
390 | // 7 32-bit words Common Data Header | |
391 | // therefore we have to shift back by 4 bytes | |
392 | // the pointer to the raw data payload | |
393 | fData -= 4; | |
394 | } | |
395 | ||
7e18047e | 396 | // Return the position in units of 10-bit words |
397 | return position*8/10; | |
398 | } | |
5e6235b5 | 399 | } |
400 | ||
401 | //_____________________________________________________________________________ | |
402 | UInt_t AliAltroRawStream::Get32bitWord(Int_t &index) | |
403 | { | |
404 | // This method returns the 32 bit word at a given | |
405 | // position inside the raw data payload. | |
406 | // The 'index' points to the beginning of the next word. | |
407 | // The method is supposed to be endian (platform) | |
408 | // independent. | |
776c3b9c | 409 | if (!fData) { |
410 | PrintDebug(); | |
5e6235b5 | 411 | AliFatal("Raw data paylod buffer is not yet initialized !"); |
776c3b9c | 412 | } |
413 | ||
414 | if (index < 4) { | |
415 | PrintDebug(); | |
5e6235b5 | 416 | AliFatal(Form("Invalid raw data payload index (%d) !",index)); |
776c3b9c | 417 | } |
5e6235b5 | 418 | |
419 | UInt_t word = 0; | |
420 | word = fData[--index] << 24; | |
421 | word |= fData[--index] << 16; | |
422 | word |= fData[--index] << 8; | |
423 | word |= fData[--index]; | |
424 | ||
425 | return word; | |
426 | } | |
427 | ||
428 | //_____________________________________________________________________________ | |
429 | Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const | |
430 | { | |
431 | // Return a pointer to the RCU trailer | |
432 | // data. Should be called always after | |
433 | // the RCU trailer was already processed | |
434 | // in the GetPosition() method | |
435 | if (!fRCUTrailerSize || !fRCUTrailerData) { | |
436 | AliError("No valid RCU trailer data is found !"); | |
437 | data = NULL; | |
438 | return kFALSE; | |
439 | } | |
440 | ||
441 | data = fRCUTrailerData; | |
442 | ||
443 | return kTRUE; | |
3ea47630 | 444 | } |
776c3b9c | 445 | |
446 | //_____________________________________________________________________________ | |
447 | void AliAltroRawStream::PrintDebug() const | |
448 | { | |
449 | // The method prints all the available | |
450 | // debug information. | |
451 | // Its is used in case of decoding errors. | |
452 | ||
453 | AliError("Start of debug printout\n--------------------"); | |
454 | ||
455 | Dump(); | |
456 | if (fRawReader) fRawReader->Dump(); | |
457 | ||
458 | AliError("End of debug printout\n--------------------"); | |
459 | } |