]> git.uio.no Git - u/mrichter/AliRoot.git/blob - RAW/AliAltroRawStreamV3.cxx
ALIROOT-5628 AliRawReaderDate cannot decode CDH v3
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStreamV3.cxx
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 ///////////////////////////////////////////////////////////////////////////////
17 ///
18 /// This is a base class for reading raw data digits in Altro format.
19 /// The class is able to read the RCU v3 and above formats.
20 /// The main difference between the format V3 and older ones is in
21 /// the coding of the 10-bit Altro payload words. In V3 3 10-bit words
22 /// are coded in one 32-bit word. The bits 30 and 31 are used to identify
23 /// the payload, altro header and RCU trailer contents.
24 ///
25 ///
26 /// cvetan.cheshkov@cern.ch 1/04/2009
27 ///////////////////////////////////////////////////////////////////////////////
28
29 #include "AliAltroRawStreamV3.h"
30 #include "AliRawReader.h"
31 #include "AliLog.h"
32 #include "AliAltroRawStream.h"
33 #include "AliRawEventHeaderBase.h"
34
35 ClassImp(AliAltroRawStreamV3)
36
37
38 //_____________________________________________________________________________
39 AliAltroRawStreamV3::AliAltroRawStreamV3(AliRawReader* rawReader) :
40   fIsShortDataHeader(kFALSE),
41   fDDLNumber(-1),
42   fRCUId(-1),
43   fHWAddress(-1),
44   fRawReader(rawReader),
45   fData(NULL),
46   fChannelStartPos(-1),
47   fPosition(-1),
48   fCount(-1),
49   fStartTimeBin(-1),
50   fBunchLength(-1),
51   fBadChannel(kFALSE),
52   fPayloadSize(-1),
53   fChannelPayloadSize(-1),
54   fBunchDataPointer(NULL),
55   fBunchDataIndex(-1),
56   fRCUTrailerData(NULL),
57   fRCUTrailerSize(0),
58   fFECERRA(0),
59   fFECERRB(0),
60   fERRREG2(0),
61   fERRREG3(0),
62   fActiveFECsA(0),
63   fActiveFECsB(0),
64   fAltroCFG1(0),
65   fAltroCFG2(0),
66   fOldStream(NULL),
67   fCheckAltroPayload(kTRUE),
68   fFormatVersion(0)
69 {
70   // Constructor
71   // Create an object to read Altro raw digits in
72   // RCU version 3 and beyond format
73   for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = 0;
74 }
75
76 //_____________________________________________________________________________
77 AliAltroRawStreamV3::~AliAltroRawStreamV3()
78 {
79 // destructor
80 // delete old stream object if one exists
81   if (fOldStream) delete fOldStream;
82 }
83
84 //_____________________________________________________________________________
85 AliAltroRawStreamV3::AliAltroRawStreamV3(const AliAltroRawStreamV3& stream) :
86   TObject(stream),
87   fIsShortDataHeader(stream.fIsShortDataHeader),
88   fDDLNumber(stream.fDDLNumber),
89   fRCUId(stream.fRCUId),
90   fHWAddress(stream.fHWAddress),
91   fRawReader(stream.fRawReader),
92   fData(stream.fData),
93   fChannelStartPos(stream.fChannelStartPos),
94   fPosition(stream.fPosition),
95   fCount(stream.fCount),
96   fStartTimeBin(stream.fStartTimeBin),
97   fBunchLength(stream.fBunchLength),
98   fBadChannel(stream.fBadChannel),
99   fPayloadSize(stream.fPayloadSize),
100   fChannelPayloadSize(stream.fChannelPayloadSize),
101   fBunchDataPointer(stream.fBunchDataPointer),
102   fBunchDataIndex(stream.fBunchDataIndex),
103   fRCUTrailerData(stream.fRCUTrailerData),
104   fRCUTrailerSize(stream.fRCUTrailerSize),
105   fFECERRA(stream.fFECERRA),
106   fFECERRB(stream.fFECERRB),
107   fERRREG2(stream.fERRREG2),
108   fERRREG3(stream.fERRREG3),
109   fActiveFECsA(stream.fActiveFECsA),
110   fActiveFECsB(stream.fActiveFECsB),
111   fAltroCFG1(stream.fAltroCFG1),
112   fAltroCFG2(stream.fAltroCFG2),
113   fOldStream(NULL),
114   fCheckAltroPayload(stream.fCheckAltroPayload),
115   fFormatVersion(0)
116 {
117   // Copy constructor
118   // Copy the bunch data array
119   for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
120
121   if (stream.fOldStream)
122     fOldStream = new AliAltroRawStream(*stream.fOldStream);
123 }
124
125 //_____________________________________________________________________________
126 AliAltroRawStreamV3& AliAltroRawStreamV3::operator = (const AliAltroRawStreamV3& stream)
127 {
128   // assignment operator
129   // ... 
130   if(&stream == this) return *this;
131
132   fIsShortDataHeader = stream.fIsShortDataHeader;
133   fDDLNumber         = stream.fDDLNumber;
134   fRCUId             = stream.fRCUId;
135   fHWAddress         = stream.fHWAddress;
136   fRawReader         = stream.fRawReader;
137   fData              = stream.fData;
138   fChannelStartPos   = stream.fChannelStartPos;
139   fPosition          = stream.fPosition;
140   fCount             = stream.fCount;
141   fStartTimeBin      = stream.fStartTimeBin;
142   fBunchLength       = stream.fBunchLength;
143   fBadChannel        = stream.fBadChannel;
144   fPayloadSize       = stream.fPayloadSize;
145   fChannelPayloadSize= stream.fChannelPayloadSize;
146   fBunchDataPointer  = stream.fBunchDataPointer;
147   fBunchDataIndex    = stream.fBunchDataIndex;
148   fRCUTrailerData    = stream.fRCUTrailerData;
149   fRCUTrailerSize    = stream.fRCUTrailerSize;
150   fFECERRA           = stream.fFECERRA;
151   fFECERRB           = stream.fFECERRB;
152   fERRREG2           = stream.fERRREG2;
153   fERRREG3           = stream.fERRREG3;
154   fActiveFECsA       = stream.fActiveFECsA;
155   fActiveFECsB       = stream.fActiveFECsB;
156   fAltroCFG1         = stream.fAltroCFG1;
157   fAltroCFG2         = stream.fAltroCFG2;
158   fFormatVersion     = stream.fFormatVersion;
159
160   for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
161
162   if (stream.fOldStream) {
163     if (fOldStream) delete fOldStream;
164     fOldStream = new AliAltroRawStream(stream.fRawReader);
165     *fOldStream = *stream.fOldStream;
166   }
167
168   fCheckAltroPayload = stream.fCheckAltroPayload;
169
170   return *this;
171 }
172
173 //_____________________________________________________________________________
174 void AliAltroRawStreamV3::Reset()
175 {
176 // Complete reset of raw stream params
177 // Reset of the raw-reader as well
178
179   fDDLNumber = fRCUId = fHWAddress = -1;
180   fChannelStartPos = -1;
181   fPosition = fCount = -1;
182   fBunchLength = fStartTimeBin = -1;
183   fBadChannel = kFALSE;
184   fPayloadSize = -1;
185   fChannelPayloadSize = -1;
186   fBunchDataPointer = NULL;
187   fBunchDataIndex = -1;
188
189   fRCUTrailerData = NULL;
190   fRCUTrailerSize = 0;
191
192   fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
193
194   if (fRawReader) fRawReader->Reset();
195
196   if (fOldStream) fOldStream->Reset();
197 }
198
199 //_____________________________________________________________________________
200 Bool_t AliAltroRawStreamV3::NextDDL()
201 {
202 // Read the next DDL payload (CDH + RCU trailer)
203 // Updates the information which is coming from these
204 // two sources
205   fFormatVersion = 0;
206   fPosition = 0;
207   // Get next DDL payload
208   // return wtih false in case no more data payloads
209   // are found
210   do {
211     if (!fRawReader->ReadNextData(fData)) return kFALSE;
212   } while (fRawReader->GetDataSize() == 0);
213
214   fDDLNumber = fRawReader->GetDDLID();
215   fChannelPayloadSize = -1;
216   fChannelStartPos = -1;
217
218   fFormatVersion = (fRawReader->GetBlockAttributes() & 0xF);
219
220   if (fFormatVersion < 2) {
221     // old altro format data
222     if (!fOldStream) {
223       fOldStream = new AliAltroRawStream(fRawReader);
224       AliInfo(Form("RCU firmware verion %d detected. Using AliAltroRawStream to decode the data.",
225                    fFormatVersion));
226     }
227     Bool_t status = fOldStream->NextDDL(fData);
228     if (status) {
229       fRCUId = fOldStream->GetRCUId();
230       fRCUTrailerSize = fOldStream->GetRCUTrailerSize();
231       fOldStream->GetRCUTrailerData(fRCUTrailerData);
232       fFECERRA = fOldStream->GetFECERRA();
233       fFECERRB = fOldStream->GetFECERRB();
234       fERRREG2 = fOldStream->GetERRREG2();
235       fERRREG3 = ((UInt_t)fOldStream->GetNChAddrMismatch()) |
236         (((UInt_t)fOldStream->GetNChLengthMismatch()) << 12);
237       fActiveFECsA = fOldStream->GetActiveFECsA();
238       fActiveFECsB = fOldStream->GetActiveFECsB();
239       fAltroCFG1 = fOldStream->GetAltroCFG1();
240       fAltroCFG2 = fOldStream->GetAltroCFG2();
241       if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData)
242         fPayloadSize = fOldStream->GetRCUPayloadSizeInSOD();
243     }
244     return status;
245   }
246
247   return ReadRCUTrailer(fFormatVersion);
248 }
249
250 //_____________________________________________________________________________
251 Bool_t AliAltroRawStreamV3::NextChannel()
252 {
253   // Read the next Altro channel from the
254   // raw-data stream
255   // Updates the channel hardware address member and
256   // channel data size. Sets the error flag in case
257   // RCU signals readout error in this channel
258   if (fOldStream) {
259     Bool_t status = fOldStream->NextChannel();
260     if (status) {
261       fHWAddress = fOldStream->GetHWAddress();
262       fChannelPayloadSize = fOldStream->GetChannelPayloadSize();
263     }
264     return status;
265   }
266
267   Int_t channelStartPos=fPosition;
268   fChannelStartPos = -1;
269   fCount = -1;
270   fBadChannel = kFALSE;
271   fBunchDataIndex = 0;
272   fBunchLength = -1;
273
274   UInt_t word = 0;
275   do {
276     word = Get32bitWord(fPosition++);
277     if (fPosition > fPayloadSize) return kFALSE;
278   }
279   while ((word >> 30) != 1);
280
281   // check for readout errors
282   fBadChannel = (word >> 29) & 0x1;
283
284   // extract channel payload and hw address
285   fCount = (word >> 16) & 0x3FF; 
286   fChannelPayloadSize = fCount;
287   fHWAddress = word & 0xFFF;
288
289   // Now unpack the altro data
290   // Revert the order of the samples
291   // inside the bunch so that the
292   // first time is first in the samples
293   // array
294   Int_t isample = 0;
295   Int_t nwords = (fCount+2)/3;
296   for (Int_t iword = 0; iword < nwords; iword++) {
297     word = Get32bitWord(fPosition++);
298     if ((word >> 30) != 0) {
299       // Unexpected end of altro channel payload
300       AliWarning(Form("Unexpected end of payload in altro channel payload! DDL=%03d, Address=0x%x, word=0x%x",
301                       fDDLNumber,fHWAddress,word));
302       fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
303       if (AliDebugLevel() > 0) HexDumpChannel();
304       fCount = -1;
305       fPosition--;
306       return kFALSE;
307     }
308     fBunchData[isample++] = (word >> 20) & 0x3FF;
309     fBunchData[isample++] = (word >> 10) & 0x3FF;
310     fBunchData[isample++] = word & 0x3FF;
311   }  
312
313   fChannelStartPos=channelStartPos;
314   return kTRUE;
315 }
316
317 //_____________________________________________________________________________
318 Bool_t AliAltroRawStreamV3::NextBunch()
319 {
320   // Read next altro bunch from the
321   // raw-data stream.
322   // Updates the start/end time-bins
323   // and the array with altro samples
324   if (fOldStream) {
325     Bool_t status = fOldStream->NextBunch(fBunchData,fBunchLength,fStartTimeBin);
326     if (status) fBunchDataPointer = &fBunchData[0];
327     else fBunchDataPointer = NULL;
328     return status;
329   }
330
331   Int_t prevTimeBin = (fBunchLength > 0) ? fStartTimeBin-fBunchLength+1 : 1024;
332   fBunchLength = fStartTimeBin = -1;
333   fBunchDataPointer = NULL;
334
335   if ((fBunchDataIndex >= fCount) || fBadChannel) return kFALSE;
336
337   fBunchLength = fBunchData[fBunchDataIndex];
338   if (fBunchLength <= 2) {
339     // Invalid bunch size
340      AliDebug(1,Form("Too short bunch length (%d) @ %d in Address=0x%x (DDL=%03d)!",
341                     fBunchLength,fBunchDataIndex,fHWAddress,fDDLNumber));
342     fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
343     if (AliDebugLevel() > 0) HexDumpChannel();
344     fCount = fBunchLength = -1;
345     return kFALSE;
346   }
347   if ((fBunchDataIndex + fBunchLength) > fCount) {
348     // Too long bunch detected
349     AliDebug(1,Form("Too long bunch detected @ %d in Address=0x%x (DDL=%03d) ! Expected <= %d 10-bit words, found %d !", fBunchDataIndex,
350                     fHWAddress,fDDLNumber,fCount-fBunchDataIndex,fBunchLength));
351     fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
352     if (AliDebugLevel() > 0) HexDumpChannel();
353     fCount = fBunchLength = -1;
354     return kFALSE;
355   }
356   fBunchDataIndex++;
357   fBunchLength -= 2;
358
359   fStartTimeBin = fBunchData[fBunchDataIndex++];
360   if (fCheckAltroPayload) {
361     if ((fStartTimeBin-fBunchLength+1) < 0) {
362       AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d-%d+1) < 0", fBunchDataIndex-1,
363                       fHWAddress,fDDLNumber,fStartTimeBin,fBunchLength));
364       fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
365       if (AliDebugLevel() > 0) HexDumpChannel();
366       fCount = fBunchLength = -1;
367       return kFALSE;
368     }
369     if (fStartTimeBin >= prevTimeBin) {
370       AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d>=%d)", fBunchDataIndex-1,
371                       fHWAddress,fDDLNumber,fStartTimeBin,prevTimeBin));
372       fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
373       if (AliDebugLevel() > 0) HexDumpChannel();
374       fCount = fBunchLength = -1;
375       return kFALSE;
376     }
377   }
378
379   fBunchDataPointer = &fBunchData[fBunchDataIndex];
380
381   fBunchDataIndex += fBunchLength;
382
383   return kTRUE;
384 }
385
386 //_____________________________________________________________________________
387 const UChar_t *AliAltroRawStreamV3::GetChannelPayload() const
388 {
389   //returns raw channel data, length 4+(fChannelPayloadSize+2)/3*4
390   if (fChannelStartPos<0 || fChannelPayloadSize<0) return NULL;
391   Int_t channelSize=1+(fChannelPayloadSize+2)/3; // nof 32bit words
392   if (fPosition<fChannelStartPos+channelSize) return NULL;
393   return fData+(fChannelStartPos<<2);
394 }
395
396 //_____________________________________________________________________________
397 UInt_t AliAltroRawStreamV3::Get32bitWord(Int_t index) const
398 {
399   // This method returns the 32 bit word at a given
400   // position inside the raw data payload.
401   // The 'index' points to the beginning of the word.
402   // The method is supposed to be endian (platform)
403   // independent.
404
405   index = (index << 2); 
406   UInt_t word  = 0;
407   word |= fData[index++];
408   word |= fData[index++] << 8;
409   word |= fData[index++] << 16;
410   word |= fData[index++] << 24;
411
412   return word;
413 }
414
415 ///_____________________________________________________________________________
416 Bool_t AliAltroRawStreamV3::ReadRCUTrailer(UChar_t rcuVer)
417 {
418   // Read the RCU trailer according
419   // to the RCU formware version
420   // specified in CDH
421   // Cross-check with version found in the
422   // trailer
423
424   fRCUTrailerData = NULL;
425   fRCUTrailerSize = 0;
426   fPayloadSize = -1;
427
428   Int_t index = fRawReader->GetDataSize()/4;
429
430   // First read 32-bit word with the
431   // trailer size (7 bits), RCU ID (9 bits) and
432   // RCU firmware version (8 bits?)
433   // The two major bit should be 11 (identifies
434   // the end of the trailer)
435   UInt_t word = Get32bitWord(--index);
436
437   if ((word >> 30) != 3) {
438     fRawReader->AddFatalErrorLog(kRCUTrailerErr,"");
439     AliError("Last RCU trailer word not found!");
440     return kFALSE;
441   }
442
443   UChar_t ver = (word >> 16) & 0xFF;
444   if (ver != rcuVer) {
445     // Wrong RCU firmware version detected
446     fRawReader->AddMajorErrorLog(kRCUVerErr,Form("%d!=%d",
447                                                  ver,rcuVer));
448     AliDebug(1,Form("Wrong RCU firmware version detected: %d != %d",
449                     ver,rcuVer));
450   }
451
452   fRCUId = (Int_t)((word >> 7) & 0x1FF);
453   Int_t trailerSize = (word & 0x7F);
454
455   // Now read the beginning of the trailer
456   // where the payload size is written
457   if (trailerSize < 2) {
458     fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
459                                                      trailerSize*4));
460     AliWarning(Form("Invalid trailer size found (%d bytes) !",
461                     trailerSize*4));
462     return kFALSE;
463   }
464
465   trailerSize -= 2;
466   fRCUTrailerSize = trailerSize*4;
467
468   for (; trailerSize > 0; trailerSize--) {
469     word = Get32bitWord(--index);
470     if ((word >> 30) != 2) {
471       fRawReader->AddMinorErrorLog(kRCUTrailerErr,"missing 10");
472       AliWarning("Missing RCU trailer identifier pattern!");
473       continue;
474     }
475     Int_t parCode = (word >> 26) & 0xF;
476     Int_t parData = word & 0x3FFFFFF;
477     switch (parCode) {
478     case 1:
479       // ERR_REG1
480       fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
481       fFECERRB = ((parData & 0x1FFF)) << 7;
482       break;
483     case 2:
484       // ERR_REG2
485       fERRREG2 = parData & 0x1FF;
486       break;
487     case 3:
488       // ERR_REG3
489       fERRREG3 = parData & 0x1FFFFFF;
490       break;
491     case 4:
492       // FEC_RO_A
493       fActiveFECsA = parData & 0xFFFF;
494       break;
495     case 5:
496       // FEC_RO_B
497       fActiveFECsB = parData & 0xFFFF;
498       break;
499     case 6:
500       // RDO_CFG1
501       fAltroCFG1 = parData & 0xFFFFF;
502       break;
503     case 7:
504       // RDO_CFG2
505       fAltroCFG2 = parData & 0x1FFFFFF;
506      break;
507     default:
508       fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
509       AliWarning(Form("Undefined parameter code %d, ignore it !",
510                       parCode));
511       break;
512     }
513   }
514
515   if (index < 1) {
516     fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
517                                                      fRCUTrailerSize+8,
518                                                      fRawReader->GetDataSize()));
519     AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
520                     fRCUTrailerSize,
521                     fRawReader->GetDataSize()));
522   }
523
524   fRCUTrailerData = fData + index*4;
525
526   // Now read the payload size
527   // (First word in the RCU trailer)
528   fPayloadSize = Get32bitWord(--index) & 0x3FFFFFF;
529
530   if ((fRawReader->GetDataSize() - fRCUTrailerSize - 8) != (fPayloadSize*4)) {
531     fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
532                                                          fRawReader->GetDataSize(),
533                                                          fRCUTrailerSize+8,
534                                                          fPayloadSize*4));
535     AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from CDH), RCU trailer - %d bytes, raw data size (from RCU trailer) - %d bytes !",
536                     fRawReader->GetDataSize(),
537                     fRCUTrailerSize+8,
538                     fPayloadSize*4));
539   }
540
541   return kTRUE;
542 }
543
544 //_____________________________________________________________________________
545 Int_t AliAltroRawStreamV3::GetBranch() const
546 {
547   // The method provides the RCU branch index (0 or 1)
548   // for the current hardware address.
549   // In case the hardware address has not been yet
550   // initialized, the method returns -1
551   if (fHWAddress == -1) return -1;
552
553   return ((fHWAddress >> 11) & 0x1);
554 }
555
556 //_____________________________________________________________________________
557 Int_t AliAltroRawStreamV3::GetFEC() const
558 {
559   // The method provides the front-end card index
560   // for the current hardware address.
561   // In case the hardware address has not been yet
562   // initialized, the method returns -1
563   if (fHWAddress == -1) return -1;
564
565   return ((fHWAddress >> 7) & 0xF);
566 }
567
568 //_____________________________________________________________________________
569 Int_t AliAltroRawStreamV3::GetAltro() const
570 {
571   // The method provides the altro chip index
572   // for the current hardware address.
573   // In case the hardware address has not been yet
574   // initialized, the method returns -1
575   if (fHWAddress == -1) return -1;
576
577   return ((fHWAddress >> 4) & 0x7);
578 }
579
580 //_____________________________________________________________________________
581 Int_t AliAltroRawStreamV3::GetChannel() const
582 {
583   // The method provides the channel index
584   // for the current hardware address.
585   // In case the hardware address has not been yet
586   // initialized, the method returns -1
587   if (fHWAddress == -1) return -1;
588
589   return (fHWAddress & 0xF);
590 }
591
592 //_____________________________________________________________________________
593 Bool_t AliAltroRawStreamV3::GetRCUTrailerData(UChar_t*& data) const
594 {
595   // Return a pointer to the RCU trailer
596   // data. Should be called always after
597   // the RCU trailer was already processed
598   // in the GetPosition() method
599   if (!fRCUTrailerSize || !fRCUTrailerData) {
600     AliError("No valid RCU trailer data is found !");
601     data = NULL;
602     return kFALSE;
603   }
604
605   data = fRCUTrailerData;
606
607   return kTRUE;
608 }
609
610 //_____________________________________________________________________________
611 void AliAltroRawStreamV3::PrintRCUTrailer() const
612 {
613   // Prints the contents of
614   // the RCU trailer data
615   printf("RCU trailer (Format version %d):\n"
616          "==================================================\n",  GetFormatVersion());
617   printf("FECERRA:                                   0x%x\n", fFECERRA);
618   printf("FECERRB:                                   0x%x\n", fFECERRB);
619   printf("ERRREG2:                                   0x%x\n", fERRREG2);
620   printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
621   printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
622   printf("Active FECs (branch A):                    0x%x\n", fActiveFECsA);
623   printf("Active FECs (branch B):                    0x%x\n", fActiveFECsB);
624   printf("Baseline corr:                             0x%x\n",GetBaselineCorr());
625   printf("Number of presamples:                      %d\n", GetNPresamples());
626   printf("Number of postsamples:                     %d\n",GetNPostsamples());
627   printf("Second baseline corr:                      %d\n",GetSecondBaselineCorr());
628   printf("GlitchFilter:                              %d\n",GetGlitchFilter());
629   printf("Number of non-ZS postsamples:              %d\n",GetNNonZSPostsamples());
630   printf("Number of non-ZS presamples:               %d\n",GetNNonZSPresamples());
631   printf("Number of ALTRO buffers:                   %d\n",GetNAltroBuffers());
632   printf("Number of pretrigger samples:              %d\n",GetNPretriggerSamples());
633   printf("Number of samples per channel:             %d\n",GetNSamplesPerCh());
634   printf("Sparse readout:                            %d\n",GetSparseRO());
635   printf("Sampling time:                             %e s\n",GetTSample());
636   printf("L1 Phase:                                  %e s\n",GetL1Phase());
637   printf("AltroCFG1:                                 0x%x\n",GetAltroCFG1());
638   printf("AltroCFG2:                                 0x%x\n",GetAltroCFG2());
639   printf("==================================================\n");
640 }
641
642 //_____________________________________________________________________________
643 void AliAltroRawStreamV3::SelectRawData(Int_t detId)
644 {
645   // Select the raw data for specific
646   // detector id
647   AliDebug(1,Form("Selecting raw data for detector %d",detId));
648   fRawReader->Select(detId);
649 }
650
651 //_____________________________________________________________________________
652 void AliAltroRawStreamV3::SelectRawData(const char *detName)
653 {
654   // Select the raw data for specific
655   // detector name
656   AliDebug(1,Form("Selecting raw data for detector %s",detName));
657   fRawReader->Select(detName);
658 }
659
660 //_____________________________________________________________________________
661 Double_t AliAltroRawStreamV3::GetTSample() const
662 {
663   // Returns the sampling time
664   // in seconds. In case the rcu trailer
665   // was note read, return an invalid number (0)
666
667   if (!fRCUTrailerData) return 0.;
668
669   const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
670   UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
671   Double_t tSample;
672   switch (fq) {
673   case 0:
674     // 20 MHz
675     tSample = 2.0*kLHCTimeSample;
676     break;
677   case 1:
678     // 10 Mhz
679     tSample = 4.0*kLHCTimeSample;
680     break;
681   case 2:
682     // 5 MHz
683     tSample = 8.0*kLHCTimeSample;
684     break;
685   default:
686     AliWarning(Form("Invalid sampling frequency value %d !",
687                       fq));
688     tSample = 0.;
689     break;
690   }
691
692   return tSample;
693 }
694
695 //_____________________________________________________________________________
696 Double_t AliAltroRawStreamV3::GetL1Phase() const
697 {
698   // Returns the L1 phase w.r.t to the
699   // LHC clock
700   if (!fRCUTrailerData) return 0.;
701
702   const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
703   Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
704
705   Double_t tSample = GetTSample();
706   if (phase >= tSample) {
707     AliWarning(Form("Invalid L1 trigger phase (%f >= %f) !",
708                     phase,tSample));
709     phase = 0.;
710   }
711
712   return phase;
713 }
714
715 //_____________________________________________________________________________
716 void AliAltroRawStreamV3::AddMappingErrorLog(const char *message)
717 {
718   // Signal a mapping error
719   // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
720   // classes in order to log an error related to bad altro mapping
721
722   if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
723 }
724
725 //_____________________________________________________________________________
726 UChar_t *AliAltroRawStreamV3::GetRCUPayloadInSOD() const
727 {
728   // Get a pointer to the data in case
729   // of SOD events
730   if (fRawReader) {
731     if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
732       return fData;
733     }
734   }
735   return NULL;
736 }
737
738 //_____________________________________________________________________________
739 Int_t AliAltroRawStreamV3::GetRCUPayloadSizeInSOD() const
740 {
741   // Get the size of the RCU data in case
742   // of SOD events
743   if (fRawReader) {
744     if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
745       return fPayloadSize;
746     }
747   }
748   return -1;
749 }
750
751 //_____________________________________________________________________________
752
753 void AliAltroRawStreamV3::HexDumpChannel() const
754 {
755   // Print of the Hex Data of the current channel
756   // to decipher read-out warnings and errors
757   if (fCount>0 && fPosition>0) {
758     printf("Hex-Dump of DDL: %3d, RCU ID: %d, HWADDR: 0x%03x\n",
759            fDDLNumber,fRCUId,fHWAddress);
760     printf("32-bit     - 2bit 10bit 10bit 10bit - ");
761     printf("Index 10bit  10bit  10bit\n");
762     printf("**********   **** ***** ***** ***** - ");
763     printf("***** ****** ****** ******\n");
764     Int_t nwords = (fCount+2)/3+1;
765     for (Int_t iword = 0; iword < nwords; iword++) {
766       UInt_t word32 = Get32bitWord(fPosition-nwords+iword);
767       UInt_t marker  = word32 >> 30 & 0x3;
768       UInt_t word101 = word32 >> 20 & 0x3FF;
769       UInt_t word102 = word32 >> 10 & 0x3FF;
770       UInt_t word103 = word32 >> 00 & 0x3FF; // nice octal number
771       printf("0x%08x - 0b%1d%1d 0x%03x 0x%03x 0x%03x",
772              word32,marker>>1,marker&0x1,word101,word102,word103);
773       if (iword == 0) { printf(" - Channel Header\n"); continue; }
774       Int_t base = 3*(iword-1);
775       printf(" - %5d 0x%03x%c 0x%03x%c 0x%03x%c\n", base,
776              fBunchData[base],   (fBunchDataIndex == base   ? '*' : ' '),
777              fBunchData[base+1], (fBunchDataIndex == base+1 ? '*' : ' '),
778              fBunchData[base+2], (fBunchDataIndex == base+2 ? '*' : ' '));
779     }
780   }
781 }