]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliAltroRawStream.cxx
Compilation on win32gcc
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStream.cxx
CommitLineData
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
33ClassImp(AliAltroRawStream)
34
35
36//_____________________________________________________________________________
37AliAltroRawStream::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//_____________________________________________________________________________
64AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
65 TObject(stream),
e7bee78b 66 fNoAltroMapping(stream.fNoAltroMapping),
67 fIsOldRCUFormat(stream.fIsOldRCUFormat),
68 fIsShortDataHeader(stream.fIsShortDataHeader),
69 fDDLNumber(stream.fDDLNumber),
70 fPrevDDLNumber(stream.fPrevDDLNumber),
71 fRCUId(stream.fRCUId),
72 fPrevRCUId(stream.fPrevRCUId),
73 fHWAddress(stream.fHWAddress),
74 fPrevHWAddress(stream.fPrevHWAddress),
75 fTime(stream.fTime),
76 fPrevTime(stream.fPrevTime),
77 fSignal(stream.fSignal),
78 fTimeBunch(stream.fTimeBunch),
79 fRawReader(stream.fRawReader),
80 fData(stream.fData),
81 fPosition(stream.fPosition),
82 fCount(stream.fCount),
83 fBunchLength(stream.fBunchLength),
84 fRCUTrailerData(stream.fRCUTrailerData),
85 fRCUTrailerSize(stream.fRCUTrailerSize)
3ea47630 86{
e7bee78b 87 fSegmentation[0] = stream.fSegmentation[0];
88 fSegmentation[1] = stream.fSegmentation[1];
89 fSegmentation[2] = stream.fSegmentation[2];
3ea47630 90}
91
92//_____________________________________________________________________________
3820a703 93AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream& stream)
3ea47630 94{
3820a703 95 if(&stream == this) return *this;
96
97 fNoAltroMapping = stream.fNoAltroMapping;
98 fIsOldRCUFormat = stream.fIsOldRCUFormat;
99 fIsShortDataHeader = stream.fIsShortDataHeader;
100 fDDLNumber = stream.fDDLNumber;
101 fPrevDDLNumber = stream.fPrevDDLNumber;
102 fRCUId = stream.fRCUId;
103 fPrevRCUId = stream.fPrevRCUId;
104 fHWAddress = stream.fHWAddress;
105 fPrevHWAddress = stream.fPrevHWAddress;
106 fTime = stream.fTime;
107 fPrevTime = stream.fPrevTime;
108 fSignal = stream.fSignal;
109 fTimeBunch = stream.fTimeBunch;
110 fRawReader = stream.fRawReader;
111 fData = stream.fData;
112 fPosition = stream.fPosition;
113 fCount = stream.fCount;
114 fBunchLength = stream.fBunchLength;
115 fRCUTrailerData = stream.fRCUTrailerData;
116 fRCUTrailerSize = stream.fRCUTrailerSize;
117
118 fSegmentation[0] = stream.fSegmentation[0];
119 fSegmentation[1] = stream.fSegmentation[1];
120 fSegmentation[2] = stream.fSegmentation[2];
121
3ea47630 122 return *this;
123}
124
125//_____________________________________________________________________________
126AliAltroRawStream::~AliAltroRawStream()
127{
128// clean up
129
130}
131
3a291af4 132//_____________________________________________________________________________
133void AliAltroRawStream::Reset()
134{
135// reset altro raw stream params
136
137 fPosition = fCount = fBunchLength = 0;
138
5e6235b5 139 fRCUTrailerData = NULL;
140 fRCUTrailerSize = 0;
141
142 fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
3a291af4 143
144 if (fRawReader) fRawReader->Reset();
e7fd2555 145
146 fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
3a291af4 147}
3ea47630 148
149//_____________________________________________________________________________
150Bool_t AliAltroRawStream::Next()
151{
152// read the next raw digit
153// returns kFALSE if there is no digit left
154
e7fd2555 155 fPrevDDLNumber = fDDLNumber;
5e6235b5 156 fPrevRCUId = fRCUId;
3a291af4 157 fPrevHWAddress = fHWAddress;
e7fd2555 158 fPrevTime = fTime;
3ea47630 159
160 while (fCount == 0) { // next trailer
161 if (fPosition <= 0) { // next payload
162 do {
163 if (!fRawReader->ReadNextData(fData)) return kFALSE;
164 } while (fRawReader->GetDataSize() == 0);
165
e7fd2555 166 fDDLNumber = fRawReader->GetDDLID();
167
3a291af4 168 fPosition = GetPosition();
3ea47630 169 }
3ea47630 170
eb09ec9a 171 ReadTrailer();
3ea47630 172
3a291af4 173 fBunchLength = 0;
3ea47630 174 }
175
3a291af4 176 if (fBunchLength == 0) ReadBunch();
177 else fTime--;
178
179 ReadAmplitude();
3ea47630 180
181 return kTRUE;
182}
183
e7fd2555 184//_____________________________________________________________________________
185void AliAltroRawStream::SelectRawData(Int_t detId)
186{
187 // Select the raw data for specific
188 // detector id
189 AliDebug(1,Form("Selecting raw data for detector %d",detId));
190 fRawReader->Select(detId);
191}
192
362c9d61 193//_____________________________________________________________________________
194void AliAltroRawStream::SelectRawData(const char *detName)
195{
196 // Select the raw data for specific
197 // detector name
198 AliDebug(1,Form("Selecting raw data for detector %s",detName));
199 fRawReader->Select(detName);
200}
201
3ea47630 202//_____________________________________________________________________________
3a291af4 203UShort_t AliAltroRawStream::GetNextWord()
3ea47630 204{
3a291af4 205 // Read the next 10 bit word in backward direction
206 // The input stream access is given by fData and fPosition
3ea47630 207
3a291af4 208 fPosition--;
209
210 Int_t iBit = fPosition * 10;
3ea47630 211 Int_t iByte = iBit / 8;
212 Int_t shift = iBit % 8;
3ea47630 213
5e6235b5 214 // the raw data is written as integers where the low bits are filled first
3ea47630 215 // -> little endian is assumed here !
5e6235b5 216 Int_t iByteLow = iByte;
3ea47630 217 iByte++;
5e6235b5 218 Int_t iByteHigh = iByte;
3a291af4 219 return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF;
220}
221
222//_____________________________________________________________________________
223Bool_t AliAltroRawStream::ReadTrailer()
224{
225 //Read a trailer of 40 bits in the backward reading mode
226 //In case of no mapping is provided, read a dummy trailer
227 if (fNoAltroMapping) {
228 AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!");
229 return ReadDummyTrailer();
230 }
231
232 //First reading filling words
233 UShort_t temp;
234 Int_t nFillWords = 0;
235 while ((temp = GetNextWord()) == 0x2AA) nFillWords++;
776c3b9c 236 if (nFillWords == 0) {
eb09ec9a 237 fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0x2AA");
238 // PrintDebug();
239 AliWarning("Incorrect trailer found ! Expected 0x2AA not found !");
240 // trying to recover and find the next bunch
241 while ((fPosition > 5) && (temp != 0x2AA)) temp = GetNextWord();
242 if (temp != 0x2AA) {
243 fCount = fPosition = 0;
244 return kFALSE;
245 }
246 temp = GetNextWord();
776c3b9c 247 }
3a291af4 248
249 //Then read the trailer
eb09ec9a 250 if (fPosition < 5) {
251 fRawReader->AddMajorErrorLog(kAltroTrailerErr,Form("size %d < 5",
252 fPosition));
253 // PrintDebug();
254 AliWarning(Form("Incorrect raw data size ! Expected at least 5 words but found %d !",fPosition));
255 fCount = fPosition = 0;
256 return kFALSE;
776c3b9c 257 }
3a291af4 258
259 fCount = (temp << 4) & 0x3FF;
776c3b9c 260 if ((temp >> 6) != 0xA) {
eb09ec9a 261 fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0xA");
262 // PrintDebug();
263 AliWarning(Form("Incorrect trailer found ! Expecting 0xA but found 0x%x !",temp >> 6));
264 fCount = 0;
265 return kFALSE;
776c3b9c 266 }
3a291af4 267
268 temp = GetNextWord();
269 fHWAddress = (temp & 0x3) << 10;
776c3b9c 270 if (((temp >> 2) & 0xF) != 0xA) {
eb09ec9a 271 fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no second 0xA");
272 // PrintDebug();
273 AliWarning(Form("Incorrect trailer found ! Expecting second 0xA but found 0x%x !",(temp >> 2) & 0xF));
274 fCount = 0;
275 return kFALSE;
776c3b9c 276 }
3a291af4 277 fCount |= ((temp & 0x3FF) >> 6);
278 if (fCount == 0) return kFALSE;
71c94b28 279 if (fCount >= fPosition) {
280 fRawReader->AddMajorErrorLog(kAltroTrailerErr,"invalid size");
281 // PrintDebug();
282 AliWarning(Form("Incorrect trailer found ! The altro payload size is invalid (%d >= %d) !",fCount,fPosition));
283 fCount = 0;
284 return kFALSE;
285 }
3a291af4 286 temp = GetNextWord();
287 fHWAddress |= temp;
288
289 fPosition -= (4 - (fCount % 4)) % 4; // skip fill words
290
3a291af4 291 return kTRUE;
292}
293
294//_____________________________________________________________________________
295Bool_t AliAltroRawStream::ReadDummyTrailer()
296{
297 //Read a trailer of 40 bits in the backward reading mode
298 //In case of no mapping is provided, read a dummy trailer
299 UShort_t temp;
300 while ((temp = GetNextWord()) == 0x2AA);
301
e7fd2555 302 fSegmentation[0] = temp;
303 fSegmentation[1] = GetNextWord();
304 fSegmentation[2] = GetNextWord();
3a291af4 305 fCount = GetNextWord();
306 if (fCount == 0) return kFALSE;
307 fHWAddress = -1;
308
e7fd2555 309 fPosition -= (4 - (fCount % 4)) % 4; // skip fill words
310
3a291af4 311 return kTRUE;
312}
313
314//_____________________________________________________________________________
315void AliAltroRawStream::ReadBunch()
316{
317 // Read altro payload in
318 // backward direction
71c94b28 319 if (fCount <= 2) {
eb09ec9a 320 fRawReader->AddMinorErrorLog(kBunchLengthReadErr,"");
321 // PrintDebug();
71c94b28 322 AliWarning(Form("Could not read bunch length and time bin ! Only %d 10-bit words are left !",fCount));
323 fBunchLength = fTimeBunch = fCount = 0;
324 return;
776c3b9c 325 }
3a291af4 326
327 fBunchLength = GetNextWord() - 2;
71c94b28 328 if (fBunchLength > fCount) {
329 fRawReader->AddMinorErrorLog(kBunchLengthReadErr,Form("bl=%d",fBunchLength));
eb09ec9a 330 // PrintDebug();
71c94b28 331 AliWarning(Form("Could not read bunch length ! Bunch length = %d (>%d)",fBunchLength,fCount));
332 fBunchLength = fTimeBunch = fCount = 0;
333 return;
776c3b9c 334 }
71c94b28 335 fTimeBunch = fBunchLength;
336 fCount--;
3a291af4 337
338 fTime = GetNextWord();
339 fCount--;
340
341 return;
342}
343
344//_____________________________________________________________________________
345void AliAltroRawStream::ReadAmplitude()
346{
347 // Read next time bin amplitude
71c94b28 348 if (fCount <= 0) {
eb09ec9a 349 fRawReader->AddMinorErrorLog(kAmplitudeReadErr,"");
350 // PrintDebug();
351 AliWarning("Could not read sample amplitude !");
71c94b28 352 fCount = fSignal = fBunchLength = 0;
353 return;
776c3b9c 354 }
3a291af4 355
356 fSignal = GetNextWord();
71c94b28 357
3a291af4 358 fCount--;
359 fBunchLength--;
360
361 return;
362}
363
364//_____________________________________________________________________________
365Int_t AliAltroRawStream::GetPosition()
366{
367 // Sets the position in the
368 // input stream
5e6235b5 369 // Read the RCU trailer
370 // This includes the trailer size,
371 // RCU identifier and raw data payload.
372 // The RCU trailer format is described
373 // in details in the RCU manual.
374
7e18047e 375 if (!fIsOldRCUFormat) {
376 // First read 32-bit word with the
377 // trailer size (22 bits) and RCU ID (the rest)
378 Int_t index = fRawReader->GetDataSize();
379 UInt_t word = Get32bitWord(index);
380 fRCUId = (Int_t)(word >> 22);
381 Int_t trailerSize = (word & 0x3FFFFF);
382
383 // Now read the beginning of the trailer
384 // where the payload size is written
776c3b9c 385 if (trailerSize < 2) {
7dcdcfe4 386 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
387 trailerSize*4));
388 AliWarning(Form("Invalid trailer size found (%d bytes) !",
389 trailerSize*4));
776c3b9c 390 }
7e18047e 391 fRCUTrailerSize = (trailerSize-2)*4;
392 index -= fRCUTrailerSize;
776c3b9c 393 if (index < 4) {
927aaa44 394 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
395 trailerSize*4,
396 fRawReader->GetDataSize()));
397 AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
398 trailerSize*4,
399 fRawReader->GetDataSize()));
776c3b9c 400 }
7e18047e 401 fRCUTrailerData = fData + index;
402 Int_t position = Get32bitWord(index);
403 // The size is specified in a number of 40bits
404 // Therefore we need to transform it to number of bytes
405 position *= 5;
406
407 // Check the consistency of the header and trailer
7dcdcfe4 408 if (((fRawReader->GetDataSize() - trailerSize*4) < position) ||
409 ((fRawReader->GetDataSize() - trailerSize*4) >= (position + 4))) {
410 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
411 fRawReader->GetDataSize(),
412 trailerSize*4,
413 position));
414 AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
7e18047e 415 fRawReader->GetDataSize(),
416 trailerSize*4,
417 position));
7dcdcfe4 418 position = fRawReader->GetDataSize() - trailerSize*4;
776c3b9c 419 }
7e18047e 420
421 return position * 8 / 10;
422 }
423 else {
424 // In case of the Old RCU trailer format
425 // we have to read just the size of altro payload
426 // in units of 40-bit words
427 Int_t index = fRawReader->GetDataSize();
428 Int_t position = Get32bitWord(index);
429
430 fRCUId = -1;
431 fRCUTrailerSize = 0;
432 fRCUTrailerData = NULL;
433
434 // The size is specified in a number of 40bits
435 // Therefore we need to transform it to number of bytes
436 position *= 5;
437
1e984421 438 if (!fIsShortDataHeader) {
7e18047e 439
1e984421 440 // Check the consistency of the header and trailer
7dcdcfe4 441 if (((fRawReader->GetDataSize() - 4) < position) ||
442 ((fRawReader->GetDataSize() - 4) >= (position + 4))) {
eb09ec9a 443 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
444 fRawReader->GetDataSize()-4,
445 position));
446 // PrintDebug();
447 AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
448 fRawReader->GetDataSize()-4,
449 position));
450 position = fRawReader->GetDataSize()-4;
776c3b9c 451 }
1e984421 452 }
453 else {
454 // Check the consistency of the header and trailer
455 // In this case the header is shorter by 4 bytes
7dcdcfe4 456 if ((fRawReader->GetDataSize() < position) ||
457 (fRawReader->GetDataSize() >= (position + 4))) {
eb09ec9a 458 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
459 fRawReader->GetDataSize(),
460 position));
461 // PrintDebug();
462 AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
463 fRawReader->GetDataSize(),
464 position));
465 position = fRawReader->GetDataSize();
776c3b9c 466 }
1e984421 467
468 // 7 32-bit words Common Data Header
469 // therefore we have to shift back by 4 bytes
470 // the pointer to the raw data payload
471 fData -= 4;
472 }
473
7e18047e 474 // Return the position in units of 10-bit words
475 return position*8/10;
476 }
5e6235b5 477}
478
479//_____________________________________________________________________________
480UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
481{
482 // This method returns the 32 bit word at a given
483 // position inside the raw data payload.
484 // The 'index' points to the beginning of the next word.
485 // The method is supposed to be endian (platform)
486 // independent.
776c3b9c 487 if (!fData) {
488 PrintDebug();
5e6235b5 489 AliFatal("Raw data paylod buffer is not yet initialized !");
776c3b9c 490 }
491
492 if (index < 4) {
eb09ec9a 493 fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index));
494 // PrintDebug();
495 AliWarning(Form("Invalid raw data payload position (%d) !",index));
776c3b9c 496 }
5e6235b5 497
498 UInt_t word = 0;
499 word = fData[--index] << 24;
500 word |= fData[--index] << 16;
501 word |= fData[--index] << 8;
502 word |= fData[--index];
503
504 return word;
505}
506
507//_____________________________________________________________________________
508Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
509{
510 // Return a pointer to the RCU trailer
511 // data. Should be called always after
512 // the RCU trailer was already processed
513 // in the GetPosition() method
514 if (!fRCUTrailerSize || !fRCUTrailerData) {
515 AliError("No valid RCU trailer data is found !");
516 data = NULL;
517 return kFALSE;
518 }
519
520 data = fRCUTrailerData;
521
522 return kTRUE;
3ea47630 523}
776c3b9c 524
525//_____________________________________________________________________________
526void AliAltroRawStream::PrintDebug() const
527{
528 // The method prints all the available
529 // debug information.
530 // Its is used in case of decoding errors.
531
532 AliError("Start of debug printout\n--------------------");
533
534 Dump();
535 if (fRawReader) fRawReader->Dump();
536
537 AliError("End of debug printout\n--------------------");
538}
e68dc1cf 539
540//_____________________________________________________________________________
541Int_t AliAltroRawStream::GetBranch() const
542{
543 // The method provides the RCU branch index (0 or 1)
544 // for the current hardware address.
545 // In case the hardware address has not been yet
546 // initialized, the method returns -1
547 if (fHWAddress == -1) return -1;
548
549 return ((fHWAddress >> 11) & 0x1);
550}
551
552//_____________________________________________________________________________
553Int_t AliAltroRawStream::GetFEC() const
554{
555 // The method provides the front-end card index
556 // for the current hardware address.
557 // In case the hardware address has not been yet
558 // initialized, the method returns -1
559 if (fHWAddress == -1) return -1;
560
561 return ((fHWAddress >> 7) & 0xF);
562}
563
564//_____________________________________________________________________________
565Int_t AliAltroRawStream::GetAltro() const
566{
567 // The method provides the altro chip index
568 // for the current hardware address.
569 // In case the hardware address has not been yet
570 // initialized, the method returns -1
571 if (fHWAddress == -1) return -1;
572
573 return ((fHWAddress >> 4) & 0x7);
574}
575
576//_____________________________________________________________________________
577Int_t AliAltroRawStream::GetChannel() const
578{
579 // The method provides the channel index
580 // for the current hardware address.
581 // In case the hardware address has not been yet
582 // initialized, the method returns -1
583 if (fHWAddress == -1) return -1;
584
585 return (fHWAddress & 0xF);
586}
eb09ec9a 587
588//_____________________________________________________________________________
589void AliAltroRawStream::AddMappingErrorLog(const char *message)
590{
591 // Signal a mapping error
592 // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
593 // classes in order to log an error related to bad altro mapping
594
595 if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
596}