]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliAltroRawStream.cxx
alimdc RPM spec file updated
[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;
279
280 temp = GetNextWord();
281 fHWAddress |= temp;
282
283 fPosition -= (4 - (fCount % 4)) % 4; // skip fill words
284
3a291af4 285 return kTRUE;
286}
287
288//_____________________________________________________________________________
289Bool_t AliAltroRawStream::ReadDummyTrailer()
290{
291 //Read a trailer of 40 bits in the backward reading mode
292 //In case of no mapping is provided, read a dummy trailer
293 UShort_t temp;
294 while ((temp = GetNextWord()) == 0x2AA);
295
e7fd2555 296 fSegmentation[0] = temp;
297 fSegmentation[1] = GetNextWord();
298 fSegmentation[2] = GetNextWord();
3a291af4 299 fCount = GetNextWord();
300 if (fCount == 0) return kFALSE;
301 fHWAddress = -1;
302
e7fd2555 303 fPosition -= (4 - (fCount % 4)) % 4; // skip fill words
304
3a291af4 305 return kTRUE;
306}
307
308//_____________________________________________________________________________
309void AliAltroRawStream::ReadBunch()
310{
311 // Read altro payload in
312 // backward direction
776c3b9c 313 if (fPosition <= 0) {
eb09ec9a 314 fRawReader->AddMinorErrorLog(kBunchLengthReadErr,"");
315 // PrintDebug();
316 AliWarning("Could not read bunch length !");
776c3b9c 317 }
3a291af4 318
319 fBunchLength = GetNextWord() - 2;
320 fTimeBunch = fBunchLength;
321 fCount--;
322
776c3b9c 323 if (fPosition <= 0) {
eb09ec9a 324 fRawReader->AddMinorErrorLog(kTimeBinReadErr,"");
325 // PrintDebug();
326 AliWarning("Could not read time bin !");
776c3b9c 327 }
3a291af4 328
329 fTime = GetNextWord();
330 fCount--;
331
332 return;
333}
334
335//_____________________________________________________________________________
336void AliAltroRawStream::ReadAmplitude()
337{
338 // Read next time bin amplitude
776c3b9c 339 if (fPosition <= 0) {
eb09ec9a 340 fRawReader->AddMinorErrorLog(kAmplitudeReadErr,"");
341 // PrintDebug();
342 AliWarning("Could not read sample amplitude !");
776c3b9c 343 }
3a291af4 344
345 fSignal = GetNextWord();
346 fCount--;
347 fBunchLength--;
348
349 return;
350}
351
352//_____________________________________________________________________________
353Int_t AliAltroRawStream::GetPosition()
354{
355 // Sets the position in the
356 // input stream
5e6235b5 357 // Read the RCU trailer
358 // This includes the trailer size,
359 // RCU identifier and raw data payload.
360 // The RCU trailer format is described
361 // in details in the RCU manual.
362
7e18047e 363 if (!fIsOldRCUFormat) {
364 // First read 32-bit word with the
365 // trailer size (22 bits) and RCU ID (the rest)
366 Int_t index = fRawReader->GetDataSize();
367 UInt_t word = Get32bitWord(index);
368 fRCUId = (Int_t)(word >> 22);
369 Int_t trailerSize = (word & 0x3FFFFF);
370
371 // Now read the beginning of the trailer
372 // where the payload size is written
776c3b9c 373 if (trailerSize < 2) {
7dcdcfe4 374 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
375 trailerSize*4));
376 AliWarning(Form("Invalid trailer size found (%d bytes) !",
377 trailerSize*4));
776c3b9c 378 }
7e18047e 379 fRCUTrailerSize = (trailerSize-2)*4;
380 index -= fRCUTrailerSize;
776c3b9c 381 if (index < 4) {
927aaa44 382 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
383 trailerSize*4,
384 fRawReader->GetDataSize()));
385 AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
386 trailerSize*4,
387 fRawReader->GetDataSize()));
776c3b9c 388 }
7e18047e 389 fRCUTrailerData = fData + index;
390 Int_t position = Get32bitWord(index);
391 // The size is specified in a number of 40bits
392 // Therefore we need to transform it to number of bytes
393 position *= 5;
394
395 // Check the consistency of the header and trailer
7dcdcfe4 396 if (((fRawReader->GetDataSize() - trailerSize*4) < position) ||
397 ((fRawReader->GetDataSize() - trailerSize*4) >= (position + 4))) {
398 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
399 fRawReader->GetDataSize(),
400 trailerSize*4,
401 position));
402 AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
7e18047e 403 fRawReader->GetDataSize(),
404 trailerSize*4,
405 position));
7dcdcfe4 406 position = fRawReader->GetDataSize() - trailerSize*4;
776c3b9c 407 }
7e18047e 408
409 return position * 8 / 10;
410 }
411 else {
412 // In case of the Old RCU trailer format
413 // we have to read just the size of altro payload
414 // in units of 40-bit words
415 Int_t index = fRawReader->GetDataSize();
416 Int_t position = Get32bitWord(index);
417
418 fRCUId = -1;
419 fRCUTrailerSize = 0;
420 fRCUTrailerData = NULL;
421
422 // The size is specified in a number of 40bits
423 // Therefore we need to transform it to number of bytes
424 position *= 5;
425
1e984421 426 if (!fIsShortDataHeader) {
7e18047e 427
1e984421 428 // Check the consistency of the header and trailer
7dcdcfe4 429 if (((fRawReader->GetDataSize() - 4) < position) ||
430 ((fRawReader->GetDataSize() - 4) >= (position + 4))) {
eb09ec9a 431 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
432 fRawReader->GetDataSize()-4,
433 position));
434 // PrintDebug();
435 AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
436 fRawReader->GetDataSize()-4,
437 position));
438 position = fRawReader->GetDataSize()-4;
776c3b9c 439 }
1e984421 440 }
441 else {
442 // Check the consistency of the header and trailer
443 // In this case the header is shorter by 4 bytes
7dcdcfe4 444 if ((fRawReader->GetDataSize() < position) ||
445 (fRawReader->GetDataSize() >= (position + 4))) {
eb09ec9a 446 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
447 fRawReader->GetDataSize(),
448 position));
449 // PrintDebug();
450 AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
451 fRawReader->GetDataSize(),
452 position));
453 position = fRawReader->GetDataSize();
776c3b9c 454 }
1e984421 455
456 // 7 32-bit words Common Data Header
457 // therefore we have to shift back by 4 bytes
458 // the pointer to the raw data payload
459 fData -= 4;
460 }
461
7e18047e 462 // Return the position in units of 10-bit words
463 return position*8/10;
464 }
5e6235b5 465}
466
467//_____________________________________________________________________________
468UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
469{
470 // This method returns the 32 bit word at a given
471 // position inside the raw data payload.
472 // The 'index' points to the beginning of the next word.
473 // The method is supposed to be endian (platform)
474 // independent.
776c3b9c 475 if (!fData) {
476 PrintDebug();
5e6235b5 477 AliFatal("Raw data paylod buffer is not yet initialized !");
776c3b9c 478 }
479
480 if (index < 4) {
eb09ec9a 481 fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index));
482 // PrintDebug();
483 AliWarning(Form("Invalid raw data payload position (%d) !",index));
776c3b9c 484 }
5e6235b5 485
486 UInt_t word = 0;
487 word = fData[--index] << 24;
488 word |= fData[--index] << 16;
489 word |= fData[--index] << 8;
490 word |= fData[--index];
491
492 return word;
493}
494
495//_____________________________________________________________________________
496Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
497{
498 // Return a pointer to the RCU trailer
499 // data. Should be called always after
500 // the RCU trailer was already processed
501 // in the GetPosition() method
502 if (!fRCUTrailerSize || !fRCUTrailerData) {
503 AliError("No valid RCU trailer data is found !");
504 data = NULL;
505 return kFALSE;
506 }
507
508 data = fRCUTrailerData;
509
510 return kTRUE;
3ea47630 511}
776c3b9c 512
513//_____________________________________________________________________________
514void AliAltroRawStream::PrintDebug() const
515{
516 // The method prints all the available
517 // debug information.
518 // Its is used in case of decoding errors.
519
520 AliError("Start of debug printout\n--------------------");
521
522 Dump();
523 if (fRawReader) fRawReader->Dump();
524
525 AliError("End of debug printout\n--------------------");
526}
e68dc1cf 527
528//_____________________________________________________________________________
529Int_t AliAltroRawStream::GetBranch() const
530{
531 // The method provides the RCU branch index (0 or 1)
532 // for the current hardware address.
533 // In case the hardware address has not been yet
534 // initialized, the method returns -1
535 if (fHWAddress == -1) return -1;
536
537 return ((fHWAddress >> 11) & 0x1);
538}
539
540//_____________________________________________________________________________
541Int_t AliAltroRawStream::GetFEC() const
542{
543 // The method provides the front-end card index
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 >> 7) & 0xF);
550}
551
552//_____________________________________________________________________________
553Int_t AliAltroRawStream::GetAltro() const
554{
555 // The method provides the altro chip 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 >> 4) & 0x7);
562}
563
564//_____________________________________________________________________________
565Int_t AliAltroRawStream::GetChannel() const
566{
567 // The method provides the channel 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 & 0xF);
574}
eb09ec9a 575
576//_____________________________________________________________________________
577void AliAltroRawStream::AddMappingErrorLog(const char *message)
578{
579 // Signal a mapping error
580 // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
581 // classes in order to log an error related to bad altro mapping
582
583 if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
584}